Blaze 3.9
HybridMatrix.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_DENSE_HYBRIDMATRIX_H_
36#define _BLAZE_MATH_DENSE_HYBRIDMATRIX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <array>
44#include <algorithm>
45#include <utility>
46#include <blaze/math/Aliases.h>
56#include <blaze/math/Forward.h>
66#include <blaze/math/SIMD.h>
112#include <blaze/system/Inline.h>
114#include <blaze/system/Padding.h>
119#include <blaze/util/Assert.h>
126#include <blaze/util/EnableIf.h>
129#include <blaze/util/Memory.h>
131#include <blaze/util/Types.h>
138
139
140namespace blaze {
141
142//=================================================================================================
143//
144// CLASS DEFINITION
145//
146//=================================================================================================
147
148//*************************************************************************************************
247template< typename Type // Data type of the matrix
248 , size_t M // Number of rows
249 , size_t N // Number of columns
250 , bool SO // Storage order
251 , AlignmentFlag AF // Alignment flag
252 , PaddingFlag PF // Padding flag
253 , typename Tag > // Type tag
255 : public DenseMatrix< HybridMatrix<Type,M,N,SO,AF,PF,Tag>, SO >
256{
257 public:
258 //**Type definitions****************************************************************************
261
263 using ResultType = This;
264
267
270
271 using ElementType = Type;
273 using TagType = Tag;
274 using ReturnType = const Type&;
275 using CompositeType = const This&;
276
277 using Reference = Type&;
278 using ConstReference = const Type&;
279 using Pointer = Type*;
280 using ConstPointer = const Type*;
281
284 //**********************************************************************************************
285
286 //**Rebind struct definition********************************************************************
289 template< typename NewType > // Data type of the other matrix
290 struct Rebind {
292 };
293 //**********************************************************************************************
294
295 //**Resize struct definition********************************************************************
298 template< size_t NewM // Number of rows of the other matrix
299 , size_t NewN > // Number of columns of the other matrix
300 struct Resize {
302 };
303 //**********************************************************************************************
304
305 //**Compilation flags***************************************************************************
307
311 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
312
314
317 static constexpr bool smpAssignable = false;
318 //**********************************************************************************************
319
320 //**Constructors********************************************************************************
323 constexpr HybridMatrix();
324 constexpr HybridMatrix( size_t m, size_t n );
325 inline HybridMatrix( size_t m, size_t n, const Type& init );
326 constexpr HybridMatrix( initializer_list< initializer_list<Type> > list );
327
328 template< typename Other >
329 inline HybridMatrix( size_t m, size_t n, const Other* array );
330
331 template< typename Other, size_t Rows, size_t Cols >
332 inline HybridMatrix( const Other (&array)[Rows][Cols] );
333
334 template< typename Other, size_t Rows, size_t Cols >
335 inline HybridMatrix( const std::array<std::array<Other,Cols>,Rows>& array );
336
337 constexpr HybridMatrix( const HybridMatrix& m );
338
339 template< typename MT, bool SO2 >
340 inline HybridMatrix( const Matrix<MT,SO2>& m );
342 //**********************************************************************************************
343
344 //**Destructor**********************************************************************************
347 ~HybridMatrix() = default;
349 //**********************************************************************************************
350
351 //**Data access functions***********************************************************************
354 constexpr Reference operator()( size_t i, size_t j ) noexcept;
355 constexpr ConstReference operator()( size_t i, size_t j ) const noexcept;
356 inline Reference at( size_t i, size_t j );
357 inline ConstReference at( size_t i, size_t j ) const;
358 constexpr Pointer data () noexcept;
359 constexpr ConstPointer data () const noexcept;
360 constexpr Pointer data ( size_t i ) noexcept;
361 constexpr ConstPointer data ( size_t i ) const noexcept;
362 constexpr Iterator begin ( size_t i ) noexcept;
363 constexpr ConstIterator begin ( size_t i ) const noexcept;
364 constexpr ConstIterator cbegin( size_t i ) const noexcept;
365 constexpr Iterator end ( size_t i ) noexcept;
366 constexpr ConstIterator end ( size_t i ) const noexcept;
367 constexpr ConstIterator cend ( size_t i ) const noexcept;
369 //**********************************************************************************************
370
371 //**Assignment operators************************************************************************
374 constexpr HybridMatrix& operator=( const Type& set ) &;
375 constexpr HybridMatrix& operator=( initializer_list< initializer_list<Type> > list ) &;
376
377 template< typename Other, size_t Rows, size_t Cols >
378 constexpr HybridMatrix& operator=( const Other (&array)[Rows][Cols] ) &;
379
380 template< typename Other, size_t Rows, size_t Cols >
381 constexpr HybridMatrix& operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &;
382
383 constexpr HybridMatrix& operator=( const HybridMatrix& rhs ) &;
384
385 template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs ) &;
386 template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs ) &;
387 template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs ) &;
388 template< typename MT, bool SO2 > inline HybridMatrix& operator%=( const Matrix<MT,SO2>& rhs ) &;
390 //**********************************************************************************************
391
392 //**Utility functions***************************************************************************
395 constexpr size_t rows() const noexcept;
396 constexpr size_t columns() const noexcept;
397 static constexpr size_t spacing() noexcept;
398 static constexpr size_t capacity() noexcept;
399 constexpr size_t capacity( size_t i ) const noexcept;
400 inline size_t nonZeros() const;
401 inline size_t nonZeros( size_t i ) const;
402 constexpr void reset();
403 constexpr void reset( size_t i );
404 constexpr void clear();
405 constexpr void resize ( size_t m, size_t n, bool preserve=true );
406 constexpr void extend ( size_t m, size_t n, bool preserve=true );
407 inline void swap( HybridMatrix& m ) noexcept;
409 //**********************************************************************************************
410
411 //**Numeric functions***************************************************************************
414 inline HybridMatrix& transpose();
415 inline HybridMatrix& ctranspose();
416
417 template< typename Other > inline HybridMatrix& scale( const Other& scalar );
419 //**********************************************************************************************
420
421 //**Memory functions****************************************************************************
424 static inline void* operator new ( std::size_t size );
425 static inline void* operator new[]( std::size_t size );
426 static inline void* operator new ( std::size_t size, const std::nothrow_t& );
427 static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
428
429 static inline void operator delete ( void* ptr );
430 static inline void operator delete[]( void* ptr );
431 static inline void operator delete ( void* ptr, const std::nothrow_t& );
432 static inline void operator delete[]( void* ptr, const std::nothrow_t& );
434 //**********************************************************************************************
435
436 private:
437 //**********************************************************************************************
439 static constexpr size_t SIMDSIZE = SIMDTrait<Type>::size;
440
442 static constexpr size_t NN = ( PF == padded ? nextMultiple( N, SIMDSIZE ) : N );
443 //**********************************************************************************************
444
445 //**********************************************************************************************
447
448 template< typename MT >
449 static constexpr bool VectorizedAssign_v =
450 ( useOptimizedKernels &&
451 NN >= SIMDSIZE &&
452 simdEnabled && MT::simdEnabled &&
453 IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
454 IsRowMajorMatrix_v<MT> );
456 //**********************************************************************************************
457
458 //**********************************************************************************************
460
461 template< typename MT >
462 static constexpr bool VectorizedAddAssign_v =
463 ( VectorizedAssign_v<MT> &&
464 HasSIMDAdd_v< Type, ElementType_t<MT> > &&
465 !IsDiagonal_v<MT> );
467 //**********************************************************************************************
468
469 //**********************************************************************************************
471
472 template< typename MT >
473 static constexpr bool VectorizedSubAssign_v =
474 ( VectorizedAssign_v<MT> &&
475 HasSIMDSub_v< Type, ElementType_t<MT> > &&
476 !IsDiagonal_v<MT> );
478 //**********************************************************************************************
479
480 //**********************************************************************************************
482
483 template< typename MT >
484 static constexpr bool VectorizedSchurAssign_v =
485 ( VectorizedAssign_v<MT> &&
486 HasSIMDMult_v< Type, ElementType_t<MT> > );
488 //**********************************************************************************************
489
490 public:
491 //**Debugging functions*************************************************************************
494 constexpr bool isIntact() const noexcept;
496 //**********************************************************************************************
497
498 //**Expression template evaluation functions****************************************************
501 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
502 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
503
504 static constexpr bool isAligned() noexcept;
505
506 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
507 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
508 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
509
510 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
511 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
512 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
513 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
514
515 template< typename MT, bool SO2 >
516 inline auto assign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
517
518 template< typename MT, bool SO2 >
519 inline auto assign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
520
521 template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
522 template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
523
524 template< typename MT, bool SO2 >
525 inline auto addAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
526
527 template< typename MT, bool SO2 >
528 inline auto addAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
529
530 template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
531 template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
532
533 template< typename MT, bool SO2 >
534 inline auto subAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
535
536 template< typename MT, bool SO2 >
537 inline auto subAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
538
539 template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
540 template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
541
542 template< typename MT, bool SO2 >
543 inline auto schurAssign( const DenseMatrix<MT,SO2>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
544
545 template< typename MT, bool SO2 >
546 inline auto schurAssign( const DenseMatrix<MT,SO2>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
547
548 template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
549 template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
551 //**********************************************************************************************
552
553 private:
554 //**********************************************************************************************
556 static constexpr size_t Alignment =
557 ( AF == aligned ? AlignmentOf_v<Type> : std::alignment_of<Type>::value );
558
561 //**********************************************************************************************
562
563 //**Member variables****************************************************************************
576 size_t m_;
577 size_t n_;
579 //**********************************************************************************************
580
581 //**Compile time checks*************************************************************************
587 BLAZE_STATIC_ASSERT( AF == unaligned || PF == padded || N % SIMDSIZE == 0UL );
588 BLAZE_STATIC_ASSERT( PF == unpadded || NN % SIMDSIZE == 0UL );
589 BLAZE_STATIC_ASSERT( NN >= N );
590 BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || NN == N );
592 //**********************************************************************************************
593};
594//*************************************************************************************************
595
596
597
598
599//=================================================================================================
600//
601// DEDUCTION GUIDES
602//
603//=================================================================================================
604
605//*************************************************************************************************
606#if BLAZE_CPP17_MODE
607
608template< typename Type, size_t M, size_t N >
609HybridMatrix( Type (&)[M][N] ) -> HybridMatrix< RemoveCV_t<Type>, M, N >;
610
611template< typename Type, size_t M, size_t N >
612HybridMatrix( std::array<std::array<Type,N>,M> ) -> HybridMatrix<Type,M,N>;
613
614#endif
615//*************************************************************************************************
616
617
618
619
620//=================================================================================================
621//
622// CONSTRUCTORS
623//
624//=================================================================================================
625
626//*************************************************************************************************
631template< typename Type // Data type of the matrix
632 , size_t M // Number of rows
633 , size_t N // Number of columns
634 , bool SO // Storage order
635 , AlignmentFlag AF // Alignment flag
636 , PaddingFlag PF // Padding flag
637 , typename Tag > // Type tag
639 : v_() // The statically allocated matrix elements
640 , m_( 0UL ) // The current number of rows of the matrix
641 , n_( 0UL ) // The current number of columns of the matrix
642{
643 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
644}
645//*************************************************************************************************
646
647
648//*************************************************************************************************
661template< typename Type // Data type of the matrix
662 , size_t M // Number of rows
663 , size_t N // Number of columns
664 , bool SO // Storage order
665 , AlignmentFlag AF // Alignment flag
666 , PaddingFlag PF // Padding flag
667 , typename Tag > // Type tag
669 : v_() // The statically allocated matrix elements
670 , m_( m ) // The current number of rows of the matrix
671 , n_( n ) // The current number of columns of the matrix
672{
673 if( m > M ) {
674 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
675 }
676
677 if( n > N ) {
678 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
679 }
680
681 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
682}
683//*************************************************************************************************
684
685
686//*************************************************************************************************
700template< typename Type // Data type of the matrix
701 , size_t M // Number of rows
702 , size_t N // Number of columns
703 , bool SO // Storage order
704 , AlignmentFlag AF // Alignment flag
705 , PaddingFlag PF // Padding flag
706 , typename Tag > // Type tag
707inline HybridMatrix<Type,M,N,SO,AF,PF,Tag>::HybridMatrix( size_t m, size_t n, const Type& init )
708 : m_( m ) // The current number of rows of the matrix
709 , n_( n ) // The current number of columns of the matrix
710 // v_ is intentionally left uninitialized
711{
712 using blaze::clear;
713
714 if( m > M ) {
715 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
716 }
717
718 if( n > N ) {
719 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
720 }
721
722 for( size_t i=0UL; i<m; ++i ) {
723 for( size_t j=0UL; j<n; ++j )
724 v_[i*NN+j] = init;
725
726 if( IsNumeric_v<Type> ) {
727 for( size_t j=n; j<NN; ++j )
728 clear( v_[i*NN+j] );
729 }
730 }
731
732 if( IsNumeric_v<Type> ) {
733 for( size_t i=m; i<M; ++i )
734 for( size_t j=0UL; j<NN; ++j )
735 clear( v_[i*NN+j] );
736 }
737
738 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
739}
740//*************************************************************************************************
741
742
743//*************************************************************************************************
767template< typename Type // Data type of the matrix
768 , size_t M // Number of rows
769 , size_t N // Number of columns
770 , bool SO // Storage order
771 , AlignmentFlag AF // Alignment flag
772 , PaddingFlag PF // Padding flag
773 , typename Tag > // Type tag
774constexpr HybridMatrix<Type,M,N,SO,AF,PF,Tag>::HybridMatrix( initializer_list< initializer_list<Type> > list )
775 : v_() // The statically allocated matrix elements
776 , m_( list.size() ) // The current number of rows of the matrix
777 , n_( determineColumns( list ) ) // The current number of columns of the matrix
778{
779 if( m_ > M ) {
780 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
781 }
782
783 if( n_ > N ) {
784 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
785 }
786
787 size_t i( 0UL );
788
789 for( const auto& rowList : list ) {
790 size_t j( 0UL );
791 for( const auto& element : rowList ) {
792 v_[i*NN+j] = element;
793 ++j;
794 }
795 ++i;
796 }
797
798 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
799}
800//*************************************************************************************************
801
802
803//*************************************************************************************************
830template< typename Type // Data type of the matrix
831 , size_t M // Number of rows
832 , size_t N // Number of columns
833 , bool SO // Storage order
834 , AlignmentFlag AF // Alignment flag
835 , PaddingFlag PF // Padding flag
836 , typename Tag > // Type tag
837template< typename Other > // Data type of the initialization array
838inline HybridMatrix<Type,M,N,SO,AF,PF,Tag>::HybridMatrix( size_t m, size_t n, const Other* array )
839 : m_( m ) // The current number of rows of the matrix
840 , n_( n ) // The current number of columns of the matrix
841 // v_ is intentionally left uninitialized
842{
843 using blaze::clear;
844
845 if( m > M ) {
846 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
847 }
848
849 if( n > N ) {
850 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
851 }
852
853 for( size_t i=0UL; i<m; ++i ) {
854 for( size_t j=0UL; j<n; ++j )
855 v_[i*NN+j] = array[i*n+j];
856
857 if( IsNumeric_v<Type> ) {
858 for( size_t j=n; j<NN; ++j )
859 clear( v_[i*NN+j] );
860 }
861 }
862
863 if( IsNumeric_v<Type> ) {
864 for( size_t i=m; i<M; ++i )
865 for( size_t j=0UL; j<NN; ++j )
866 clear( v_[i*NN+j] );
867 }
868
869 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
870}
871//*************************************************************************************************
872
873
874//*************************************************************************************************
895template< typename Type // Data type of the matrix
896 , size_t M // Number of rows
897 , size_t N // Number of columns
898 , bool SO // Storage order
899 , AlignmentFlag AF // Alignment flag
900 , PaddingFlag PF // Padding flag
901 , typename Tag > // Type tag
902template< typename Other // Data type of the static array
903 , size_t Rows // Number of rows of the static array
904 , size_t Cols > // Number of columns of the static array
905inline HybridMatrix<Type,M,N,SO,AF,PF,Tag>::HybridMatrix( const Other (&array)[Rows][Cols] )
906 : m_( Rows ) // The current number of rows of the matrix
907 , n_( Cols ) // The current number of columns of the matrix
908 // v_ is intentionally left uninitialized
909{
910 using blaze::clear;
911
912 BLAZE_STATIC_ASSERT( Rows <= M );
913 BLAZE_STATIC_ASSERT( Cols <= N );
914
915 for( size_t i=0UL; i<Rows; ++i ) {
916 for( size_t j=0UL; j<Cols; ++j )
917 v_[i*NN+j] = array[i][j];
918
919 if( IsNumeric_v<Type> ) {
920 for( size_t j=Cols; j<NN; ++j )
921 clear( v_[i*NN+j] );
922 }
923 }
924
925 if( IsNumeric_v<Type> ) {
926 for( size_t i=Rows; i<M; ++i )
927 for( size_t j=0UL; j<NN; ++j )
928 clear( v_[i*NN+j] );
929 }
930
931 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
932}
933//*************************************************************************************************
934
935
936//*************************************************************************************************
957template< typename Type // Data type of the matrix
958 , size_t M // Number of rows
959 , size_t N // Number of columns
960 , bool SO // Storage order
961 , AlignmentFlag AF // Alignment flag
962 , PaddingFlag PF // Padding flag
963 , typename Tag > // Type tag
964template< typename Other // Data type of the static array
965 , size_t Rows // Number of rows of the static array
966 , size_t Cols > // Number of columns of the static array
967inline HybridMatrix<Type,M,N,SO,AF,PF,Tag>::HybridMatrix( const std::array<std::array<Other,Cols>,Rows>& array )
968 : m_( Rows ) // The current number of rows of the matrix
969 , n_( Cols ) // The current number of columns of the matrix
970 // v_ is intentionally left uninitialized
971{
972 using blaze::clear;
973
974 BLAZE_STATIC_ASSERT( Rows <= M );
975 BLAZE_STATIC_ASSERT( Cols <= N );
976
977 for( size_t i=0UL; i<Rows; ++i ) {
978 for( size_t j=0UL; j<Cols; ++j )
979 v_[i*NN+j] = array[i][j];
980
981 if( IsNumeric_v<Type> ) {
982 for( size_t j=Cols; j<NN; ++j )
983 clear( v_[i*NN+j] );
984 }
985 }
986
987 if( IsNumeric_v<Type> ) {
988 for( size_t i=Rows; i<M; ++i )
989 for( size_t j=0UL; j<NN; ++j )
990 clear( v_[i*NN+j] );
991 }
992
993 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
994}
995//*************************************************************************************************
996
997
998//*************************************************************************************************
1006template< typename Type // Data type of the matrix
1007 , size_t M // Number of rows
1008 , size_t N // Number of columns
1009 , bool SO // Storage order
1010 , AlignmentFlag AF // Alignment flag
1011 , PaddingFlag PF // Padding flag
1012 , typename Tag > // Type tag
1014 : BaseType() // Initialization of the base class
1015 , v_( m.v_ ) // The statically allocated matrix elements
1016 , m_( m.m_ ) // The current number of rows of the matrix
1017 , n_( m.n_ ) // The current number of columns of the matrix{
1018{
1019 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1020}
1021//*************************************************************************************************
1022
1023
1024//*************************************************************************************************
1030template< typename Type // Data type of the matrix
1031 , size_t M // Number of rows
1032 , size_t N // Number of columns
1033 , bool SO // Storage order
1034 , AlignmentFlag AF // Alignment flag
1035 , PaddingFlag PF // Padding flag
1036 , typename Tag > // Type tag
1037template< typename MT // Type of the foreign matrix
1038 , bool SO2 > // Storage order of the foreign matrix
1040 : m_( (*m).rows() ) // The current number of rows of the matrix
1041 , n_( (*m).columns() ) // The current number of columns of the matrix
1042 // v_ is intentionally left uninitialized
1043{
1044 using blaze::assign;
1045 using blaze::clear;
1046
1048
1049 if( (*m).rows() > M || (*m).columns() > N ) {
1050 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
1051 }
1052
1053 for( size_t i=0UL; i<m_; ++i ) {
1054 for( size_t j=( IsSparseMatrix_v<MT> ? 0UL : n_ );
1055 j<( IsNumeric_v<Type> ? NN : n_ );
1056 ++j ) {
1057 clear( v_[i*NN+j] );
1058 }
1059 }
1060
1061 if( IsNumeric_v<Type> ) {
1062 for( size_t i=m_; i<M; ++i )
1063 for( size_t j=0UL; j<NN; ++j )
1064 clear( v_[i*NN+j] );
1065 }
1066
1067 assign( *this, *m );
1068
1069 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1070}
1071//*************************************************************************************************
1072
1073
1074
1075
1076//=================================================================================================
1077//
1078// DATA ACCESS FUNCTIONS
1079//
1080//=================================================================================================
1081
1082//*************************************************************************************************
1092template< typename Type // Data type of the matrix
1093 , size_t M // Number of rows
1094 , size_t N // Number of columns
1095 , bool SO // Storage order
1096 , AlignmentFlag AF // Alignment flag
1097 , PaddingFlag PF // Padding flag
1098 , typename Tag > // Type tag
1101{
1102 BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1103 BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1104 return v_[i*NN+j];
1105}
1106//*************************************************************************************************
1107
1108
1109//*************************************************************************************************
1119template< typename Type // Data type of the matrix
1120 , size_t M // Number of rows
1121 , size_t N // Number of columns
1122 , bool SO // Storage order
1123 , AlignmentFlag AF // Alignment flag
1124 , PaddingFlag PF // Padding flag
1125 , typename Tag > // Type tag
1127 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator()( size_t i, size_t j ) const noexcept
1128{
1129 BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1130 BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1131 return v_[i*NN+j];
1132}
1133//*************************************************************************************************
1134
1135
1136//*************************************************************************************************
1147template< typename Type // Data type of the matrix
1148 , size_t M // Number of rows
1149 , size_t N // Number of columns
1150 , bool SO // Storage order
1151 , AlignmentFlag AF // Alignment flag
1152 , PaddingFlag PF // Padding flag
1153 , typename Tag > // Type tag
1156{
1157 if( i >= m_ ) {
1158 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1159 }
1160 if( j >= n_ ) {
1161 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1162 }
1163 return (*this)(i,j);
1164}
1165//*************************************************************************************************
1166
1167
1168//*************************************************************************************************
1179template< typename Type // Data type of the matrix
1180 , size_t M // Number of rows
1181 , size_t N // Number of columns
1182 , bool SO // Storage order
1183 , AlignmentFlag AF // Alignment flag
1184 , PaddingFlag PF // Padding flag
1185 , typename Tag > // Type tag
1188{
1189 if( i >= m_ ) {
1190 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1191 }
1192 if( j >= n_ ) {
1193 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1194 }
1195 return (*this)(i,j);
1196}
1197//*************************************************************************************************
1198
1199
1200//*************************************************************************************************
1212template< typename Type // Data type of the matrix
1213 , size_t M // Number of rows
1214 , size_t N // Number of columns
1215 , bool SO // Storage order
1216 , AlignmentFlag AF // Alignment flag
1217 , PaddingFlag PF // Padding flag
1218 , typename Tag > // Type tag
1221{
1222 return v_;
1223}
1224//*************************************************************************************************
1225
1226
1227//*************************************************************************************************
1239template< typename Type // Data type of the matrix
1240 , size_t M // Number of rows
1241 , size_t N // Number of columns
1242 , bool SO // Storage order
1243 , AlignmentFlag AF // Alignment flag
1244 , PaddingFlag PF // Padding flag
1245 , typename Tag > // Type tag
1248{
1249 return v_;
1250}
1251//*************************************************************************************************
1252
1253
1254//*************************************************************************************************
1262template< typename Type // Data type of the matrix
1263 , size_t M // Number of rows
1264 , size_t N // Number of columns
1265 , bool SO // Storage order
1266 , AlignmentFlag AF // Alignment flag
1267 , PaddingFlag PF // Padding flag
1268 , typename Tag > // Type tag
1271{
1272 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1273 return v_ + i*NN;
1274}
1275//*************************************************************************************************
1276
1277
1278//*************************************************************************************************
1286template< typename Type // Data type of the matrix
1287 , size_t M // Number of rows
1288 , size_t N // Number of columns
1289 , bool SO // Storage order
1290 , AlignmentFlag AF // Alignment flag
1291 , PaddingFlag PF // Padding flag
1292 , typename Tag > // Type tag
1295{
1296 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1297 return v_ + i*NN;
1298}
1299//*************************************************************************************************
1300
1301
1302//*************************************************************************************************
1313template< typename Type // Data type of the matrix
1314 , size_t M // Number of rows
1315 , size_t N // Number of columns
1316 , bool SO // Storage order
1317 , AlignmentFlag AF // Alignment flag
1318 , PaddingFlag PF // Padding flag
1319 , typename Tag > // Type tag
1322{
1323 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1324 return Iterator( v_ + i*NN );
1325}
1326//*************************************************************************************************
1327
1328
1329//*************************************************************************************************
1340template< typename Type // Data type of the matrix
1341 , size_t M // Number of rows
1342 , size_t N // Number of columns
1343 , bool SO // Storage order
1344 , AlignmentFlag AF // Alignment flag
1345 , PaddingFlag PF // Padding flag
1346 , typename Tag > // Type tag
1349{
1350 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1351 return ConstIterator( v_ + i*NN );
1352}
1353//*************************************************************************************************
1354
1355
1356//*************************************************************************************************
1367template< typename Type // Data type of the matrix
1368 , size_t M // Number of rows
1369 , size_t N // Number of columns
1370 , bool SO // Storage order
1371 , AlignmentFlag AF // Alignment flag
1372 , PaddingFlag PF // Padding flag
1373 , typename Tag > // Type tag
1376{
1377 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1378 return ConstIterator( v_ + i*NN );
1379}
1380//*************************************************************************************************
1381
1382
1383//*************************************************************************************************
1394template< typename Type // Data type of the matrix
1395 , size_t M // Number of rows
1396 , size_t N // Number of columns
1397 , bool SO // Storage order
1398 , AlignmentFlag AF // Alignment flag
1399 , PaddingFlag PF // Padding flag
1400 , typename Tag > // Type tag
1403{
1404 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1405 return Iterator( v_ + i*NN + N );
1406}
1407//*************************************************************************************************
1408
1409
1410//*************************************************************************************************
1421template< typename Type // Data type of the matrix
1422 , size_t M // Number of rows
1423 , size_t N // Number of columns
1424 , bool SO // Storage order
1425 , AlignmentFlag AF // Alignment flag
1426 , PaddingFlag PF // Padding flag
1427 , typename Tag > // Type tag
1430{
1431 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1432 return ConstIterator( v_ + i*NN + N );
1433}
1434//*************************************************************************************************
1435
1436
1437//*************************************************************************************************
1448template< typename Type // Data type of the matrix
1449 , size_t M // Number of rows
1450 , size_t N // Number of columns
1451 , bool SO // Storage order
1452 , AlignmentFlag AF // Alignment flag
1453 , PaddingFlag PF // Padding flag
1454 , typename Tag > // Type tag
1457{
1458 BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1459 return ConstIterator( v_ + i*NN + N );
1460}
1461//*************************************************************************************************
1462
1463
1464
1465
1466//=================================================================================================
1467//
1468// ASSIGNMENT OPERATORS
1469//
1470//=================================================================================================
1471
1472//*************************************************************************************************
1478template< typename Type // Data type of the matrix
1479 , size_t M // Number of rows
1480 , size_t N // Number of columns
1481 , bool SO // Storage order
1482 , AlignmentFlag AF // Alignment flag
1483 , PaddingFlag PF // Padding flag
1484 , typename Tag > // Type tag
1487{
1488 BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1489 BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1490
1491 for( size_t i=0UL; i<m_; ++i )
1492 for( size_t j=0UL; j<n_; ++j )
1493 v_[i*NN+j] = set;
1494
1495 return *this;
1496}
1497//*************************************************************************************************
1498
1499
1500//*************************************************************************************************
1525template< typename Type // Data type of the matrix
1526 , size_t M // Number of rows
1527 , size_t N // Number of columns
1528 , bool SO // Storage order
1529 , AlignmentFlag AF // Alignment flag
1530 , PaddingFlag PF // Padding flag
1531 , typename Tag > // Type tag
1533 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator=( initializer_list< initializer_list<Type> > list ) &
1534{
1535 using blaze::clear;
1536
1537 const size_t m( list.size() );
1538 const size_t n( determineColumns( list ) );
1539
1540 if( m > M ) {
1541 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1542 }
1543
1544 if( n > N ) {
1545 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1546 }
1547
1548 resize( m, n, false );
1549
1550 size_t i( 0UL );
1551
1552 for( const auto& rowList : list ) {
1553 size_t j( 0UL );
1554 for( const auto& element : rowList ) {
1555 v_[i*NN+j] = element;
1556 ++j;
1557 }
1558 for( ; j<N; ++j ) {
1559 clear( v_[i*NN+j] );
1560 }
1561 ++i;
1562 }
1563
1564 return *this;
1565}
1566//*************************************************************************************************
1567
1568
1569//*************************************************************************************************
1590template< typename Type // Data type of the matrix
1591 , size_t M // Number of rows
1592 , size_t N // Number of columns
1593 , bool SO // Storage order
1594 , AlignmentFlag AF // Alignment flag
1595 , PaddingFlag PF // Padding flag
1596 , typename Tag > // Type tag
1597template< typename Other // Data type of the static array
1598 , size_t Rows // Number of rows of the static array
1599 , size_t Cols > // Number of columns of the static array
1601 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator=( const Other (&array)[Rows][Cols] ) &
1602{
1603 BLAZE_STATIC_ASSERT( Rows <= M );
1604 BLAZE_STATIC_ASSERT( Cols <= N );
1605
1606 resize( Rows, Cols );
1607
1608 for( size_t i=0UL; i<Rows; ++i )
1609 for( size_t j=0UL; j<Cols; ++j )
1610 v_[i*NN+j] = array[i][j];
1611
1612 return *this;
1613}
1614//*************************************************************************************************
1615
1616
1617//*************************************************************************************************
1638template< typename Type // Data type of the matrix
1639 , size_t M // Number of rows
1640 , size_t N // Number of columns
1641 , bool SO // Storage order
1642 , AlignmentFlag AF // Alignment flag
1643 , PaddingFlag PF // Padding flag
1644 , typename Tag > // Type tag
1645template< typename Other // Data type of the static array
1646 , size_t Rows // Number of rows of the static array
1647 , size_t Cols > // Number of columns of the static array
1649 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &
1650{
1651 BLAZE_STATIC_ASSERT( Rows <= M );
1652 BLAZE_STATIC_ASSERT( Cols <= N );
1653
1654 resize( Rows, Cols );
1655
1656 for( size_t i=0UL; i<Rows; ++i )
1657 for( size_t j=0UL; j<Cols; ++j )
1658 v_[i*NN+j] = array[i][j];
1659
1660 return *this;
1661}
1662//*************************************************************************************************
1663
1664
1665//*************************************************************************************************
1673template< typename Type // Data type of the matrix
1674 , size_t M // Number of rows
1675 , size_t N // Number of columns
1676 , bool SO // Storage order
1677 , AlignmentFlag AF // Alignment flag
1678 , PaddingFlag PF // Padding flag
1679 , typename Tag > // Type tag
1682{
1683 using blaze::assign;
1684
1685 BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1686 BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1687
1688 resize( rhs.rows(), rhs.columns() );
1689 assign( *this, *rhs );
1690
1691 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1692
1693 return *this;
1694}
1695//*************************************************************************************************
1696
1697
1698//*************************************************************************************************
1709template< typename Type // Data type of the matrix
1710 , size_t M // Number of rows
1711 , size_t N // Number of columns
1712 , bool SO // Storage order
1713 , AlignmentFlag AF // Alignment flag
1714 , PaddingFlag PF // Padding flag
1715 , typename Tag > // Type tag
1716template< typename MT // Type of the right-hand side matrix
1717 , bool SO2 > // Storage order of the right-hand side matrix
1720{
1721 using blaze::assign;
1722
1723 using TT = decltype( trans( *this ) );
1724 using CT = decltype( ctrans( *this ) );
1725 using IT = decltype( inv( *this ) );
1726
1728
1729 if( (*rhs).rows() > M || (*rhs).columns() > N ) {
1730 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
1731 }
1732
1733 if( IsSame_v<MT,TT> && (*rhs).isAliased( this ) ) {
1734 transpose();
1735 }
1736 else if( IsSame_v<MT,CT> && (*rhs).isAliased( this ) ) {
1737 ctranspose();
1738 }
1739 else if( !IsSame_v<MT,IT> && (*rhs).canAlias( this ) ) {
1740 HybridMatrix tmp( *rhs );
1741 resize( tmp.rows(), tmp.columns() );
1742 assign( *this, tmp );
1743 }
1744 else {
1745 resize( (*rhs).rows(), (*rhs).columns() );
1746 if( IsSparseMatrix_v<MT> )
1747 reset();
1748 assign( *this, *rhs );
1749 }
1750
1751 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1752
1753 return *this;
1754}
1755//*************************************************************************************************
1756
1757
1758//*************************************************************************************************
1768template< typename Type // Data type of the matrix
1769 , size_t M // Number of rows
1770 , size_t N // Number of columns
1771 , bool SO // Storage order
1772 , AlignmentFlag AF // Alignment flag
1773 , PaddingFlag PF // Padding flag
1774 , typename Tag > // Type tag
1775template< typename MT // Type of the right-hand side matrix
1776 , bool SO2 > // Storage order of the right-hand side matrix
1779{
1780 using blaze::addAssign;
1781
1783
1784 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1785 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1786 }
1787
1788 if( (*rhs).canAlias( this ) ) {
1789 const ResultType_t<MT> tmp( *rhs );
1790 addAssign( *this, tmp );
1791 }
1792 else {
1793 addAssign( *this, *rhs );
1794 }
1795
1796 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1797
1798 return *this;
1799}
1800//*************************************************************************************************
1801
1802
1803//*************************************************************************************************
1813template< typename Type // Data type of the matrix
1814 , size_t M // Number of rows
1815 , size_t N // Number of columns
1816 , bool SO // Storage order
1817 , AlignmentFlag AF // Alignment flag
1818 , PaddingFlag PF // Padding flag
1819 , typename Tag > // Type tag
1820template< typename MT // Type of the right-hand side matrix
1821 , bool SO2 > // Storage order of the right-hand side matrix
1824{
1825 using blaze::subAssign;
1826
1828
1829 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1830 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1831 }
1832
1833 if( (*rhs).canAlias( this ) ) {
1834 const ResultType_t<MT> tmp( *rhs );
1835 subAssign( *this, tmp );
1836 }
1837 else {
1838 subAssign( *this, *rhs );
1839 }
1840
1841 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1842
1843 return *this;
1844}
1845//*************************************************************************************************
1846
1847
1848//*************************************************************************************************
1858template< typename Type // Data type of the matrix
1859 , size_t M // Number of rows
1860 , size_t N // Number of columns
1861 , bool SO // Storage order
1862 , AlignmentFlag AF // Alignment flag
1863 , PaddingFlag PF // Padding flag
1864 , typename Tag > // Type tag
1865template< typename MT // Type of the right-hand side matrix
1866 , bool SO2 > // Storage order of the right-hand side matrix
1869{
1870 using blaze::schurAssign;
1871
1873
1874 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1875 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1876 }
1877
1878 if( (*rhs).canAlias( this ) ) {
1879 const ResultType_t<MT> tmp( *rhs );
1880 schurAssign( *this, tmp );
1881 }
1882 else {
1883 schurAssign( *this, *rhs );
1884 }
1885
1886 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1887
1888 return *this;
1889}
1890//*************************************************************************************************
1891
1892
1893
1894
1895//=================================================================================================
1896//
1897// UTILITY FUNCTIONS
1898//
1899//=================================================================================================
1900
1901//*************************************************************************************************
1906template< typename Type // Data type of the matrix
1907 , size_t M // Number of rows
1908 , size_t N // Number of columns
1909 , bool SO // Storage order
1910 , AlignmentFlag AF // Alignment flag
1911 , PaddingFlag PF // Padding flag
1912 , typename Tag > // Type tag
1913constexpr size_t HybridMatrix<Type,M,N,SO,AF,PF,Tag>::rows() const noexcept
1914{
1915 return m_;
1916}
1917//*************************************************************************************************
1918
1919
1920//*************************************************************************************************
1925template< typename Type // Data type of the matrix
1926 , size_t M // Number of rows
1927 , size_t N // Number of columns
1928 , bool SO // Storage order
1929 , AlignmentFlag AF // Alignment flag
1930 , PaddingFlag PF // Padding flag
1931 , typename Tag > // Type tag
1932constexpr size_t HybridMatrix<Type,M,N,SO,AF,PF,Tag>::columns() const noexcept
1933{
1934 return n_;
1935}
1936//*************************************************************************************************
1937
1938
1939//*************************************************************************************************
1947template< typename Type // Data type of the matrix
1948 , size_t M // Number of rows
1949 , size_t N // Number of columns
1950 , bool SO // Storage order
1951 , AlignmentFlag AF // Alignment flag
1952 , PaddingFlag PF // Padding flag
1953 , typename Tag > // Type tag
1955{
1956 return NN;
1957}
1958//*************************************************************************************************
1959
1960
1961//*************************************************************************************************
1966template< typename Type // Data type of the matrix
1967 , size_t M // Number of rows
1968 , size_t N // Number of columns
1969 , bool SO // Storage order
1970 , AlignmentFlag AF // Alignment flag
1971 , PaddingFlag PF // Padding flag
1972 , typename Tag > // Type tag
1974{
1975 return M*NN;
1976}
1977//*************************************************************************************************
1978
1979
1980//*************************************************************************************************
1991template< typename Type // Data type of the matrix
1992 , size_t M // Number of rows
1993 , size_t N // Number of columns
1994 , bool SO // Storage order
1995 , AlignmentFlag AF // Alignment flag
1996 , PaddingFlag PF // Padding flag
1997 , typename Tag > // Type tag
1998constexpr size_t HybridMatrix<Type,M,N,SO,AF,PF,Tag>::capacity( size_t i ) const noexcept
1999{
2000 MAYBE_UNUSED( i );
2001
2002 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2003
2004 return NN;
2005}
2006//*************************************************************************************************
2007
2008
2009//*************************************************************************************************
2018template< typename Type // Data type of the matrix
2019 , size_t M // Number of rows
2020 , size_t N // Number of columns
2021 , bool SO // Storage order
2022 , AlignmentFlag AF // Alignment flag
2023 , PaddingFlag PF // Padding flag
2024 , typename Tag > // Type tag
2026{
2027 size_t nonzeros( 0UL );
2028
2029 for( size_t i=0UL; i<m_; ++i )
2030 for( size_t j=0UL; j<n_; ++j )
2031 if( !isDefault<strict>( v_[i*NN+j] ) )
2032 ++nonzeros;
2033
2034 return nonzeros;
2035}
2036//*************************************************************************************************
2037
2038
2039//*************************************************************************************************
2051template< typename Type // Data type of the matrix
2052 , size_t M // Number of rows
2053 , size_t N // Number of columns
2054 , bool SO // Storage order
2055 , AlignmentFlag AF // Alignment flag
2056 , PaddingFlag PF // Padding flag
2057 , typename Tag > // Type tag
2059{
2060 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2061
2062 const size_t jend( i*NN + n_ );
2063 size_t nonzeros( 0UL );
2064
2065 for( size_t j=i*NN; j<jend; ++j )
2066 if( !isDefault<strict>( v_[j] ) )
2067 ++nonzeros;
2068
2069 return nonzeros;
2070}
2071//*************************************************************************************************
2072
2073
2074//*************************************************************************************************
2079template< typename Type // Data type of the matrix
2080 , size_t M // Number of rows
2081 , size_t N // Number of columns
2082 , bool SO // Storage order
2083 , AlignmentFlag AF // Alignment flag
2084 , PaddingFlag PF // Padding flag
2085 , typename Tag > // Type tag
2087{
2088 using blaze::clear;
2089
2090 for( size_t i=0UL; i<m_; ++i )
2091 for( size_t j=0UL; j<n_; ++j )
2092 clear( v_[i*NN+j] );
2093}
2094//*************************************************************************************************
2095
2096
2097//*************************************************************************************************
2108template< typename Type // Data type of the matrix
2109 , size_t M // Number of rows
2110 , size_t N // Number of columns
2111 , bool SO // Storage order
2112 , AlignmentFlag AF // Alignment flag
2113 , PaddingFlag PF // Padding flag
2114 , typename Tag > // Type tag
2116{
2117 using blaze::clear;
2118
2119 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2120 for( size_t j=0UL; j<n_; ++j )
2121 clear( v_[i*NN+j] );
2122}
2123//*************************************************************************************************
2124
2125
2126//*************************************************************************************************
2133template< typename Type // Data type of the matrix
2134 , size_t M // Number of rows
2135 , size_t N // Number of columns
2136 , bool SO // Storage order
2137 , AlignmentFlag AF // Alignment flag
2138 , PaddingFlag PF // Padding flag
2139 , typename Tag > // Type tag
2141{
2142 resize( 0UL, 0UL );
2143}
2144//*************************************************************************************************
2145
2146
2147//*************************************************************************************************
2183template< typename Type // Data type of the matrix
2184 , size_t M // Number of rows
2185 , size_t N // Number of columns
2186 , bool SO // Storage order
2187 , AlignmentFlag AF // Alignment flag
2188 , PaddingFlag PF // Padding flag
2189 , typename Tag > // Type tag
2190constexpr void HybridMatrix<Type,M,N,SO,AF,PF,Tag>::resize( size_t m, size_t n, bool preserve )
2191{
2192 using blaze::clear;
2193
2194 MAYBE_UNUSED( preserve );
2195
2196 if( m > M ) {
2197 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
2198 }
2199
2200 if( n > N ) {
2201 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
2202 }
2203
2204 if( IsVectorizable_v<Type> && n < n_ ) {
2205 for( size_t i=0UL; i<m; ++i )
2206 for( size_t j=n; j<n_; ++j )
2207 clear( v_[i*NN+j] );
2208 }
2209
2210 if( IsVectorizable_v<Type> && m < m_ ) {
2211 for( size_t i=m; i<m_; ++i )
2212 for( size_t j=0UL; j<n_; ++j )
2213 clear( v_[i*NN+j] );
2214 }
2215
2216 m_ = m;
2217 n_ = n;
2218}
2219//*************************************************************************************************
2220
2221
2222//*************************************************************************************************
2237template< typename Type // Data type of the matrix
2238 , size_t M // Number of rows
2239 , size_t N // Number of columns
2240 , bool SO // Storage order
2241 , AlignmentFlag AF // Alignment flag
2242 , PaddingFlag PF // Padding flag
2243 , typename Tag > // Type tag
2244constexpr void HybridMatrix<Type,M,N,SO,AF,PF,Tag>::extend( size_t m, size_t n, bool preserve )
2245{
2246 MAYBE_UNUSED( preserve );
2247 resize( m_+m, n_+n );
2248}
2249//*************************************************************************************************
2250
2251
2252//*************************************************************************************************
2258template< typename Type // Data type of the matrix
2259 , size_t M // Number of rows
2260 , size_t N // Number of columns
2261 , bool SO // Storage order
2262 , AlignmentFlag AF // Alignment flag
2263 , PaddingFlag PF // Padding flag
2264 , typename Tag > // Type tag
2266{
2267 using std::swap;
2268
2269 const size_t maxrows( max( m_, m.m_ ) );
2270 const size_t maxcols( max( n_, m.n_ ) );
2271
2272 for( size_t i=0UL; i<maxrows; ++i ) {
2273 for( size_t j=0UL; j<maxcols; ++j ) {
2274 swap( v_[i*NN+j], m(i,j) );
2275 }
2276 }
2277
2278 swap( m_, m.m_ );
2279 swap( n_, m.n_ );
2280}
2281//*************************************************************************************************
2282
2283
2284
2285
2286//=================================================================================================
2287//
2288// NUMERIC FUNCTIONS
2289//
2290//=================================================================================================
2291
2292//*************************************************************************************************
2303template< typename Type // Data type of the matrix
2304 , size_t M // Number of rows
2305 , size_t N // Number of columns
2306 , bool SO // Storage order
2307 , AlignmentFlag AF // Alignment flag
2308 , PaddingFlag PF // Padding flag
2309 , typename Tag > // Type tag
2311{
2312 using std::swap;
2313 using blaze::clear;
2314
2315 if( m_ > N || n_ > M ) {
2316 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2317 }
2318
2319 const size_t maxsize( max( m_, n_ ) );
2320 for( size_t i=1UL; i<maxsize; ++i ) {
2321 for( size_t j=0UL; j<i; ++j ) {
2322 swap( v_[i*NN+j], v_[j*NN+i] );
2323 }
2324 }
2325
2326 if( IsVectorizable_v<Type> && m_ < n_ ) {
2327 for( size_t i=0UL; i<m_; ++i ) {
2328 for( size_t j=m_; j<n_; ++j ) {
2329 clear( v_[i*NN+j] );
2330 }
2331 }
2332 }
2333
2334 if( IsVectorizable_v<Type> && m_ > n_ ) {
2335 for( size_t i=n_; i<m_; ++i ) {
2336 for( size_t j=0UL; j<n_; ++j ) {
2337 clear( v_[i*NN+j] );
2338 }
2339 }
2340 }
2341
2342 swap( m_, n_ );
2343
2344 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2345
2346 return *this;
2347}
2348//*************************************************************************************************
2349
2350
2351//*************************************************************************************************
2362template< typename Type // Data type of the matrix
2363 , size_t M // Number of rows
2364 , size_t N // Number of columns
2365 , bool SO // Storage order
2366 , AlignmentFlag AF // Alignment flag
2367 , PaddingFlag PF // Padding flag
2368 , typename Tag > // Type tag
2370{
2371 using std::swap;
2372 using blaze::clear;
2373
2374 if( m_ > N || n_ > M ) {
2375 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2376 }
2377
2378 const size_t maxsize( max( m_, n_ ) );
2379 for( size_t i=0UL; i<maxsize; ++i ) {
2380 for( size_t j=0UL; j<i; ++j ) {
2381 cswap( v_[i*NN+j], v_[j*NN+i] );
2382 }
2383 conjugate( v_[i*NN+i] );
2384 }
2385
2386 if( IsVectorizable_v<Type> && m_ < n_ ) {
2387 for( size_t i=0UL; i<m_; ++i ) {
2388 for( size_t j=m_; j<n_; ++j ) {
2389 clear( v_[i*NN+j] );
2390 }
2391 }
2392 }
2393
2394 if( IsVectorizable_v<Type> && m_ > n_ ) {
2395 for( size_t i=n_; i<m_; ++i ) {
2396 for( size_t j=0UL; j<n_; ++j ) {
2397 clear( v_[i*NN+j] );
2398 }
2399 }
2400 }
2401
2402 swap( m_, n_ );
2403
2404 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2405
2406 return *this;
2407}
2408//*************************************************************************************************
2409
2410
2411//*************************************************************************************************
2428template< typename Type // Data type of the matrix
2429 , size_t M // Number of rows
2430 , size_t N // Number of columns
2431 , bool SO // Storage order
2432 , AlignmentFlag AF // Alignment flag
2433 , PaddingFlag PF // Padding flag
2434 , typename Tag > // Type tag
2435template< typename Other > // Data type of the scalar value
2438{
2439 for( size_t i=0UL; i<m_; ++i )
2440 for( size_t j=0UL; j<n_; ++j )
2441 v_[i*NN+j] *= scalar;
2442
2443 return *this;
2444}
2445//*************************************************************************************************
2446
2447
2448
2449
2450//=================================================================================================
2451//
2452// MEMORY FUNCTIONS
2453//
2454//=================================================================================================
2455
2456//*************************************************************************************************
2466template< typename Type // Data type of the matrix
2467 , size_t M // Number of rows
2468 , size_t N // Number of columns
2469 , bool SO // Storage order
2470 , AlignmentFlag AF // Alignment flag
2471 , PaddingFlag PF // Padding flag
2472 , typename Tag > // Type tag
2474{
2475 MAYBE_UNUSED( size );
2476
2477 BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2478
2479 return allocate<HybridMatrix>( 1UL );
2480}
2481//*************************************************************************************************
2482
2483
2484//*************************************************************************************************
2494template< typename Type // Data type of the matrix
2495 , size_t M // Number of rows
2496 , size_t N // Number of columns
2497 , bool SO // Storage order
2498 , AlignmentFlag AF // Alignment flag
2499 , PaddingFlag PF // Padding flag
2500 , typename Tag > // Type tag
2502{
2503 BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2504 BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2505
2506 return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2507}
2508//*************************************************************************************************
2509
2510
2511//*************************************************************************************************
2521template< typename Type // Data type of the matrix
2522 , size_t M // Number of rows
2523 , size_t N // Number of columns
2524 , bool SO // Storage order
2525 , AlignmentFlag AF // Alignment flag
2526 , PaddingFlag PF // Padding flag
2527 , typename Tag > // Type tag
2528inline void* HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator new( std::size_t size, const std::nothrow_t& )
2529{
2530 MAYBE_UNUSED( size );
2531
2532 BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2533
2534 return allocate<HybridMatrix>( 1UL );
2535}
2536//*************************************************************************************************
2537
2538
2539//*************************************************************************************************
2549template< typename Type // Data type of the matrix
2550 , size_t M // Number of rows
2551 , size_t N // Number of columns
2552 , bool SO // Storage order
2553 , AlignmentFlag AF // Alignment flag
2554 , PaddingFlag PF // Padding flag
2555 , typename Tag > // Type tag
2556inline void* HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator new[]( std::size_t size, const std::nothrow_t& )
2557{
2558 BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2559 BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2560
2561 return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2562}
2563//*************************************************************************************************
2564
2565
2566//*************************************************************************************************
2572template< typename Type // Data type of the matrix
2573 , size_t M // Number of rows
2574 , size_t N // Number of columns
2575 , bool SO // Storage order
2576 , AlignmentFlag AF // Alignment flag
2577 , PaddingFlag PF // Padding flag
2578 , typename Tag > // Type tag
2580{
2581 deallocate( static_cast<HybridMatrix*>( ptr ) );
2582}
2583//*************************************************************************************************
2584
2585
2586//*************************************************************************************************
2592template< typename Type // Data type of the matrix
2593 , size_t M // Number of rows
2594 , size_t N // Number of columns
2595 , bool SO // Storage order
2596 , AlignmentFlag AF // Alignment flag
2597 , PaddingFlag PF // Padding flag
2598 , typename Tag > // Type tag
2599inline void HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator delete[]( void* ptr )
2600{
2601 deallocate( static_cast<HybridMatrix*>( ptr ) );
2602}
2603//*************************************************************************************************
2604
2605
2606//*************************************************************************************************
2612template< typename Type // Data type of the matrix
2613 , size_t M // Number of rows
2614 , size_t N // Number of columns
2615 , bool SO // Storage order
2616 , AlignmentFlag AF // Alignment flag
2617 , PaddingFlag PF // Padding flag
2618 , typename Tag > // Type tag
2619inline void HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator delete( void* ptr, const std::nothrow_t& )
2620{
2621 deallocate( static_cast<HybridMatrix*>( ptr ) );
2622}
2623//*************************************************************************************************
2624
2625
2626//*************************************************************************************************
2632template< typename Type // Data type of the matrix
2633 , size_t M // Number of rows
2634 , size_t N // Number of columns
2635 , bool SO // Storage order
2636 , AlignmentFlag AF // Alignment flag
2637 , PaddingFlag PF // Padding flag
2638 , typename Tag > // Type tag
2639inline void HybridMatrix<Type,M,N,SO,AF,PF,Tag>::operator delete[]( void* ptr, const std::nothrow_t& )
2640{
2641 deallocate( static_cast<HybridMatrix*>( ptr ) );
2642}
2643//*************************************************************************************************
2644
2645
2646
2647
2648//=================================================================================================
2649//
2650// DEBUGGING FUNCTIONS
2651//
2652//=================================================================================================
2653
2654//*************************************************************************************************
2663template< typename Type // Data type of the matrix
2664 , size_t M // Number of rows
2665 , size_t N // Number of columns
2666 , bool SO // Storage order
2667 , AlignmentFlag AF // Alignment flag
2668 , PaddingFlag PF // Padding flag
2669 , typename Tag > // Type tag
2671{
2672 if( m_ > M || n_ > N )
2673 return false;
2674
2675 if( IsVectorizable_v<Type> )
2676 {
2677 for( size_t i=0UL; i<m_; ++i ) {
2678 for( size_t j=n_; j<NN; ++j ) {
2679 if( !isDefault<strict>( v_[i*NN+j] ) )
2680 return false;
2681 }
2682 }
2683
2684 for( size_t i=m_; i<M; ++i ) {
2685 for( size_t j=0UL; j<NN; ++j ) {
2686 if( !isDefault<strict>( v_[i*NN+j] ) )
2687 return false;
2688 }
2689 }
2690 }
2691
2692 return true;
2693}
2694//*************************************************************************************************
2695
2696
2697
2698
2699//=================================================================================================
2700//
2701// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2702//
2703//=================================================================================================
2704
2705//*************************************************************************************************
2715template< typename Type // Data type of the matrix
2716 , size_t M // Number of rows
2717 , size_t N // Number of columns
2718 , bool SO // Storage order
2719 , AlignmentFlag AF // Alignment flag
2720 , PaddingFlag PF // Padding flag
2721 , typename Tag > // Type tag
2722template< typename Other > // Data type of the foreign expression
2723inline bool HybridMatrix<Type,M,N,SO,AF,PF,Tag>::canAlias( const Other* alias ) const noexcept
2724{
2725 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2726}
2727//*************************************************************************************************
2728
2729
2730//*************************************************************************************************
2740template< typename Type // Data type of the matrix
2741 , size_t M // Number of rows
2742 , size_t N // Number of columns
2743 , bool SO // Storage order
2744 , AlignmentFlag AF // Alignment flag
2745 , PaddingFlag PF // Padding flag
2746 , typename Tag > // Type tag
2747template< typename Other > // Data type of the foreign expression
2748inline bool HybridMatrix<Type,M,N,SO,AF,PF,Tag>::isAliased( const Other* alias ) const noexcept
2749{
2750 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2751}
2752//*************************************************************************************************
2753
2754
2755//*************************************************************************************************
2764template< typename Type // Data type of the matrix
2765 , size_t M // Number of rows
2766 , size_t N // Number of columns
2767 , bool SO // Storage order
2768 , AlignmentFlag AF // Alignment flag
2769 , PaddingFlag PF // Padding flag
2770 , typename Tag > // Type tag
2772{
2773 return AF == aligned;
2774}
2775//*************************************************************************************************
2776
2777
2778//*************************************************************************************************
2793template< typename Type // Data type of the matrix
2794 , size_t M // Number of rows
2795 , size_t N // Number of columns
2796 , bool SO // Storage order
2797 , AlignmentFlag AF // Alignment flag
2798 , PaddingFlag PF // Padding flag
2799 , typename Tag > // Type tag
2801 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::load( size_t i, size_t j ) const noexcept
2802{
2803 if( AF == aligned )
2804 return loada( i, j );
2805 else
2806 return loadu( i, j );
2807}
2808//*************************************************************************************************
2809
2810
2811//*************************************************************************************************
2826template< typename Type // Data type of the matrix
2827 , size_t M // Number of rows
2828 , size_t N // Number of columns
2829 , bool SO // Storage order
2830 , AlignmentFlag AF // Alignment flag
2831 , PaddingFlag PF // Padding flag
2832 , typename Tag > // Type tag
2834 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::loada( size_t i, size_t j ) const noexcept
2835{
2836 using blaze::loada;
2837
2839
2840 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2841 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2842 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2843 BLAZE_INTERNAL_ASSERT( PF == unpadded || j % SIMDSIZE == 0UL, "Invalid column access index" );
2844 BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2845
2846 return loada( &v_[i*NN+j] );
2847}
2848//*************************************************************************************************
2849
2850
2851//*************************************************************************************************
2866template< typename Type // Data type of the matrix
2867 , size_t M // Number of rows
2868 , size_t N // Number of columns
2869 , bool SO // Storage order
2870 , AlignmentFlag AF // Alignment flag
2871 , PaddingFlag PF // Padding flag
2872 , typename Tag > // Type tag
2874 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::loadu( size_t i, size_t j ) const noexcept
2875{
2876 using blaze::loadu;
2877
2879
2880 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2881 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2882 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2883
2884 return loadu( &v_[i*NN+j] );
2885}
2886//*************************************************************************************************
2887
2888
2889//*************************************************************************************************
2905template< typename Type // Data type of the matrix
2906 , size_t M // Number of rows
2907 , size_t N // Number of columns
2908 , bool SO // Storage order
2909 , AlignmentFlag AF // Alignment flag
2910 , PaddingFlag PF // Padding flag
2911 , typename Tag > // Type tag
2913 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2914{
2915 if( AF == aligned )
2916 storea( i, j, value );
2917 else
2918 storeu( i, j, value );
2919}
2920//*************************************************************************************************
2921
2922
2923//*************************************************************************************************
2939template< typename Type // Data type of the matrix
2940 , size_t M // Number of rows
2941 , size_t N // Number of columns
2942 , bool SO // Storage order
2943 , AlignmentFlag AF // Alignment flag
2944 , PaddingFlag PF // Padding flag
2945 , typename Tag > // Type tag
2947 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2948{
2949 using blaze::storea;
2950
2952
2953 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2954 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2955 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2956 BLAZE_INTERNAL_ASSERT( PF == unpadded || j % SIMDSIZE == 0UL, "Invalid column access index" );
2957 BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2958
2959 storea( &v_[i*NN+j], value );
2960}
2961//*************************************************************************************************
2962
2963
2964//*************************************************************************************************
2980template< typename Type // Data type of the matrix
2981 , size_t M // Number of rows
2982 , size_t N // Number of columns
2983 , bool SO // Storage order
2984 , AlignmentFlag AF // Alignment flag
2985 , PaddingFlag PF // Padding flag
2986 , typename Tag > // Type tag
2988 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2989{
2990 using blaze::storeu;
2991
2993
2994 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2995 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2996 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2997
2998 storeu( &v_[i*NN+j], value );
2999}
3000//*************************************************************************************************
3001
3002
3003//*************************************************************************************************
3020template< typename Type // Data type of the matrix
3021 , size_t M // Number of rows
3022 , size_t N // Number of columns
3023 , bool SO // Storage order
3024 , AlignmentFlag AF // Alignment flag
3025 , PaddingFlag PF // Padding flag
3026 , typename Tag > // Type tag
3028 HybridMatrix<Type,M,N,SO,AF,PF,Tag>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
3029{
3030 using blaze::stream;
3031
3033
3034 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
3035 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
3036 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
3037 BLAZE_INTERNAL_ASSERT( PF == unpadded || j % SIMDSIZE == 0UL, "Invalid column access index" );
3038 BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
3039
3040 stream( &v_[i*NN+j], value );
3041}
3042//*************************************************************************************************
3043
3044
3045//*************************************************************************************************
3056template< typename Type // Data type of the matrix
3057 , size_t M // Number of rows
3058 , size_t N // Number of columns
3059 , bool SO // Storage order
3060 , AlignmentFlag AF // Alignment flag
3061 , PaddingFlag PF // Padding flag
3062 , typename Tag > // Type tag
3063template< typename MT // Type of the right-hand side dense matrix
3064 , bool SO2 > // Storage order of the right-hand side dense matrix
3067{
3068 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3069
3070 for( size_t i=0UL; i<m_; ++i ) {
3071 for( size_t j=0UL; j<n_; ++j ) {
3072 v_[i*NN+j] = (*rhs)(i,j);
3073 }
3074 }
3075}
3076//*************************************************************************************************
3077
3078
3079//*************************************************************************************************
3090template< typename Type // Data type of the matrix
3091 , size_t M // Number of rows
3092 , size_t N // Number of columns
3093 , bool SO // Storage order
3094 , AlignmentFlag AF // Alignment flag
3095 , PaddingFlag PF // Padding flag
3096 , typename Tag > // Type tag
3097template< typename MT // Type of the right-hand side dense matrix
3098 , bool SO2 > // Storage order of the right-hand side dense matrix
3101{
3103
3104 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3105
3106 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
3107
3108 const size_t jpos( remainder ? prevMultiple( n_, SIMDSIZE ) : n_ );
3109 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
3110
3111 for( size_t i=0UL; i<m_; ++i )
3112 {
3113 size_t j( 0UL );
3114
3115 for( ; j<jpos; j+=SIMDSIZE ) {
3116 store( i, j, (*rhs).load(i,j) );
3117 }
3118 for( ; remainder && j<n_; ++j ) {
3119 v_[i*NN+j] = (*rhs)(i,j);
3120 }
3121 }
3122}
3123//*************************************************************************************************
3124
3125
3126//*************************************************************************************************
3137template< typename Type // Data type of the matrix
3138 , size_t M // Number of rows
3139 , size_t N // Number of columns
3140 , bool SO // Storage order
3141 , AlignmentFlag AF // Alignment flag
3142 , PaddingFlag PF // Padding flag
3143 , typename Tag > // Type tag
3144template< typename MT > // Type of the right-hand side sparse matrix
3146{
3147 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3148
3149 for( size_t i=0UL; i<m_; ++i )
3150 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3151 v_[i*NN+element->index()] = element->value();
3152}
3153//*************************************************************************************************
3154
3155
3156//*************************************************************************************************
3167template< typename Type // Data type of the matrix
3168 , size_t M // Number of rows
3169 , size_t N // Number of columns
3170 , bool SO // Storage order
3171 , AlignmentFlag AF // Alignment flag
3172 , PaddingFlag PF // Padding flag
3173 , typename Tag > // Type tag
3174template< typename MT > // Type of the right-hand side sparse matrix
3176{
3178
3179 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3180
3181 for( size_t j=0UL; j<n_; ++j )
3182 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3183 v_[element->index()*NN+j] = element->value();
3184}
3185//*************************************************************************************************
3186
3187
3188//*************************************************************************************************
3199template< typename Type // Data type of the matrix
3200 , size_t M // Number of rows
3201 , size_t N // Number of columns
3202 , bool SO // Storage order
3203 , AlignmentFlag AF // Alignment flag
3204 , PaddingFlag PF // Padding flag
3205 , typename Tag > // Type tag
3206template< typename MT // Type of the right-hand side dense matrix
3207 , bool SO2 > // Storage order of the right-hand side dense matrix
3210{
3211 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3212
3213 for( size_t i=0UL; i<m_; ++i )
3214 {
3215 if( IsDiagonal_v<MT> )
3216 {
3217 v_[i*NN+i] += (*rhs)(i,i);
3218 }
3219 else
3220 {
3221 const size_t jbegin( ( IsUpper_v<MT> )
3222 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
3223 :( 0UL ) );
3224 const size_t jend ( ( IsLower_v<MT> )
3225 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3226 :( n_ ) );
3227 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3228
3229 for( size_t j=jbegin; j<jend; ++j ) {
3230 v_[i*NN+j] += (*rhs)(i,j);
3231 }
3232 }
3233 }
3234}
3235//*************************************************************************************************
3236
3237
3238//*************************************************************************************************
3249template< typename Type // Data type of the matrix
3250 , size_t M // Number of rows
3251 , size_t N // Number of columns
3252 , bool SO // Storage order
3253 , AlignmentFlag AF // Alignment flag
3254 , PaddingFlag PF // Padding flag
3255 , typename Tag > // Type tag
3256template< typename MT // Type of the right-hand side dense matrix
3257 , bool SO2 > // Storage order of the right-hand side dense matrix
3260{
3263
3264 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3265
3266 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
3267
3268 for( size_t i=0UL; i<m_; ++i )
3269 {
3270 const size_t jbegin( ( IsUpper_v<MT> )
3271 ?( prevMultiple( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), SIMDSIZE ) )
3272 :( 0UL ) );
3273 const size_t jend ( ( IsLower_v<MT> )
3274 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3275 :( n_ ) );
3276 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3277
3278 const size_t jpos( remainder ? prevMultiple( jend, SIMDSIZE ) : jend );
3279 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
3280
3281 size_t j( jbegin );
3282
3283 for( ; j<jpos; j+=SIMDSIZE ) {
3284 store( i, j, load(i,j) + (*rhs).load(i,j) );
3285 }
3286 for( ; remainder && j<jend; ++j ) {
3287 v_[i*NN+j] += (*rhs)(i,j);
3288 }
3289 }
3290}
3291//*************************************************************************************************
3292
3293
3294//*************************************************************************************************
3305template< typename Type // Data type of the matrix
3306 , size_t M // Number of rows
3307 , size_t N // Number of columns
3308 , bool SO // Storage order
3309 , AlignmentFlag AF // Alignment flag
3310 , PaddingFlag PF // Padding flag
3311 , typename Tag > // Type tag
3312template< typename MT > // Type of the right-hand side sparse matrix
3314{
3315 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3316
3317 for( size_t i=0UL; i<m_; ++i )
3318 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3319 v_[i*NN+element->index()] += element->value();
3320}
3321//*************************************************************************************************
3322
3323
3324//*************************************************************************************************
3335template< typename Type // Data type of the matrix
3336 , size_t M // Number of rows
3337 , size_t N // Number of columns
3338 , bool SO // Storage order
3339 , AlignmentFlag AF // Alignment flag
3340 , PaddingFlag PF // Padding flag
3341 , typename Tag > // Type tag
3342template< typename MT > // Type of the right-hand side sparse matrix
3344{
3346
3347 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3348
3349 for( size_t j=0UL; j<n_; ++j )
3350 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3351 v_[element->index()*NN+j] += element->value();
3352}
3353//*************************************************************************************************
3354
3355
3356//*************************************************************************************************
3367template< typename Type // Data type of the matrix
3368 , size_t M // Number of rows
3369 , size_t N // Number of columns
3370 , bool SO // Storage order
3371 , AlignmentFlag AF // Alignment flag
3372 , PaddingFlag PF // Padding flag
3373 , typename Tag > // Type tag
3374template< typename MT // Type of the right-hand side dense matrix
3375 , bool SO2 > // Storage order of the right-hand side dense matrix
3378{
3379 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3380
3381 for( size_t i=0UL; i<m_; ++i )
3382 {
3383 if( IsDiagonal_v<MT> )
3384 {
3385 v_[i*NN+i] -= (*rhs)(i,i);
3386 }
3387 else
3388 {
3389 const size_t jbegin( ( IsUpper_v<MT> )
3390 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
3391 :( 0UL ) );
3392 const size_t jend ( ( IsLower_v<MT> )
3393 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3394 :( n_ ) );
3395 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3396
3397 for( size_t j=jbegin; j<jend; ++j ) {
3398 v_[i*NN+j] -= (*rhs)(i,j);
3399 }
3400 }
3401 }
3402}
3403//*************************************************************************************************
3404
3405
3406//*************************************************************************************************
3417template< typename Type // Data type of the matrix
3418 , size_t M // Number of rows
3419 , size_t N // Number of columns
3420 , bool SO // Storage order
3421 , AlignmentFlag AF // Alignment flag
3422 , PaddingFlag PF // Padding flag
3423 , typename Tag > // Type tag
3424template< typename MT // Type of the right-hand side dense matrix
3425 , bool SO2 > // Storage order of the right-hand side dense matrix
3428{
3431
3432 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3433
3434 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
3435
3436 for( size_t i=0UL; i<m_; ++i )
3437 {
3438 const size_t jbegin( ( IsUpper_v<MT> )
3439 ?( prevMultiple( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), SIMDSIZE ) )
3440 :( 0UL ) );
3441 const size_t jend ( ( IsLower_v<MT> )
3442 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3443 :( n_ ) );
3444 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3445
3446 const size_t jpos( remainder ? prevMultiple( jend, SIMDSIZE ) : jend );
3447 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
3448
3449 size_t j( jbegin );
3450
3451 for( ; j<jpos; j+=SIMDSIZE ) {
3452 store( i, j, load(i,j) - (*rhs).load(i,j) );
3453 }
3454 for( ; remainder && j<jend; ++j ) {
3455 v_[i*NN+j] -= (*rhs)(i,j);
3456 }
3457 }
3458}
3459//*************************************************************************************************
3460
3461
3462//*************************************************************************************************
3473template< typename Type // Data type of the matrix
3474 , size_t M // Number of rows
3475 , size_t N // Number of columns
3476 , bool SO // Storage order
3477 , AlignmentFlag AF // Alignment flag
3478 , PaddingFlag PF // Padding flag
3479 , typename Tag > // Type tag
3480template< typename MT > // Type of the right-hand side sparse matrix
3482{
3483 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3484
3485 for( size_t i=0UL; i<m_; ++i )
3486 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3487 v_[i*NN+element->index()] -= element->value();
3488}
3489//*************************************************************************************************
3490
3491
3492//*************************************************************************************************
3503template< typename Type // Data type of the matrix
3504 , size_t M // Number of rows
3505 , size_t N // Number of columns
3506 , bool SO // Storage order
3507 , AlignmentFlag AF // Alignment flag
3508 , PaddingFlag PF // Padding flag
3509 , typename Tag > // Type tag
3510template< typename MT > // Type of the right-hand side sparse matrix
3512{
3514
3515 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3516
3517 for( size_t j=0UL; j<n_; ++j )
3518 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3519 v_[element->index()*NN+j] -= element->value();
3520}
3521//*************************************************************************************************
3522
3523
3524//*************************************************************************************************
3535template< typename Type // Data type of the matrix
3536 , size_t M // Number of rows
3537 , size_t N // Number of columns
3538 , bool SO // Storage order
3539 , AlignmentFlag AF // Alignment flag
3540 , PaddingFlag PF // Padding flag
3541 , typename Tag > // Type tag
3542template< typename MT // Type of the right-hand side dense matrix
3543 , bool SO2 > // Storage order of the right-hand side dense matrix
3546{
3547 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3548
3549 for( size_t i=0UL; i<m_; ++i ) {
3550 for( size_t j=0UL; j<n_; ++j ) {
3551 v_[i*NN+j] *= (*rhs)(i,j);
3552 }
3553 }
3554}
3555//*************************************************************************************************
3556
3557
3558//*************************************************************************************************
3569template< typename Type // Data type of the matrix
3570 , size_t M // Number of rows
3571 , size_t N // Number of columns
3572 , bool SO // Storage order
3573 , AlignmentFlag AF // Alignment flag
3574 , PaddingFlag PF // Padding flag
3575 , typename Tag > // Type tag
3576template< typename MT // Type of the right-hand side dense matrix
3577 , bool SO2 > // Storage order of the right-hand side dense matrix
3580{
3582
3583 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3584
3585 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
3586
3587 for( size_t i=0UL; i<m_; ++i )
3588 {
3589 const size_t jpos( remainder ? prevMultiple( n_, SIMDSIZE ) : n_ );
3590 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
3591
3592 size_t j( 0UL );
3593
3594 for( ; j<jpos; j+=SIMDSIZE ) {
3595 store( i, j, load(i,j) * (*rhs).load(i,j) );
3596 }
3597 for( ; remainder && j<n_; ++j ) {
3598 v_[i*NN+j] *= (*rhs)(i,j);
3599 }
3600 }
3601}
3602//*************************************************************************************************
3603
3604
3605//*************************************************************************************************
3616template< typename Type // Data type of the matrix
3617 , size_t M // Number of rows
3618 , size_t N // Number of columns
3619 , bool SO // Storage order
3620 , AlignmentFlag AF // Alignment flag
3621 , PaddingFlag PF // Padding flag
3622 , typename Tag > // Type tag
3623template< typename MT > // Type of the right-hand side sparse matrix
3625{
3626 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3627
3628 const HybridMatrix tmp( serial( *this ) );
3629
3630 reset();
3631
3632 for( size_t i=0UL; i<m_; ++i )
3633 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3634 v_[i*NN+element->index()] = tmp.v_[i*NN+element->index()] * element->value();
3635}
3636//*************************************************************************************************
3637
3638
3639//*************************************************************************************************
3650template< typename Type // Data type of the matrix
3651 , size_t M // Number of rows
3652 , size_t N // Number of columns
3653 , bool SO // Storage order
3654 , AlignmentFlag AF // Alignment flag
3655 , PaddingFlag PF // Padding flag
3656 , typename Tag > // Type tag
3657template< typename MT > // Type of the right-hand side sparse matrix
3659{
3661
3662 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
3663
3664 const HybridMatrix tmp( serial( *this ) );
3665
3666 reset();
3667
3668 for( size_t j=0UL; j<n_; ++j )
3669 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3670 v_[element->index()*NN+j] = tmp.v_[element->index()*NN+j] * element->value();
3671}
3672//*************************************************************************************************
3673
3674
3675
3676
3677
3678
3679
3680
3681//=================================================================================================
3682//
3683// CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3684//
3685//=================================================================================================
3686
3687//*************************************************************************************************
3695template< typename Type // Data type of the matrix
3696 , size_t M // Number of rows
3697 , size_t N // Number of columns
3698 , AlignmentFlag AF // Alignment flag
3699 , PaddingFlag PF // Padding flag
3700 , typename Tag > // Type tag
3701class HybridMatrix<Type,M,N,true,AF,PF,Tag>
3702 : public DenseMatrix< HybridMatrix<Type,M,N,true,AF,PF,Tag>, true >
3703{
3704 public:
3705 //**Type definitions****************************************************************************
3708
3710 using ResultType = This;
3711
3714
3717
3718 using ElementType = Type;
3720 using TagType = Tag;
3721 using ReturnType = const Type&;
3722 using CompositeType = const This&;
3723
3724 using Reference = Type&;
3725 using ConstReference = const Type&;
3726 using Pointer = Type*;
3727 using ConstPointer = const Type*;
3728
3731 //**********************************************************************************************
3732
3733 //**Rebind struct definition********************************************************************
3736 template< typename NewType > // Data type of the other matrix
3737 struct Rebind {
3739 };
3740 //**********************************************************************************************
3741
3742 //**Resize struct definition********************************************************************
3745 template< size_t NewM // Number of rows of the other matrix
3746 , size_t NewN > // Number of columns of the other matrix
3747 struct Resize {
3748 using Other = HybridMatrix<Type,NewM,NewN,true,AF,PF,Tag>;
3749 };
3750 //**********************************************************************************************
3751
3752 //**Compilation flags***************************************************************************
3754
3758 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
3759
3761
3764 static constexpr bool smpAssignable = false;
3765 //**********************************************************************************************
3766
3767 //**Constructors********************************************************************************
3770 constexpr HybridMatrix();
3771 constexpr HybridMatrix( size_t m, size_t n );
3772 inline HybridMatrix( size_t m, size_t n, const Type& init );
3774
3775 template< typename Other >
3776 inline HybridMatrix( size_t m, size_t n, const Other* array );
3777
3778 template< typename Other, size_t Rows, size_t Cols >
3779 inline HybridMatrix( const Other (&array)[Rows][Cols] );
3780
3781 template< typename Other, size_t Rows, size_t Cols >
3782 inline HybridMatrix( const std::array<std::array<Other,Cols>,Rows>& array );
3783
3784 constexpr HybridMatrix( const HybridMatrix& m );
3785
3786 template< typename MT, bool SO >
3787 inline HybridMatrix( const Matrix<MT,SO>& m );
3789 //**********************************************************************************************
3790
3791 //**Destructor**********************************************************************************
3794 ~HybridMatrix() = default;
3796 //**********************************************************************************************
3797
3798 //**Data access functions***********************************************************************
3801 constexpr Reference operator()( size_t i, size_t j ) noexcept;
3802 constexpr ConstReference operator()( size_t i, size_t j ) const noexcept;
3803 inline Reference at( size_t i, size_t j );
3804 inline ConstReference at( size_t i, size_t j ) const;
3805 constexpr Pointer data () noexcept;
3806 constexpr ConstPointer data () const noexcept;
3807 constexpr Pointer data ( size_t j ) noexcept;
3808 constexpr ConstPointer data ( size_t j ) const noexcept;
3809 constexpr Iterator begin ( size_t j ) noexcept;
3810 constexpr ConstIterator begin ( size_t j ) const noexcept;
3811 constexpr ConstIterator cbegin( size_t j ) const noexcept;
3812 constexpr Iterator end ( size_t j ) noexcept;
3813 constexpr ConstIterator end ( size_t j ) const noexcept;
3814 constexpr ConstIterator cend ( size_t j ) const noexcept;
3816 //**********************************************************************************************
3817
3818 //**Assignment operators************************************************************************
3821 constexpr HybridMatrix& operator=( const Type& set ) &;
3822 constexpr HybridMatrix& operator=( initializer_list< initializer_list<Type> > list ) &;
3823
3824 template< typename Other, size_t Rows, size_t Cols >
3825 constexpr HybridMatrix& operator=( const Other (&array)[Rows][Cols] ) &;
3826
3827 template< typename Other, size_t Rows, size_t Cols >
3828 constexpr HybridMatrix& operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &;
3829
3830 constexpr HybridMatrix& operator=( const HybridMatrix& rhs ) &;
3831
3832 template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs ) &;
3833 template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs ) &;
3834 template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs ) &;
3835 template< typename MT, bool SO > inline HybridMatrix& operator%=( const Matrix<MT,SO>& rhs ) &;
3837 //**********************************************************************************************
3838
3839 //**Utility functions***************************************************************************
3842 constexpr size_t rows() const noexcept;
3843 constexpr size_t columns() const noexcept;
3844 static constexpr size_t spacing() noexcept;
3845 static constexpr size_t capacity() noexcept;
3846 constexpr size_t capacity( size_t j ) const noexcept;
3847 inline size_t nonZeros() const;
3848 inline size_t nonZeros( size_t j ) const;
3849 constexpr void reset();
3850 constexpr void reset( size_t i );
3851 constexpr void clear();
3852 constexpr void resize ( size_t m, size_t n, bool preserve=true );
3853 constexpr void extend ( size_t m, size_t n, bool preserve=true );
3854 inline void swap( HybridMatrix& m ) noexcept;
3856 //**********************************************************************************************
3857
3858 //**Numeric functions***************************************************************************
3861 inline HybridMatrix& transpose();
3862 inline HybridMatrix& ctranspose();
3863
3864 template< typename Other > inline HybridMatrix& scale( const Other& scalar );
3866 //**********************************************************************************************
3867
3868 //**Memory functions****************************************************************************
3871 static inline void* operator new ( std::size_t size );
3872 static inline void* operator new[]( std::size_t size );
3873 static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3874 static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3875
3876 static inline void operator delete ( void* ptr );
3877 static inline void operator delete[]( void* ptr );
3878 static inline void operator delete ( void* ptr, const std::nothrow_t& );
3879 static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3881 //**********************************************************************************************
3882
3883 private:
3884 //**********************************************************************************************
3886 static constexpr size_t SIMDSIZE = SIMDTrait<Type>::size;
3887
3889 static constexpr size_t MM = ( PF == padded ? nextMultiple( M, SIMDSIZE ) : M );
3890 //**********************************************************************************************
3891
3892 //**********************************************************************************************
3894 template< typename MT >
3895 static constexpr bool VectorizedAssign_v =
3896 ( useOptimizedKernels &&
3897 MM >= SIMDSIZE &&
3898 simdEnabled && MT::simdEnabled &&
3899 IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3901 //**********************************************************************************************
3902
3903 //**********************************************************************************************
3905 template< typename MT >
3906 static constexpr bool VectorizedAddAssign_v =
3907 ( VectorizedAssign_v<MT> &&
3908 HasSIMDAdd_v< Type, ElementType_t<MT> > &&
3909 !IsDiagonal_v<MT> );
3910 //**********************************************************************************************
3911
3912 //**********************************************************************************************
3914 template< typename MT >
3915 static constexpr bool VectorizedSubAssign_v =
3916 ( VectorizedAssign_v<MT> &&
3917 HasSIMDSub_v< Type, ElementType_t<MT> > &&
3918 !IsDiagonal_v<MT> );
3919 //**********************************************************************************************
3920
3921 //**********************************************************************************************
3923 template< typename MT >
3924 static constexpr bool VectorizedSchurAssign_v =
3925 ( VectorizedAssign_v<MT> &&
3926 HasSIMDMult_v< Type, ElementType_t<MT> > );
3927 //**********************************************************************************************
3928
3929 public:
3930 //**Debugging functions*************************************************************************
3933 constexpr bool isIntact() const noexcept;
3935 //**********************************************************************************************
3936
3937 //**Expression template evaluation functions****************************************************
3940 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3941 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3942
3943 static constexpr bool isAligned() noexcept;
3944
3945 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3946 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3947 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3948
3949 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3950 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3951 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3952 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3953
3954 template< typename MT, bool SO >
3955 inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
3956
3957 template< typename MT, bool SO >
3958 inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
3959
3960 template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3961 template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3962
3963 template< typename MT, bool SO >
3964 inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
3965
3966 template< typename MT, bool SO >
3967 inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
3968
3969 template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3970 template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3971
3972 template< typename MT, bool SO >
3973 inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
3974
3975 template< typename MT, bool SO >
3976 inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
3977
3978 template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3979 template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3980
3981 template< typename MT, bool SO >
3982 inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
3983
3984 template< typename MT, bool SO >
3985 inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
3986
3987 template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3988 template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3990 //**********************************************************************************************
3991
3992 private:
3993 //**********************************************************************************************
3995 static constexpr size_t Alignment =
3996 ( AF == aligned ? AlignmentOf_v<Type> : std::alignment_of<Type>::value );
3997
3999 using AlignedStorage = AlignedArray<Type,MM*N,Alignment>;
4000 //**********************************************************************************************
4001
4002 //**Member variables****************************************************************************
4007 size_t m_;
4008 size_t n_;
4010 //**********************************************************************************************
4011
4012 //**Compile time checks*************************************************************************
4017 BLAZE_STATIC_ASSERT( AF == unaligned || PF == padded || M % SIMDSIZE == 0UL );
4018 BLAZE_STATIC_ASSERT( PF == unpadded || MM % SIMDSIZE == 0UL );
4019 BLAZE_STATIC_ASSERT( MM >= M );
4020 BLAZE_STATIC_ASSERT( IsVectorizable_v<Type> || MM == M );
4021 //**********************************************************************************************
4022};
4024//*************************************************************************************************
4025
4026
4027
4028
4029//=================================================================================================
4030//
4031// CONSTRUCTORS
4032//
4033//=================================================================================================
4034
4035//*************************************************************************************************
4041template< typename Type // Data type of the matrix
4042 , size_t M // Number of rows
4043 , size_t N // Number of columns
4044 , AlignmentFlag AF // Alignment flag
4045 , PaddingFlag PF // Padding flag
4046 , typename Tag > // Type tag
4047constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix()
4048 : v_() // The statically allocated matrix elements
4049 , m_( 0UL ) // The current number of rows of the matrix
4050 , n_( 0UL ) // The current number of columns of the matrix
4051{
4052 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4053}
4055//*************************************************************************************************
4056
4057
4058//*************************************************************************************************
4072template< typename Type // Data type of the matrix
4073 , size_t M // Number of rows
4074 , size_t N // Number of columns
4075 , AlignmentFlag AF // Alignment flag
4076 , PaddingFlag PF // Padding flag
4077 , typename Tag > // Type tag
4078constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( size_t m, size_t n )
4079 : v_() // The statically allocated matrix elements
4080 , m_( m ) // The current number of rows of the matrix
4081 , n_( n ) // The current number of columns of the matrix
4082{
4083 if( m > M ) {
4084 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4085 }
4086
4087 if( n > N ) {
4088 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4089 }
4090
4091 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4092}
4094//*************************************************************************************************
4095
4096
4097//*************************************************************************************************
4112template< typename Type // Data type of the matrix
4113 , size_t M // Number of rows
4114 , size_t N // Number of columns
4115 , AlignmentFlag AF // Alignment flag
4116 , PaddingFlag PF // Padding flag
4117 , typename Tag > // Type tag
4118inline HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( size_t m, size_t n, const Type& init )
4119 : m_( m ) // The current number of rows of the matrix
4120 , n_( n ) // The current number of columns of the matrix
4121 // v_ is intentionally left uninitialized
4122{
4123 using blaze::clear;
4124
4125 if( m > M ) {
4126 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4127 }
4128
4129 if( n > N ) {
4130 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4131 }
4132
4133 for( size_t j=0UL; j<n; ++j ) {
4134 for( size_t i=0UL; i<m; ++i )
4135 v_[i+j*MM] = init;
4136
4137 if( IsNumeric_v<Type> ) {
4138 for( size_t i=m; i<MM; ++i )
4139 clear( v_[i+j*MM] );
4140 }
4141 }
4142
4143 if( IsNumeric_v<Type> ) {
4144 for( size_t j=n; j<N; ++j )
4145 for( size_t i=0UL; i<MM; ++i )
4146 clear( v_[i+j*MM] );
4147 }
4148
4149 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4150}
4152//*************************************************************************************************
4153
4154
4155//*************************************************************************************************
4180template< typename Type // Data type of the matrix
4181 , size_t M // Number of rows
4182 , size_t N // Number of columns
4183 , AlignmentFlag AF // Alignment flag
4184 , PaddingFlag PF // Padding flag
4185 , typename Tag > // Type tag
4187 : v_() // The statically allocated matrix elements
4188 , m_( list.size() ) // The current number of rows of the matrix
4189 , n_( determineColumns( list ) ) // The current number of columns of the matrix
4190{
4191 if( m_ > M ) {
4192 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4193 }
4194
4195 if( n_ > N ) {
4196 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4197 }
4198
4199 size_t i( 0UL );
4200
4201 for( const auto& rowList : list ) {
4202 size_t j( 0UL );
4203 for( const auto& element : rowList ) {
4204 v_[i+j*MM] = element;
4205 ++j;
4206 }
4207 ++i;
4208 }
4209
4210 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4211}
4213//*************************************************************************************************
4214
4215
4216//*************************************************************************************************
4244template< typename Type // Data type of the matrix
4245 , size_t M // Number of rows
4246 , size_t N // Number of columns
4247 , AlignmentFlag AF // Alignment flag
4248 , PaddingFlag PF // Padding flag
4249 , typename Tag > // Type tag
4250template< typename Other > // Data type of the initialization array
4251inline HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( size_t m, size_t n, const Other* array )
4252 : m_( m ) // The current number of rows of the matrix
4253 , n_( n ) // The current number of columns of the matrix
4254 // v_ is intentionally left uninitialized
4255{
4256 using blaze::clear;
4257
4258 if( m > M ) {
4259 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4260 }
4261
4262 if( n > N ) {
4263 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4264 }
4265
4266 for( size_t j=0UL; j<n; ++j ) {
4267 for( size_t i=0UL; i<m; ++i )
4268 v_[i+j*MM] = array[i+j*m];
4269
4270 if( IsNumeric_v<Type> ) {
4271 for( size_t i=m; i<MM; ++i )
4272 clear( v_[i+j*MM] );
4273 }
4274 }
4275
4276 if( IsNumeric_v<Type> ) {
4277 for( size_t j=n; j<N; ++j )
4278 for( size_t i=0UL; i<MM; ++i )
4279 clear( v_[i+j*MM] );
4280 }
4281
4282 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4283}
4285//*************************************************************************************************
4286
4287
4288//*************************************************************************************************
4310template< typename Type // Data type of the matrix
4311 , size_t M // Number of rows
4312 , size_t N // Number of columns
4313 , AlignmentFlag AF // Alignment flag
4314 , PaddingFlag PF // Padding flag
4315 , typename Tag > // Type tag
4316template< typename Other // Data type of the static array
4317 , size_t Rows // Number of rows of the static array
4318 , size_t Cols > // Number of columns of the static array
4319inline HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( const Other (&array)[Rows][Cols] )
4320 : m_( Rows ) // The current number of rows of the matrix
4321 , n_( Cols ) // The current number of columns of the matrix
4322 // v_ is intentionally left uninitialized
4323{
4324 using blaze::clear;
4325
4326 BLAZE_STATIC_ASSERT( Rows <= M );
4327 BLAZE_STATIC_ASSERT( Cols <= N );
4328
4329 for( size_t j=0UL; j<Cols; ++j ) {
4330 for( size_t i=0UL; i<Rows; ++i )
4331 v_[i+j*MM] = array[i][j];
4332
4333 if( IsNumeric_v<Type> ) {
4334 for( size_t i=Rows; i<MM; ++i )
4335 clear( v_[i+j*MM] );
4336 }
4337 }
4338
4339 if( IsNumeric_v<Type> ) {
4340 for( size_t j=Cols; j<N; ++j )
4341 for( size_t i=0UL; i<MM; ++i )
4342 clear( v_[i+j*MM] );
4343 }
4344
4345 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4346}
4348//*************************************************************************************************
4349
4350
4351//*************************************************************************************************
4373template< typename Type // Data type of the matrix
4374 , size_t M // Number of rows
4375 , size_t N // Number of columns
4376 , AlignmentFlag AF // Alignment flag
4377 , PaddingFlag PF // Padding flag
4378 , typename Tag > // Type tag
4379template< typename Other // Data type of the static array
4380 , size_t Rows // Number of rows of the static array
4381 , size_t Cols > // Number of columns of the static array
4382inline HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( const std::array<std::array<Other,Cols>,Rows>& array )
4383 : m_( Rows ) // The current number of rows of the matrix
4384 , n_( Cols ) // The current number of columns of the matrix
4385 // v_ is intentionally left uninitialized
4386{
4387 using blaze::clear;
4388
4389 BLAZE_STATIC_ASSERT( Rows <= M );
4390 BLAZE_STATIC_ASSERT( Cols <= N );
4391
4392 for( size_t j=0UL; j<Cols; ++j ) {
4393 for( size_t i=0UL; i<Rows; ++i )
4394 v_[i+j*MM] = array[i][j];
4395
4396 if( IsNumeric_v<Type> ) {
4397 for( size_t i=Rows; i<MM; ++i )
4398 clear( v_[i+j*MM] );
4399 }
4400 }
4401
4402 if( IsNumeric_v<Type> ) {
4403 for( size_t j=Cols; j<N; ++j )
4404 for( size_t i=0UL; i<MM; ++i )
4405 clear( v_[i+j*MM] );
4406 }
4407
4408 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4409}
4411//*************************************************************************************************
4412
4413
4414//*************************************************************************************************
4423template< typename Type // Data type of the matrix
4424 , size_t M // Number of rows
4425 , size_t N // Number of columns
4426 , AlignmentFlag AF // Alignment flag
4427 , PaddingFlag PF // Padding flag
4428 , typename Tag > // Type tag
4429constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( const HybridMatrix& m )
4430 : BaseType() // Initialization of the base class
4431 , v_( m.v_ ) // The statically allocated matrix elements
4432 , m_( m.m_ ) // The current number of rows of the matrix
4433 , n_( m.n_ ) // The current number of columns of the matrix
4434{
4435 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4436}
4438//*************************************************************************************************
4439
4440
4441//*************************************************************************************************
4448template< typename Type // Data type of the matrix
4449 , size_t M // Number of rows
4450 , size_t N // Number of columns
4451 , AlignmentFlag AF // Alignment flag
4452 , PaddingFlag PF // Padding flag
4453 , typename Tag > // Type tag
4454template< typename MT // Type of the foreign matrix
4455 , bool SO2 > // Storage order of the foreign matrix
4456inline HybridMatrix<Type,M,N,true,AF,PF,Tag>::HybridMatrix( const Matrix<MT,SO2>& m )
4457 : m_( (*m).rows() ) // The current number of rows of the matrix
4458 , n_( (*m).columns() ) // The current number of columns of the matrix
4459 // v_ is intentionally left uninitialized
4460{
4461 using blaze::assign;
4462 using blaze::clear;
4463
4464 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4465
4466 if( (*m).rows() > M || (*m).columns() > N ) {
4467 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
4468 }
4469
4470 for( size_t j=0UL; j<n_; ++j ) {
4471 for( size_t i=( IsSparseMatrix_v<MT> ? 0UL : m_ );
4472 i<( IsNumeric_v<Type> ? MM : m_ );
4473 ++i ) {
4474 clear( v_[i+j*MM] );
4475 }
4476 }
4477
4478 if( IsNumeric_v<Type> ) {
4479 for( size_t j=n_; j<N; ++j )
4480 for( size_t i=0UL; i<MM; ++i )
4481 clear( v_[i+j*MM] );
4482 }
4483
4484 assign( *this, *m );
4485
4486 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4487}
4489//*************************************************************************************************
4490
4491
4492
4493
4494//=================================================================================================
4495//
4496// DATA ACCESS FUNCTIONS
4497//
4498//=================================================================================================
4499
4500//*************************************************************************************************
4511template< typename Type // Data type of the matrix
4512 , size_t M // Number of rows
4513 , size_t N // Number of columns
4514 , AlignmentFlag AF // Alignment flag
4515 , PaddingFlag PF // Padding flag
4516 , typename Tag > // Type tag
4518 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator()( size_t i, size_t j ) noexcept
4519{
4520 BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
4521 BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
4522 return v_[i+j*MM];
4523}
4525//*************************************************************************************************
4526
4527
4528//*************************************************************************************************
4539template< typename Type // Data type of the matrix
4540 , size_t M // Number of rows
4541 , size_t N // Number of columns
4542 , AlignmentFlag AF // Alignment flag
4543 , PaddingFlag PF // Padding flag
4544 , typename Tag > // Type tag
4546 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator()( size_t i, size_t j ) const noexcept
4547{
4548 BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
4549 BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
4550 return v_[i+j*MM];
4551}
4553//*************************************************************************************************
4554
4555
4556//*************************************************************************************************
4568template< typename Type // Data type of the matrix
4569 , size_t M // Number of rows
4570 , size_t N // Number of columns
4571 , AlignmentFlag AF // Alignment flag
4572 , PaddingFlag PF // Padding flag
4573 , typename Tag > // Type tag
4575 HybridMatrix<Type,M,N,true,AF,PF,Tag>::at( size_t i, size_t j )
4576{
4577 if( i >= m_ ) {
4578 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4579 }
4580 if( j >= n_ ) {
4581 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4582 }
4583 return (*this)(i,j);
4584}
4586//*************************************************************************************************
4587
4588
4589//*************************************************************************************************
4601template< typename Type // Data type of the matrix
4602 , size_t M // Number of rows
4603 , size_t N // Number of columns
4604 , AlignmentFlag AF // Alignment flag
4605 , PaddingFlag PF // Padding flag
4606 , typename Tag > // Type tag
4608 HybridMatrix<Type,M,N,true,AF,PF,Tag>::at( size_t i, size_t j ) const
4609{
4610 if( i >= m_ ) {
4611 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4612 }
4613 if( j >= n_ ) {
4614 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4615 }
4616 return (*this)(i,j);
4617}
4619//*************************************************************************************************
4620
4621
4622//*************************************************************************************************
4634template< typename Type // Data type of the matrix
4635 , size_t M // Number of rows
4636 , size_t N // Number of columns
4637 , AlignmentFlag AF // Alignment flag
4638 , PaddingFlag PF // Padding flag
4639 , typename Tag > // Type tag
4642{
4643 return v_;
4644}
4646//*************************************************************************************************
4647
4648
4649//*************************************************************************************************
4661template< typename Type // Data type of the matrix
4662 , size_t M // Number of rows
4663 , size_t N // Number of columns
4664 , AlignmentFlag AF // Alignment flag
4665 , PaddingFlag PF // Padding flag
4666 , typename Tag > // Type tag
4669{
4670 return v_;
4671}
4673//*************************************************************************************************
4674
4675
4676//*************************************************************************************************
4685template< typename Type // Data type of the matrix
4686 , size_t M // Number of rows
4687 , size_t N // Number of columns
4688 , AlignmentFlag AF // Alignment flag
4689 , PaddingFlag PF // Padding flag
4690 , typename Tag > // Type tag
4693{
4694 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4695 return v_ + j*MM;
4696}
4698//*************************************************************************************************
4699
4700
4701//*************************************************************************************************
4710template< typename Type // Data type of the matrix
4711 , size_t M // Number of rows
4712 , size_t N // Number of columns
4713 , AlignmentFlag AF // Alignment flag
4714 , PaddingFlag PF // Padding flag
4715 , typename Tag > // Type tag
4717 HybridMatrix<Type,M,N,true,AF,PF,Tag>::data( size_t j ) const noexcept
4718{
4719 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4720 return v_ + j*MM;
4721}
4723//*************************************************************************************************
4724
4725
4726//*************************************************************************************************
4733template< typename Type // Data type of the matrix
4734 , size_t M // Number of rows
4735 , size_t N // Number of columns
4736 , AlignmentFlag AF // Alignment flag
4737 , PaddingFlag PF // Padding flag
4738 , typename Tag > // Type tag
4741{
4742 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4743 return Iterator( v_ + j*MM );
4744}
4746//*************************************************************************************************
4747
4748
4749//*************************************************************************************************
4756template< typename Type // Data type of the matrix
4757 , size_t M // Number of rows
4758 , size_t N // Number of columns
4759 , AlignmentFlag AF // Alignment flag
4760 , PaddingFlag PF // Padding flag
4761 , typename Tag > // Type tag
4763 HybridMatrix<Type,M,N,true,AF,PF,Tag>::begin( size_t j ) const noexcept
4764{
4765 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4766 return ConstIterator( v_ + j*MM );
4767}
4769//*************************************************************************************************
4770
4771
4772//*************************************************************************************************
4779template< typename Type // Data type of the matrix
4780 , size_t M // Number of rows
4781 , size_t N // Number of columns
4782 , AlignmentFlag AF // Alignment flag
4783 , PaddingFlag PF // Padding flag
4784 , typename Tag > // Type tag
4786 HybridMatrix<Type,M,N,true,AF,PF,Tag>::cbegin( size_t j ) const noexcept
4787{
4788 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4789 return ConstIterator( v_ + j*MM );
4790}
4792//*************************************************************************************************
4793
4794
4795//*************************************************************************************************
4802template< typename Type // Data type of the matrix
4803 , size_t M // Number of rows
4804 , size_t N // Number of columns
4805 , AlignmentFlag AF // Alignment flag
4806 , PaddingFlag PF // Padding flag
4807 , typename Tag > // Type tag
4810{
4811 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4812 return Iterator( v_ + j*MM + M );
4813}
4815//*************************************************************************************************
4816
4817
4818//*************************************************************************************************
4825template< typename Type // Data type of the matrix
4826 , size_t M // Number of rows
4827 , size_t N // Number of columns
4828 , AlignmentFlag AF // Alignment flag
4829 , PaddingFlag PF // Padding flag
4830 , typename Tag > // Type tag
4832 HybridMatrix<Type,M,N,true,AF,PF,Tag>::end( size_t j ) const noexcept
4833{
4834 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4835 return ConstIterator( v_ + j*MM + M );
4836}
4838//*************************************************************************************************
4839
4840
4841//*************************************************************************************************
4848template< typename Type // Data type of the matrix
4849 , size_t M // Number of rows
4850 , size_t N // Number of columns
4851 , AlignmentFlag AF // Alignment flag
4852 , PaddingFlag PF // Padding flag
4853 , typename Tag > // Type tag
4855 HybridMatrix<Type,M,N,true,AF,PF,Tag>::cend( size_t j ) const noexcept
4856{
4857 BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4858 return ConstIterator( v_ + j*MM + M );
4859}
4861//*************************************************************************************************
4862
4863
4864
4865
4866//=================================================================================================
4867//
4868// ASSIGNMENT OPERATORS
4869//
4870//=================================================================================================
4871
4872//*************************************************************************************************
4879template< typename Type // Data type of the matrix
4880 , size_t M // Number of rows
4881 , size_t N // Number of columns
4882 , AlignmentFlag AF // Alignment flag
4883 , PaddingFlag PF // Padding flag
4884 , typename Tag > // Type tag
4885constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>&
4887{
4888 BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4889 BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4890
4891 for( size_t j=0UL; j<n_; ++j )
4892 for( size_t i=0UL; i<m_; ++i )
4893 v_[i+j*MM] = set;
4894
4895 return *this;
4896}
4898//*************************************************************************************************
4899
4900
4901//*************************************************************************************************
4927template< typename Type // Data type of the matrix
4928 , size_t M // Number of rows
4929 , size_t N // Number of columns
4930 , AlignmentFlag AF // Alignment flag
4931 , PaddingFlag PF // Padding flag
4932 , typename Tag > // Type tag
4933constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>&
4935{
4936 using blaze::clear;
4937
4938 const size_t m( list.size() );
4939 const size_t n( determineColumns( list ) );
4940
4941 if( m > M ) {
4942 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4943 }
4944
4945 if( n > N ) {
4946 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4947 }
4948
4949 resize( m, n, false );
4950
4951 size_t i( 0UL );
4952
4953 for( const auto& rowList : list ) {
4954 size_t j( 0UL );
4955 for( const auto& element : rowList ) {
4956 v_[i+j*MM] = element;
4957 ++j;
4958 }
4959 for( ; j<n_; ++j ) {
4960 clear( v_[i+j*MM] );
4961 }
4962 ++i;
4963 }
4964
4965 return *this;
4966}
4968//*************************************************************************************************
4969
4970
4971//*************************************************************************************************
4993template< typename Type // Data type of the matrix
4994 , size_t M // Number of rows
4995 , size_t N // Number of columns
4996 , AlignmentFlag AF // Alignment flag
4997 , PaddingFlag PF // Padding flag
4998 , typename Tag > // Type tag
4999template< typename Other // Data type of the static array
5000 , size_t Rows // Number of rows of the static array
5001 , size_t Cols > // Number of columns of the static array
5002constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5003 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator=( const Other (&array)[Rows][Cols] ) &
5004{
5005 BLAZE_STATIC_ASSERT( Rows <= M );
5006 BLAZE_STATIC_ASSERT( Cols <= N );
5007
5008 resize( Rows, Cols );
5009
5010 for( size_t j=0UL; j<Cols; ++j )
5011 for( size_t i=0UL; i<Rows; ++i )
5012 v_[i+j*MM] = array[i][j];
5013
5014 return *this;
5015}
5017//*************************************************************************************************
5018
5019
5020//*************************************************************************************************
5042template< typename Type // Data type of the matrix
5043 , size_t M // Number of rows
5044 , size_t N // Number of columns
5045 , AlignmentFlag AF // Alignment flag
5046 , PaddingFlag PF // Padding flag
5047 , typename Tag > // Type tag
5048template< typename Other // Data type of the static array
5049 , size_t Rows // Number of rows of the static array
5050 , size_t Cols > // Number of columns of the static array
5051constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5052 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &
5053{
5054 BLAZE_STATIC_ASSERT( Rows <= M );
5055 BLAZE_STATIC_ASSERT( Cols <= N );
5056
5057 resize( Rows, Cols );
5058
5059 for( size_t j=0UL; j<Cols; ++j )
5060 for( size_t i=0UL; i<Rows; ++i )
5061 v_[i+j*MM] = array[i][j];
5062
5063 return *this;
5064}
5066//*************************************************************************************************
5067
5068
5069//*************************************************************************************************
5078template< typename Type // Data type of the matrix
5079 , size_t M // Number of rows
5080 , size_t N // Number of columns
5081 , AlignmentFlag AF // Alignment flag
5082 , PaddingFlag PF // Padding flag
5083 , typename Tag > // Type tag
5084constexpr HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5085 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator=( const HybridMatrix& rhs ) &
5086{
5087 using blaze::assign;
5088
5089 BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
5090 BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
5091
5092 resize( rhs.rows(), rhs.columns() );
5093 assign( *this, *rhs );
5094
5095 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5096
5097 return *this;
5098}
5100//*************************************************************************************************
5101
5102
5103//*************************************************************************************************
5115template< typename Type // Data type of the matrix
5116 , size_t M // Number of rows
5117 , size_t N // Number of columns
5118 , AlignmentFlag AF // Alignment flag
5119 , PaddingFlag PF // Padding flag
5120 , typename Tag > // Type tag
5121template< typename MT // Type of the right-hand side matrix
5122 , bool SO > // Storage order of the right-hand side matrix
5123inline HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5124 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator=( const Matrix<MT,SO>& rhs ) &
5125{
5126 using blaze::assign;
5127
5128 using TT = decltype( trans( *this ) );
5129 using CT = decltype( ctrans( *this ) );
5130 using IT = decltype( inv( *this ) );
5131
5132 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5133
5134 if( (*rhs).rows() > M || (*rhs).columns() > N ) {
5135 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
5136 }
5137
5138 if( IsSame_v<MT,TT> && (*rhs).isAliased( this ) ) {
5139 transpose();
5140 }
5141 else if( IsSame_v<MT,CT> && (*rhs).isAliased( this ) ) {
5142 ctranspose();
5143 }
5144 else if( !IsSame_v<MT,IT> && (*rhs).canAlias( this ) ) {
5145 HybridMatrix tmp( *rhs );
5146 resize( tmp.rows(), tmp.columns() );
5147 assign( *this, tmp );
5148 }
5149 else {
5150 resize( (*rhs).rows(), (*rhs).columns() );
5151 if( IsSparseMatrix_v<MT> )
5152 reset();
5153 assign( *this, *rhs );
5154 }
5155
5156 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5157
5158 return *this;
5159}
5161//*************************************************************************************************
5162
5163
5164//*************************************************************************************************
5175template< typename Type // Data type of the matrix
5176 , size_t M // Number of rows
5177 , size_t N // Number of columns
5178 , AlignmentFlag AF // Alignment flag
5179 , PaddingFlag PF // Padding flag
5180 , typename Tag > // Type tag
5181template< typename MT // Type of the right-hand side matrix
5182 , bool SO > // Storage order of the right-hand side matrix
5183inline HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5184 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator+=( const Matrix<MT,SO>& rhs ) &
5185{
5186 using blaze::addAssign;
5187
5188 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5189
5190 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
5191 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
5192 }
5193
5194 if( (*rhs).canAlias( this ) ) {
5195 const ResultType_t<MT> tmp( *rhs );
5196 addAssign( *this, tmp );
5197 }
5198 else {
5199 addAssign( *this, *rhs );
5200 }
5201
5202 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5203
5204 return *this;
5205}
5207//*************************************************************************************************
5208
5209
5210//*************************************************************************************************
5221template< typename Type // Data type of the matrix
5222 , size_t M // Number of rows
5223 , size_t N // Number of columns
5224 , AlignmentFlag AF // Alignment flag
5225 , PaddingFlag PF // Padding flag
5226 , typename Tag > // Type tag
5227template< typename MT // Type of the right-hand side matrix
5228 , bool SO > // Storage order of the right-hand side matrix
5229inline HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5230 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator-=( const Matrix<MT,SO>& rhs ) &
5231{
5232 using blaze::subAssign;
5233
5234 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5235
5236 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
5237 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
5238 }
5239
5240 if( (*rhs).canAlias( this ) ) {
5241 const ResultType_t<MT> tmp( *rhs );
5242 subAssign( *this, tmp );
5243 }
5244 else {
5245 subAssign( *this, *rhs );
5246 }
5247
5248 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5249
5250 return *this;
5251}
5253//*************************************************************************************************
5254
5255
5256//*************************************************************************************************
5267template< typename Type // Data type of the matrix
5268 , size_t M // Number of rows
5269 , size_t N // Number of columns
5270 , AlignmentFlag AF // Alignment flag
5271 , PaddingFlag PF // Padding flag
5272 , typename Tag > // Type tag
5273template< typename MT // Type of the right-hand side matrix
5274 , bool SO > // Storage order of the right-hand side matrix
5275inline HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5276 HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator%=( const Matrix<MT,SO>& rhs ) &
5277{
5278 using blaze::schurAssign;
5279
5280 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5281
5282 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
5283 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
5284 }
5285
5286 if( (*rhs).canAlias( this ) ) {
5287 const ResultType_t<MT> tmp( *rhs );
5288 schurAssign( *this, tmp );
5289 }
5290 else {
5291 schurAssign( *this, *rhs );
5292 }
5293
5294 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5295
5296 return *this;
5297}
5299//*************************************************************************************************
5300
5301
5302
5303
5304//=================================================================================================
5305//
5306// UTILITY FUNCTIONS
5307//
5308//=================================================================================================
5309
5310//*************************************************************************************************
5316template< typename Type // Data type of the matrix
5317 , size_t M // Number of rows
5318 , size_t N // Number of columns
5319 , AlignmentFlag AF // Alignment flag
5320 , PaddingFlag PF // Padding flag
5321 , typename Tag > // Type tag
5322constexpr size_t HybridMatrix<Type,M,N,true,AF,PF,Tag>::rows() const noexcept
5323{
5324 return m_;
5325}
5327//*************************************************************************************************
5328
5329
5330//*************************************************************************************************
5336template< typename Type // Data type of the matrix
5337 , size_t M // Number of rows
5338 , size_t N // Number of columns
5339 , AlignmentFlag AF // Alignment flag
5340 , PaddingFlag PF // Padding flag
5341 , typename Tag > // Type tag
5342constexpr size_t HybridMatrix<Type,M,N,true,AF,PF,Tag>::columns() const noexcept
5343{
5344 return n_;
5345}
5347//*************************************************************************************************
5348
5349
5350//*************************************************************************************************
5359template< typename Type // Data type of the matrix
5360 , size_t M // Number of rows
5361 , size_t N // Number of columns
5362 , AlignmentFlag AF // Alignment flag
5363 , PaddingFlag PF // Padding flag
5364 , typename Tag > // Type tag
5365constexpr size_t HybridMatrix<Type,M,N,true,AF,PF,Tag>::spacing() noexcept
5366{
5367 return MM;
5368}
5370//*************************************************************************************************
5371
5372
5373//*************************************************************************************************
5379template< typename Type // Data type of the matrix
5380 , size_t M // Number of rows
5381 , size_t N // Number of columns
5382 , AlignmentFlag AF // Alignment flag
5383 , PaddingFlag PF // Padding flag
5384 , typename Tag > // Type tag
5385constexpr size_t HybridMatrix<Type,M,N,true,AF,PF,Tag>::capacity() noexcept
5386{
5387 return MM*N;
5388}
5390//*************************************************************************************************
5391
5392
5393//*************************************************************************************************
5400template< typename Type // Data type of the matrix
5401 , size_t M // Number of rows
5402 , size_t N // Number of columns
5403 , AlignmentFlag AF // Alignment flag
5404 , PaddingFlag PF // Padding flag
5405 , typename Tag > // Type tag
5406constexpr size_t HybridMatrix<Type,M,N,true,AF,PF,Tag>::capacity( size_t j ) const noexcept
5407{
5408 MAYBE_UNUSED( j );
5409
5410 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5411
5412 return MM;
5413}
5415//*************************************************************************************************
5416
5417
5418//*************************************************************************************************
5428template< typename Type // Data type of the matrix
5429 , size_t M // Number of rows
5430 , size_t N // Number of columns
5431 , AlignmentFlag AF // Alignment flag
5432 , PaddingFlag PF // Padding flag
5433 , typename Tag > // Type tag
5435{
5436 size_t nonzeros( 0UL );
5437
5438 for( size_t j=0UL; j<n_; ++j )
5439 for( size_t i=0UL; i<m_; ++i )
5440 if( !isDefault<strict>( v_[i+j*MM] ) )
5441 ++nonzeros;
5442
5443 return nonzeros;
5444}
5446//*************************************************************************************************
5447
5448
5449//*************************************************************************************************
5459template< typename Type // Data type of the matrix
5460 , size_t M // Number of rows
5461 , size_t N // Number of columns
5462 , AlignmentFlag AF // Alignment flag
5463 , PaddingFlag PF // Padding flag
5464 , typename Tag > // Type tag
5465inline size_t HybridMatrix<Type,M,N,true,AF,PF,Tag>::nonZeros( size_t j ) const
5466{
5467 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5468
5469 const size_t iend( j*MM + m_ );
5470 size_t nonzeros( 0UL );
5471
5472 for( size_t i=j*MM; i<iend; ++i )
5473 if( !isDefault<strict>( v_[i] ) )
5474 ++nonzeros;
5475
5476 return nonzeros;
5477}
5479//*************************************************************************************************
5480
5481
5482//*************************************************************************************************
5488template< typename Type // Data type of the matrix
5489 , size_t M // Number of rows
5490 , size_t N // Number of columns
5491 , AlignmentFlag AF // Alignment flag
5492 , PaddingFlag PF // Padding flag
5493 , typename Tag > // Type tag
5495{
5496 using blaze::clear;
5497
5498 for( size_t j=0UL; j<n_; ++j )
5499 for( size_t i=0UL; i<m_; ++i )
5500 clear( v_[i+j*MM] );
5501}
5503//*************************************************************************************************
5504
5505
5506//*************************************************************************************************
5516template< typename Type // Data type of the matrix
5517 , size_t M // Number of rows
5518 , size_t N // Number of columns
5519 , AlignmentFlag AF // Alignment flag
5520 , PaddingFlag PF // Padding flag
5521 , typename Tag > // Type tag
5522constexpr void HybridMatrix<Type,M,N,true,AF,PF,Tag>::reset( size_t j )
5523{
5524 using blaze::clear;
5525
5526 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5527 for( size_t i=0UL; i<m_; ++i )
5528 clear( v_[i+j*MM] );
5529}
5531//*************************************************************************************************
5532
5533
5534//*************************************************************************************************
5542template< typename Type // Data type of the matrix
5543 , size_t M // Number of rows
5544 , size_t N // Number of columns
5545 , AlignmentFlag AF // Alignment flag
5546 , PaddingFlag PF // Padding flag
5547 , typename Tag > // Type tag
5549{
5550 resize( 0UL, 0UL );
5551}
5553//*************************************************************************************************
5554
5555
5556//*************************************************************************************************
5593template< typename Type // Data type of the matrix
5594 , size_t M // Number of rows
5595 , size_t N // Number of columns
5596 , AlignmentFlag AF // Alignment flag
5597 , PaddingFlag PF // Padding flag
5598 , typename Tag > // Type tag
5599constexpr void HybridMatrix<Type,M,N,true,AF,PF,Tag>::resize( size_t m, size_t n, bool preserve )
5600{
5601 using blaze::clear;
5602
5603 MAYBE_UNUSED( preserve );
5604
5605 if( m > M ) {
5606 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
5607 }
5608
5609 if( n > N ) {
5610 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
5611 }
5612
5613 if( IsVectorizable_v<Type> && m < m_ ) {
5614 for( size_t j=0UL; j<n; ++j )
5615 for( size_t i=m; i<m_; ++i )
5616 clear( v_[i+j*MM] );
5617 }
5618
5619 if( IsVectorizable_v<Type> && n < n_ ) {
5620 for( size_t j=n; j<n_; ++j )
5621 for( size_t i=0UL; i<m_; ++i )
5622 clear( v_[i+j*MM] );
5623 }
5624
5625 m_ = m;
5626 n_ = n;
5627}
5629//*************************************************************************************************
5630
5631
5632//*************************************************************************************************
5648template< typename Type // Data type of the matrix
5649 , size_t M // Number of rows
5650 , size_t N // Number of columns
5651 , AlignmentFlag AF // Alignment flag
5652 , PaddingFlag PF // Padding flag
5653 , typename Tag > // Type tag
5654constexpr void HybridMatrix<Type,M,N,true,AF,PF,Tag>::extend( size_t m, size_t n, bool preserve )
5655{
5656 MAYBE_UNUSED( preserve );
5657 resize( m_+m, n_+n );
5658}
5660//*************************************************************************************************
5661
5662
5663//*************************************************************************************************
5670template< typename Type // Data type of the matrix
5671 , size_t M // Number of rows
5672 , size_t N // Number of columns
5673 , AlignmentFlag AF // Alignment flag
5674 , PaddingFlag PF // Padding flag
5675 , typename Tag > // Type tag
5676inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::swap( HybridMatrix& m ) noexcept
5677{
5678 using std::swap;
5679
5680 const size_t maxrows( max( m_, m.m_ ) );
5681 const size_t maxcols( max( n_, m.n_ ) );
5682
5683 for( size_t j=0UL; j<maxcols; ++j ) {
5684 for( size_t i=0UL; i<maxrows; ++i ) {
5685 swap( v_[i+j*MM], m(i,j) );
5686 }
5687 }
5688
5689 swap( m_, m.m_ );
5690 swap( n_, m.n_ );
5691}
5693//*************************************************************************************************
5694
5695
5696
5697
5698//=================================================================================================
5699//
5700// NUMERIC FUNCTIONS
5701//
5702//=================================================================================================
5703
5704//*************************************************************************************************
5716template< typename Type // Data type of the matrix
5717 , size_t M // Number of rows
5718 , size_t N // Number of columns
5719 , AlignmentFlag AF // Alignment flag
5720 , PaddingFlag PF // Padding flag
5721 , typename Tag > // Type tag
5722inline HybridMatrix<Type,M,N,true,AF,PF,Tag>& HybridMatrix<Type,M,N,true,AF,PF,Tag>::transpose()
5723{
5724 using std::swap;
5725 using blaze::clear;
5726
5727 if( m_ > N || n_ > M ) {
5728 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5729 }
5730
5731 const size_t maxsize( max( m_, n_ ) );
5732 for( size_t j=1UL; j<maxsize; ++j ) {
5733 for( size_t i=0UL; i<j; ++i ) {
5734 swap( v_[i+j*MM], v_[j+i*MM] );
5735 }
5736 }
5737
5738 if( IsVectorizable_v<Type> && n_ < m_ ) {
5739 for( size_t j=0UL; j<n_; ++j ) {
5740 for( size_t i=n_; i<m_; ++i ) {
5741 clear( v_[i+j*MM] );
5742 }
5743 }
5744 }
5745
5746 if( IsVectorizable_v<Type> && n_ > m_ ) {
5747 for( size_t j=m_; j<n_; ++j ) {
5748 for( size_t i=0UL; i<m_; ++i ) {
5749 clear( v_[i+j*MM] );
5750 }
5751 }
5752 }
5753
5754 swap( m_, n_ );
5755
5756 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5757
5758 return *this;
5759}
5761//*************************************************************************************************
5762
5763
5764//*************************************************************************************************
5776template< typename Type // Data type of the matrix
5777 , size_t M // Number of rows
5778 , size_t N // Number of columns
5779 , AlignmentFlag AF // Alignment flag
5780 , PaddingFlag PF // Padding flag
5781 , typename Tag > // Type tag
5782inline HybridMatrix<Type,M,N,true,AF,PF,Tag>& HybridMatrix<Type,M,N,true,AF,PF,Tag>::ctranspose()
5783{
5784 using std::swap;
5785 using blaze::clear;
5786
5787 if( m_ > N || n_ > M ) {
5788 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5789 }
5790
5791 const size_t maxsize( max( m_, n_ ) );
5792 for( size_t j=0UL; j<maxsize; ++j ) {
5793 for( size_t i=0UL; i<j; ++i ) {
5794 cswap( v_[i+j*MM], v_[j+i*MM] );
5795 }
5796 conjugate( v_[j+j*MM] );
5797 }
5798
5799 if( IsVectorizable_v<Type> && n_ < m_ ) {
5800 for( size_t j=0UL; j<n_; ++j ) {
5801 for( size_t i=n_; i<m_; ++i ) {
5802 clear( v_[i+j*MM] );
5803 }
5804 }
5805 }
5806
5807 if( IsVectorizable_v<Type> && n_ > m_ ) {
5808 for( size_t j=m_; j<n_; ++j ) {
5809 for( size_t i=0UL; i<m_; ++i ) {
5810 clear( v_[i+j*MM] );
5811 }
5812 }
5813 }
5814
5815 swap( m_, n_ );
5816
5817 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5818
5819 return *this;
5820}
5822//*************************************************************************************************
5823
5824
5825//*************************************************************************************************
5843template< typename Type // Data type of the matrix
5844 , size_t M // Number of rows
5845 , size_t N // Number of columns
5846 , AlignmentFlag AF // Alignment flag
5847 , PaddingFlag PF // Padding flag
5848 , typename Tag > // Type tag
5849template< typename Other > // Data type of the scalar value
5850inline HybridMatrix<Type,M,N,true,AF,PF,Tag>&
5851 HybridMatrix<Type,M,N,true,AF,PF,Tag>::scale( const Other& scalar )
5852{
5853 for( size_t j=0UL; j<n_; ++j )
5854 for( size_t i=0UL; i<m_; ++i )
5855 v_[i+j*MM] *= scalar;
5856
5857 return *this;
5858}
5860//*************************************************************************************************
5861
5862
5863
5864
5865//=================================================================================================
5866//
5867// MEMORY FUNCTIONS
5868//
5869//=================================================================================================
5870
5871//*************************************************************************************************
5882template< typename Type // Data type of the matrix
5883 , size_t M // Number of rows
5884 , size_t N // Number of columns
5885 , AlignmentFlag AF // Alignment flag
5886 , PaddingFlag PF // Padding flag
5887 , typename Tag > // Type tag
5888inline void* HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator new( std::size_t size )
5889{
5890 MAYBE_UNUSED( size );
5891
5892 BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5893
5894 return allocate<HybridMatrix>( 1UL );
5895}
5897//*************************************************************************************************
5898
5899
5900//*************************************************************************************************
5911template< typename Type // Data type of the matrix
5912 , size_t M // Number of rows
5913 , size_t N // Number of columns
5914 , AlignmentFlag AF // Alignment flag
5915 , PaddingFlag PF // Padding flag
5916 , typename Tag > // Type tag
5917inline void* HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator new[]( std::size_t size )
5918{
5919 BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5920 BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5921
5922 return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5923}
5925//*************************************************************************************************
5926
5927
5928//*************************************************************************************************
5939template< typename Type // Data type of the matrix
5940 , size_t M // Number of rows
5941 , size_t N // Number of columns
5942 , AlignmentFlag AF // Alignment flag
5943 , PaddingFlag PF // Padding flag
5944 , typename Tag > // Type tag
5945inline void* HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator new( std::size_t size, const std::nothrow_t& )
5946{
5947 MAYBE_UNUSED( size );
5948
5949 BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5950
5951 return allocate<HybridMatrix>( 1UL );
5952}
5954//*************************************************************************************************
5955
5956
5957//*************************************************************************************************
5968template< typename Type // Data type of the matrix
5969 , size_t M // Number of rows
5970 , size_t N // Number of columns
5971 , AlignmentFlag AF // Alignment flag
5972 , PaddingFlag PF // Padding flag
5973 , typename Tag > // Type tag
5974inline void* HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator new[]( std::size_t size, const std::nothrow_t& )
5975{
5976 BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5977 BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5978
5979 return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5980}
5982//*************************************************************************************************
5983
5984
5985//*************************************************************************************************
5992template< typename Type // Data type of the matrix
5993 , size_t M // Number of rows
5994 , size_t N // Number of columns
5995 , AlignmentFlag AF // Alignment flag
5996 , PaddingFlag PF // Padding flag
5997 , typename Tag > // Type tag
5998inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator delete( void* ptr )
5999{
6000 deallocate( static_cast<HybridMatrix*>( ptr ) );
6001}
6003//*************************************************************************************************
6004
6005
6006//*************************************************************************************************
6013template< typename Type // Data type of the matrix
6014 , size_t M // Number of rows
6015 , size_t N // Number of columns
6016 , AlignmentFlag AF // Alignment flag
6017 , PaddingFlag PF // Padding flag
6018 , typename Tag > // Type tag
6019inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator delete[]( void* ptr )
6020{
6021 deallocate( static_cast<HybridMatrix*>( ptr ) );
6022}
6024//*************************************************************************************************
6025
6026
6027//*************************************************************************************************
6034template< typename Type // Data type of the matrix
6035 , size_t M // Number of rows
6036 , size_t N // Number of columns
6037 , AlignmentFlag AF // Alignment flag
6038 , PaddingFlag PF // Padding flag
6039 , typename Tag > // Type tag
6040inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator delete( void* ptr, const std::nothrow_t& )
6041{
6042 deallocate( static_cast<HybridMatrix*>( ptr ) );
6043}
6045//*************************************************************************************************
6046
6047
6048//*************************************************************************************************
6055template< typename Type // Data type of the matrix
6056 , size_t M // Number of rows
6057 , size_t N // Number of columns
6058 , AlignmentFlag AF // Alignment flag
6059 , PaddingFlag PF // Padding flag
6060 , typename Tag > // Type tag
6061inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::operator delete[]( void* ptr, const std::nothrow_t& )
6062{
6063 deallocate( static_cast<HybridMatrix*>( ptr ) );
6064}
6066//*************************************************************************************************
6067
6068
6069
6070
6071//=================================================================================================
6072//
6073// DEBUGGING FUNCTIONS
6074//
6075//=================================================================================================
6076
6077//*************************************************************************************************
6087template< typename Type // Data type of the matrix
6088 , size_t M // Number of rows
6089 , size_t N // Number of columns
6090 , AlignmentFlag AF // Alignment flag
6091 , PaddingFlag PF // Padding flag
6092 , typename Tag > // Type tag
6093constexpr bool HybridMatrix<Type,M,N,true,AF,PF,Tag>::isIntact() const noexcept
6094{
6095 if( m_ > M || n_ > N )
6096 return false;
6097
6098 if( IsVectorizable_v<Type> )
6099 {
6100 for( size_t j=0UL; j<n_; ++j ) {
6101 for( size_t i=m_; i<MM; ++i ) {
6102 if( !isDefault<strict>( v_[i+j*MM] ) )
6103 return false;
6104 }
6105 }
6106
6107 for( size_t j=n_; j<N; ++j ) {
6108 for( size_t i=0UL; i<MM; ++i ) {
6109 if( !isDefault<strict>( v_[i+j*MM] ) )
6110 return false;
6111 }
6112 }
6113 }
6114
6115 return true;
6116}
6118//*************************************************************************************************
6119
6120
6121
6122
6123//=================================================================================================
6124//
6125// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6126//
6127//=================================================================================================
6128
6129//*************************************************************************************************
6140template< typename Type // Data type of the matrix
6141 , size_t M // Number of rows
6142 , size_t N // Number of columns
6143 , AlignmentFlag AF // Alignment flag
6144 , PaddingFlag PF // Padding flag
6145 , typename Tag > // Type tag
6146template< typename Other > // Data type of the foreign expression
6147inline bool HybridMatrix<Type,M,N,true,AF,PF,Tag>::canAlias( const Other* alias ) const noexcept
6148{
6149 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
6150}
6152//*************************************************************************************************
6153
6154
6155//*************************************************************************************************
6166template< typename Type // Data type of the matrix
6167 , size_t M // Number of rows
6168 , size_t N // Number of columns
6169 , AlignmentFlag AF // Alignment flag
6170 , PaddingFlag PF // Padding flag
6171 , typename Tag > // Type tag
6172template< typename Other > // Data type of the foreign expression
6173inline bool HybridMatrix<Type,M,N,true,AF,PF,Tag>::isAliased( const Other* alias ) const noexcept
6174{
6175 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
6176}
6178//*************************************************************************************************
6179
6180
6181//*************************************************************************************************
6191template< typename Type // Data type of the matrix
6192 , size_t M // Number of rows
6193 , size_t N // Number of columns
6194 , AlignmentFlag AF // Alignment flag
6195 , PaddingFlag PF // Padding flag
6196 , typename Tag > // Type tag
6198{
6199 return AF == aligned;
6200}
6202//*************************************************************************************************
6203
6204
6205//*************************************************************************************************
6220template< typename Type // Data type of the matrix
6221 , size_t M // Number of rows
6222 , size_t N // Number of columns
6223 , AlignmentFlag AF // Alignment flag
6224 , PaddingFlag PF // Padding flag
6225 , typename Tag > // Type tag
6227 HybridMatrix<Type,M,N,true,AF,PF,Tag>::load( size_t i, size_t j ) const noexcept
6228{
6229 if( AF == aligned )
6230 return loada( i, j );
6231 else
6232 return loadu( i, j );
6233}
6235//*************************************************************************************************
6236
6237
6238//*************************************************************************************************
6253template< typename Type // Data type of the matrix
6254 , size_t M // Number of rows
6255 , size_t N // Number of columns
6256 , AlignmentFlag AF // Alignment flag
6257 , PaddingFlag PF // Padding flag
6258 , typename Tag > // Type tag
6260 HybridMatrix<Type,M,N,true,AF,PF,Tag>::loada( size_t i, size_t j ) const noexcept
6261{
6262 using blaze::loada;
6263
6265
6266 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6267 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
6268 BLAZE_INTERNAL_ASSERT( PF == unpadded || i % SIMDSIZE == 0UL, "Invalid row access index" );
6269 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6270 BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
6271
6272 return loada( &v_[i+j*MM] );
6273}
6275//*************************************************************************************************
6276
6277
6278//*************************************************************************************************
6293template< typename Type // Data type of the matrix
6294 , size_t M // Number of rows
6295 , size_t N // Number of columns
6296 , AlignmentFlag AF // Alignment flag
6297 , PaddingFlag PF // Padding flag
6298 , typename Tag > // Type tag
6300 HybridMatrix<Type,M,N,true,AF,PF,Tag>::loadu( size_t i, size_t j ) const noexcept
6301{
6302 using blaze::loadu;
6303
6305
6306 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6307 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
6308 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6309
6310 return loadu( &v_[i+j*MM] );
6311}
6313//*************************************************************************************************
6314
6315
6316//*************************************************************************************************
6332template< typename Type // Data type of the matrix
6333 , size_t M // Number of rows
6334 , size_t N // Number of columns
6335 , AlignmentFlag AF // Alignment flag
6336 , PaddingFlag PF // Padding flag
6337 , typename Tag > // Type tag
6339 HybridMatrix<Type,M,N,true,AF,PF,Tag>::store( size_t i, size_t j, const SIMDType& value ) noexcept
6340{
6341 if( AF == aligned )
6342 storea( i, j, value );
6343 else
6344 storeu( i, j, value );
6345}
6347//*************************************************************************************************
6348
6349
6350//*************************************************************************************************
6366template< typename Type // Data type of the matrix
6367 , size_t M // Number of rows
6368 , size_t N // Number of columns
6369 , AlignmentFlag AF // Alignment flag
6370 , PaddingFlag PF // Padding flag
6371 , typename Tag > // Type tag
6373 HybridMatrix<Type,M,N,true,AF,PF,Tag>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
6374{
6375 using blaze::storea;
6376
6378
6379 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6380 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
6381 BLAZE_INTERNAL_ASSERT( PF == unpadded || i % SIMDSIZE == 0UL, "Invalid row access index" );
6382 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6383 BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
6384
6385 storea( &v_[i+j*MM], value );
6386}
6388//*************************************************************************************************
6389
6390
6391//*************************************************************************************************
6407template< typename Type // Data type of the matrix
6408 , size_t M // Number of rows
6409 , size_t N // Number of columns
6410 , AlignmentFlag AF // Alignment flag
6411 , PaddingFlag PF // Padding flag
6412 , typename Tag > // Type tag
6414 HybridMatrix<Type,M,N,true,AF,PF,Tag>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
6415{
6416 using blaze::storeu;
6417
6419
6420 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6421 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
6422 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6423
6424 storeu( &v_[i+j*MM], value );
6425}
6427//*************************************************************************************************
6428
6429
6430//*************************************************************************************************
6447template< typename Type // Data type of the matrix
6448 , size_t M // Number of rows
6449 , size_t N // Number of columns
6450 , AlignmentFlag AF // Alignment flag
6451 , PaddingFlag PF // Padding flag
6452 , typename Tag > // Type tag
6454 HybridMatrix<Type,M,N,true,AF,PF,Tag>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
6455{
6456 using blaze::stream;
6457
6459
6460 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6461 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
6462 BLAZE_INTERNAL_ASSERT( PF == unpadded || i % SIMDSIZE == 0UL, "Invalid row access index" );
6463 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6464 BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
6465
6466 stream( &v_[i+j*MM], value );
6467}
6469//*************************************************************************************************
6470
6471
6472//*************************************************************************************************
6484template< typename Type // Data type of the matrix
6485 , size_t M // Number of rows
6486 , size_t N // Number of columns
6487 , AlignmentFlag AF // Alignment flag
6488 , PaddingFlag PF // Padding flag
6489 , typename Tag > // Type tag
6490template< typename MT // Type of the right-hand side dense matrix
6491 , bool SO > // Storage order of the right-hand side dense matrix
6492inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::assign( const DenseMatrix<MT,SO>& rhs )
6493 -> DisableIf_t< VectorizedAssign_v<MT> >
6494{
6495 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6496
6497 for( size_t j=0UL; j<n_; ++j ) {
6498 for( size_t i=0UL; i<m_; ++i ) {
6499 v_[i+j*MM] = (*rhs)(i,j);
6500 }
6501 }
6502}
6504//*************************************************************************************************
6505
6506
6507//*************************************************************************************************
6519template< typename Type // Data type of the matrix
6520 , size_t M // Number of rows
6521 , size_t N // Number of columns
6522 , AlignmentFlag AF // Alignment flag
6523 , PaddingFlag PF // Padding flag
6524 , typename Tag > // Type tag
6525template< typename MT // Type of the right-hand side dense matrix
6526 , bool SO > // Storage order of the right-hand side dense matrix
6527inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::assign( const DenseMatrix<MT,SO>& rhs )
6528 -> EnableIf_t< VectorizedAssign_v<MT> >
6529{
6531
6532 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6533
6534 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
6535
6536 const size_t ipos( remainder ? prevMultiple( m_, SIMDSIZE ) : m_ );
6537 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6538
6539 for( size_t j=0UL; j<n_; ++j )
6540 {
6541 size_t i( 0UL );
6542
6543 for( ; i<ipos; i+=SIMDSIZE ) {
6544 store( i, j, (*rhs).load(i,j) );
6545 }
6546 for( ; remainder && i<m_; ++i ) {
6547 v_[i+j*MM] = (*rhs)(i,j);
6548 }
6549 }
6550}
6552//*************************************************************************************************
6553
6554
6555//*************************************************************************************************
6567template< typename Type // Data type of the matrix
6568 , size_t M // Number of rows
6569 , size_t N // Number of columns
6570 , AlignmentFlag AF // Alignment flag
6571 , PaddingFlag PF // Padding flag
6572 , typename Tag > // Type tag
6573template< typename MT > // Type of the right-hand side sparse matrix
6574inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::assign( const SparseMatrix<MT,true>& rhs )
6575{
6576 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6577
6578 for( size_t j=0UL; j<n_; ++j )
6579 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6580 v_[element->index()+j*MM] = element->value();
6581}
6583//*************************************************************************************************
6584
6585
6586//*************************************************************************************************
6598template< typename Type // Data type of the matrix
6599 , size_t M // Number of rows
6600 , size_t N // Number of columns
6601 , AlignmentFlag AF // Alignment flag
6602 , PaddingFlag PF // Padding flag
6603 , typename Tag > // Type tag
6604template< typename MT > // Type of the right-hand side sparse matrix
6605inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::assign( const SparseMatrix<MT,false>& rhs )
6606{
6608
6609 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6610
6611 for( size_t i=0UL; i<m_; ++i )
6612 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6613 v_[i+element->index()*MM] = element->value();
6614}
6616//*************************************************************************************************
6617
6618
6619//*************************************************************************************************
6631template< typename Type // Data type of the matrix
6632 , size_t M // Number of rows
6633 , size_t N // Number of columns
6634 , AlignmentFlag AF // Alignment flag
6635 , PaddingFlag PF // Padding flag
6636 , typename Tag > // Type tag
6637template< typename MT // Type of the right-hand side dense matrix
6638 , bool SO > // Storage order of the right-hand side dense matrix
6639inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::addAssign( const DenseMatrix<MT,SO>& rhs )
6640 -> DisableIf_t< VectorizedAddAssign_v<MT> >
6641{
6642 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6643
6644 for( size_t j=0UL; j<n_; ++j )
6645 {
6646 if( IsDiagonal_v<MT> )
6647 {
6648 v_[j+j*MM] += (*rhs)(j,j);
6649 }
6650 else
6651 {
6652 const size_t ibegin( ( IsLower_v<MT> )
6653 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
6654 :( 0UL ) );
6655 const size_t iend ( ( IsUpper_v<MT> )
6656 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6657 :( m_ ) );
6658 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6659
6660 for( size_t i=ibegin; i<iend; ++i ) {
6661 v_[i+j*MM] += (*rhs)(i,j);
6662 }
6663 }
6664 }
6665}
6667//*************************************************************************************************
6668
6669
6670//*************************************************************************************************
6682template< typename Type // Data type of the matrix
6683 , size_t M // Number of rows
6684 , size_t N // Number of columns
6685 , AlignmentFlag AF // Alignment flag
6686 , PaddingFlag PF // Padding flag
6687 , typename Tag > // Type tag
6688template< typename MT // Type of the right-hand side dense matrix
6689 , bool SO > // Storage order of the right-hand side dense matrix
6690inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::addAssign( const DenseMatrix<MT,SO>& rhs )
6691 -> EnableIf_t< VectorizedAddAssign_v<MT> >
6692{
6695
6696 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6697
6698 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
6699
6700 for( size_t j=0UL; j<n_; ++j )
6701 {
6702 const size_t ibegin( ( IsLower_v<MT> )
6703 ?( prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6704 :( 0UL ) );
6705 const size_t iend ( ( IsUpper_v<MT> )
6706 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6707 :( m_ ) );
6708 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6709
6710 const size_t ipos( remainder ? prevMultiple( iend, SIMDSIZE ) : iend );
6711 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
6712
6713 size_t i( ibegin );
6714
6715 for( ; i<ipos; i+=SIMDSIZE ) {
6716 store( i, j, load(i,j) + (*rhs).load(i,j) );
6717 }
6718 for( ; remainder && i<iend; ++i ) {
6719 v_[i+j*MM] += (*rhs)(i,j);
6720 }
6721 }
6722}
6724//*************************************************************************************************
6725
6726
6727//*************************************************************************************************
6739template< typename Type // Data type of the matrix
6740 , size_t M // Number of rows
6741 , size_t N // Number of columns
6742 , AlignmentFlag AF // Alignment flag
6743 , PaddingFlag PF // Padding flag
6744 , typename Tag > // Type tag
6745template< typename MT > // Type of the right-hand side sparse matrix
6746inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::addAssign( const SparseMatrix<MT,true>& rhs )
6747{
6748 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6749
6750 for( size_t j=0UL; j<n_; ++j )
6751 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6752 v_[element->index()+j*MM] += element->value();
6753}
6755//*************************************************************************************************
6756
6757
6758//*************************************************************************************************
6770template< typename Type // Data type of the matrix
6771 , size_t M // Number of rows
6772 , size_t N // Number of columns
6773 , AlignmentFlag AF // Alignment flag
6774 , PaddingFlag PF // Padding flag
6775 , typename Tag > // Type tag
6776template< typename MT > // Type of the right-hand side sparse matrix
6777inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::addAssign( const SparseMatrix<MT,false>& rhs )
6778{
6780
6781 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6782
6783 for( size_t i=0UL; i<m_; ++i )
6784 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6785 v_[i+element->index()*MM] += element->value();
6786}
6788//*************************************************************************************************
6789
6790
6791//*************************************************************************************************
6803template< typename Type // Data type of the matrix
6804 , size_t M // Number of rows
6805 , size_t N // Number of columns
6806 , AlignmentFlag AF // Alignment flag
6807 , PaddingFlag PF // Padding flag
6808 , typename Tag > // Type tag
6809template< typename MT // Type of the right-hand side dense matrix
6810 , bool SO > // Storage order of the right-hand side dense matrix
6811inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::subAssign( const DenseMatrix<MT,SO>& rhs )
6812 -> DisableIf_t< VectorizedSubAssign_v<MT> >
6813{
6814 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6815
6816 for( size_t j=0UL; j<n_; ++j )
6817 {
6818 if( IsDiagonal_v<MT> )
6819 {
6820 v_[j+j*MM] -= (*rhs)(j,j);
6821 }
6822 else
6823 {
6824 const size_t ibegin( ( IsLower_v<MT> )
6825 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
6826 :( 0UL ) );
6827 const size_t iend ( ( IsUpper_v<MT> )
6828 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6829 :( m_ ) );
6830 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6831
6832 for( size_t i=ibegin; i<iend; ++i ) {
6833 v_[i+j*MM] -= (*rhs)(i,j);
6834 }
6835 }
6836 }
6837}
6839//*************************************************************************************************
6840
6841
6842//*************************************************************************************************
6854template< typename Type // Data type of the matrix
6855 , size_t M // Number of rows
6856 , size_t N // Number of columns
6857 , AlignmentFlag AF // Alignment flag
6858 , PaddingFlag PF // Padding flag
6859 , typename Tag > // Type tag
6860template< typename MT // Type of the right-hand side dense matrix
6861 , bool SO > // Storage order of the right-hand side dense matrix
6862inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::subAssign( const DenseMatrix<MT,SO>& rhs )
6863 -> EnableIf_t< VectorizedSubAssign_v<MT> >
6864{
6867
6868 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6869
6870 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
6871
6872 for( size_t j=0UL; j<n_; ++j )
6873 {
6874 const size_t ibegin( ( IsLower_v<MT> )
6875 ?( prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6876 :( 0UL ) );
6877 const size_t iend ( ( IsUpper_v<MT> )
6878 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6879 :( m_ ) );
6880 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6881
6882 const size_t ipos( remainder ? prevMultiple( iend, SIMDSIZE ) : iend );
6883 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
6884
6885 size_t i( ibegin );
6886
6887 for( ; i<ipos; i+=SIMDSIZE ) {
6888 store( i, j, load(i,j) - (*rhs).load(i,j) );
6889 }
6890 for( ; remainder && i<iend; ++i ) {
6891 v_[i+j*MM] -= (*rhs)(i,j);
6892 }
6893 }
6894}
6896//*************************************************************************************************
6897
6898
6899//*************************************************************************************************
6911template< typename Type // Data type of the matrix
6912 , size_t M // Number of rows
6913 , size_t N // Number of columns
6914 , AlignmentFlag AF // Alignment flag
6915 , PaddingFlag PF // Padding flag
6916 , typename Tag > // Type tag
6917template< typename MT > // Type of the right-hand side sparse matrix
6918inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::subAssign( const SparseMatrix<MT,true>& rhs )
6919{
6920 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6921
6922 for( size_t j=0UL; j<n_; ++j )
6923 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6924 v_[element->index()+j*MM] -= element->value();
6925}
6927//*************************************************************************************************
6928
6929
6930//*************************************************************************************************
6942template< typename Type // Data type of the matrix
6943 , size_t M // Number of rows
6944 , size_t N // Number of columns
6945 , AlignmentFlag AF // Alignment flag
6946 , PaddingFlag PF // Padding flag
6947 , typename Tag > // Type tag
6948template< typename MT > // Type of the right-hand side sparse matrix
6949inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::subAssign( const SparseMatrix<MT,false>& rhs )
6950{
6952
6953 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6954
6955 for( size_t i=0UL; i<m_; ++i )
6956 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6957 v_[i+element->index()*MM] -= element->value();
6958}
6960//*************************************************************************************************
6961
6962
6963//*************************************************************************************************
6975template< typename Type // Data type of the matrix
6976 , size_t M // Number of rows
6977 , size_t N // Number of columns
6978 , AlignmentFlag AF // Alignment flag
6979 , PaddingFlag PF // Padding flag
6980 , typename Tag > // Type tag
6981template< typename MT // Type of the right-hand side dense matrix
6982 , bool SO > // Storage order of the right-hand side dense matrix
6983inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::schurAssign( const DenseMatrix<MT,SO>& rhs )
6984 -> DisableIf_t< VectorizedSchurAssign_v<MT> >
6985{
6986 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
6987
6988 for( size_t j=0UL; j<n_; ++j ) {
6989 for( size_t i=0UL; i<m_; ++i ) {
6990 v_[i+j*MM] *= (*rhs)(i,j);
6991 }
6992 }
6993}
6995//*************************************************************************************************
6996
6997
6998//*************************************************************************************************
7010template< typename Type // Data type of the matrix
7011 , size_t M // Number of rows
7012 , size_t N // Number of columns
7013 , AlignmentFlag AF // Alignment flag
7014 , PaddingFlag PF // Padding flag
7015 , typename Tag > // Type tag
7016template< typename MT // Type of the right-hand side dense matrix
7017 , bool SO > // Storage order of the right-hand side dense matrix
7018inline auto HybridMatrix<Type,M,N,true,AF,PF,Tag>::schurAssign( const DenseMatrix<MT,SO>& rhs )
7019 -> EnableIf_t< VectorizedSchurAssign_v<MT> >
7020{
7022
7023 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
7024
7025 constexpr bool remainder( PF == unpadded || !IsPadded_v<MT> );
7026
7027 for( size_t j=0UL; j<n_; ++j )
7028 {
7029 const size_t ipos( remainder ? prevMultiple( m_, SIMDSIZE ) : m_ );
7030 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
7031
7032 size_t i( 0UL );
7033
7034 for( ; i<ipos; i+=SIMDSIZE ) {
7035 store( i, j, load(i,j) * (*rhs).load(i,j) );
7036 }
7037 for( ; remainder && i<m_; ++i ) {
7038 v_[i+j*MM] *= (*rhs)(i,j);
7039 }
7040 }
7041}
7043//*************************************************************************************************
7044
7045
7046//*************************************************************************************************
7058template< typename Type // Data type of the matrix
7059 , size_t M // Number of rows
7060 , size_t N // Number of columns
7061 , AlignmentFlag AF // Alignment flag
7062 , PaddingFlag PF // Padding flag
7063 , typename Tag > // Type tag
7064template< typename MT > // Type of the right-hand side sparse matrix
7065inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::schurAssign( const SparseMatrix<MT,true>& rhs )
7066{
7067 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
7068
7069 const HybridMatrix tmp( serial( *this ) );
7070
7071 reset();
7072
7073 for( size_t j=0UL; j<n_; ++j )
7074 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
7075 v_[element->index()+j*MM] = tmp.v_[element->index()+j*MM] * element->value();
7076}
7078//*************************************************************************************************
7079
7080
7081//*************************************************************************************************
7093template< typename Type // Data type of the matrix
7094 , size_t M // Number of rows
7095 , size_t N // Number of columns
7096 , AlignmentFlag AF // Alignment flag
7097 , PaddingFlag PF // Padding flag
7098 , typename Tag > // Type tag
7099template< typename MT > // Type of the right-hand side sparse matrix
7100inline void HybridMatrix<Type,M,N,true,AF,PF,Tag>::schurAssign( const SparseMatrix<MT,false>& rhs )
7101{
7103
7104 BLAZE_INTERNAL_ASSERT( (*rhs).rows() == m_ && (*rhs).columns() == n_, "Invalid matrix size" );
7105
7106 const HybridMatrix tmp( serial( *this ) );
7107
7108 reset();
7109
7110 for( size_t i=0UL; i<m_; ++i )
7111 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
7112 v_[i+element->index()*MM] = tmp.v_[i+element->index()*MM] * element->value();
7113}
7115//*************************************************************************************************
7116
7117
7118
7119
7120
7121
7122
7123
7124//=================================================================================================
7125//
7126// HYBRIDMATRIX OPERATORS
7127//
7128//=================================================================================================
7129
7130//*************************************************************************************************
7133template< RelaxationFlag RF, typename Type, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7134bool isDefault( const HybridMatrix<Type,M,N,SO,AF,PF,Tag>& m );
7135
7136template< typename Type, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7137bool isIntact( const HybridMatrix<Type,M,N,SO,AF,PF,Tag>& m ) noexcept;
7138
7139template< typename Type, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7140void swap( HybridMatrix<Type,M,N,SO,AF,PF,Tag>& a, HybridMatrix<Type,M,N,SO,AF,PF,Tag>& b ) noexcept;
7142//*************************************************************************************************
7143
7144
7145//*************************************************************************************************
7170template< RelaxationFlag RF // Relaxation flag
7171 , typename Type // Data type of the matrix
7172 , size_t M // Number of rows
7173 , size_t N // Number of columns
7174 , bool SO // Storage order
7175 , AlignmentFlag AF // Alignment flag
7176 , PaddingFlag PF // Padding flag
7177 , typename Tag > // Type tag
7179{
7180 return ( m.rows() == 0UL && m.columns() == 0UL );
7181}
7182//*************************************************************************************************
7183
7184
7185//*************************************************************************************************
7203template< typename Type // Data type of the matrix
7204 , size_t M // Number of rows
7205 , size_t N // Number of columns
7206 , bool SO // Storage order
7207 , AlignmentFlag AF // Alignment flag
7208 , PaddingFlag PF // Padding flag
7209 , typename Tag > // Type tag
7210inline bool isIntact( const HybridMatrix<Type,M,N,SO,AF,PF,Tag>& m ) noexcept
7211{
7212 return m.isIntact();
7213}
7214//*************************************************************************************************
7215
7216
7217//*************************************************************************************************
7225template< typename Type // Data type of the matrix
7226 , size_t M // Number of rows
7227 , size_t N // Number of columns
7228 , bool SO // Storage order
7229 , AlignmentFlag AF // Alignment flag
7230 , PaddingFlag PF // Padding flag
7231 , typename Tag > // Type tag
7233{
7234 a.swap( b );
7235}
7236//*************************************************************************************************
7237
7238
7239
7240
7241//=================================================================================================
7242//
7243// MAXSIZE SPECIALIZATIONS
7244//
7245//=================================================================================================
7246
7247//*************************************************************************************************
7249template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7250struct MaxSize< HybridMatrix<T,M,N,SO,AF,PF,Tag>, 0UL >
7251 : public Ptrdiff_t< static_cast<ptrdiff_t>(M) >
7252{};
7253
7254template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7255struct MaxSize< HybridMatrix<T,M,N,SO,AF,PF,Tag>, 1UL >
7256 : public Ptrdiff_t< static_cast<ptrdiff_t>(N) >
7257{};
7259//*************************************************************************************************
7260
7261
7262
7263
7264//=================================================================================================
7265//
7266// HASCONSTDATAACCESS SPECIALIZATIONS
7267//
7268//=================================================================================================
7269
7270//*************************************************************************************************
7272template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7273struct HasConstDataAccess< HybridMatrix<T,M,N,SO,AF,PF,Tag> >
7274 : public TrueType
7275{};
7277//*************************************************************************************************
7278
7279
7280
7281
7282//=================================================================================================
7283//
7284// HASMUTABLEDATAACCESS SPECIALIZATIONS
7285//
7286//=================================================================================================
7287
7288//*************************************************************************************************
7290template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7291struct HasMutableDataAccess< HybridMatrix<T,M,N,SO,AF,PF,Tag> >
7292 : public TrueType
7293{};
7295//*************************************************************************************************
7296
7297
7298
7299
7300//=================================================================================================
7301//
7302// ISALIGNED SPECIALIZATIONS
7303//
7304//=================================================================================================
7305
7306//*************************************************************************************************
7308template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7309struct IsAligned< HybridMatrix<T,M,N,SO,AF,PF,Tag> >
7310 : public BoolConstant< AF == aligned >
7311{};
7313//*************************************************************************************************
7314
7315
7316
7317
7318//=================================================================================================
7319//
7320// ISCONTIGUOUS SPECIALIZATIONS
7321//
7322//=================================================================================================
7323
7324//*************************************************************************************************
7326template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7327struct IsContiguous< HybridMatrix<T,M,N,SO,AF,PF,Tag> >
7328 : public TrueType
7329{};
7331//*************************************************************************************************
7332
7333
7334
7335
7336//=================================================================================================
7337//
7338// ISPADDED SPECIALIZATIONS
7339//
7340//=================================================================================================
7341
7342//*************************************************************************************************
7344template< typename T, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag >
7345struct IsPadded< HybridMatrix<T,M,N,SO,AF,PF,Tag> >
7346 : public BoolConstant< PF == padded >
7347{};
7349//*************************************************************************************************
7350
7351
7352
7353
7354//=================================================================================================
7355//
7356// ADDTRAIT SPECIALIZATIONS
7357//
7358//=================================================================================================
7359
7360//*************************************************************************************************
7362template< typename T1, typename T2 >
7363struct AddTraitEval2< T1, T2
7364 , EnableIf_t< IsMatrix_v<T1> &&
7365 IsMatrix_v<T2> &&
7366 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7367 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7368 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7369 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7370 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ||
7371 MaxSize_v<T2,0UL> != DefaultMaxSize_v ) &&
7372 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ||
7373 MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7374{
7375 static constexpr bool SO1 = StorageOrder_v<T1>;
7376 static constexpr bool SO2 = StorageOrder_v<T2>;
7377
7378 static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
7379 ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7380 ? ( IsSymmetric_v<T1>
7381 ? SO2
7382 : SO1 )
7383 : SO1 && SO2 )
7384 : ( IsDenseMatrix_v<T1>
7385 ? SO1
7386 : SO2 ) );
7387
7388 using Type = HybridMatrix< AddTrait_t< ElementType_t<T1>, ElementType_t<T2> >
7389 , min( size_t( MaxSize_v<T1,0UL> ), size_t( MaxSize_v<T2,0UL> ) )
7390 , min( size_t( MaxSize_v<T1,1UL> ), size_t( MaxSize_v<T2,1UL> ) )
7391 , SO
7394 , AddTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7395};
7397//*************************************************************************************************
7398
7399
7400
7401
7402//=================================================================================================
7403//
7404// SUBTRAIT SPECIALIZATIONS
7405//
7406//=================================================================================================
7407
7408//*************************************************************************************************
7410template< typename T1, typename T2 >
7411struct SubTraitEval2< T1, T2
7412 , EnableIf_t< IsMatrix_v<T1> &&
7413 IsMatrix_v<T2> &&
7414 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7415 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7416 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7417 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7418 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ||
7419 MaxSize_v<T2,0UL> != DefaultMaxSize_v ) &&
7420 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ||
7421 MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7422{
7423 static constexpr bool SO1 = StorageOrder_v<T1>;
7424 static constexpr bool SO2 = StorageOrder_v<T2>;
7425
7426 static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
7427 ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7428 ? ( IsSymmetric_v<T1>
7429 ? SO2
7430 : SO1 )
7431 : SO1 && SO2 )
7432 : ( IsDenseMatrix_v<T1>
7433 ? SO1
7434 : SO2 ) );
7435
7436 using Type = HybridMatrix< SubTrait_t< ElementType_t<T1>, ElementType_t<T2> >
7437 , min( size_t( MaxSize_v<T1,0UL> ), size_t( MaxSize_v<T2,0UL> ) )
7438 , min( size_t( MaxSize_v<T1,1UL> ), size_t( MaxSize_v<T2,1UL> ) )
7439 , SO
7442 , SubTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7443};
7445//*************************************************************************************************
7446
7447
7448
7449
7450//=================================================================================================
7451//
7452// SCHURTRAIT SPECIALIZATIONS
7453//
7454//=================================================================================================
7455
7456//*************************************************************************************************
7458template< typename T1, typename T2 >
7459struct SchurTraitEval2< T1, T2
7460 , EnableIf_t< IsDenseMatrix_v<T1> &&
7461 IsDenseMatrix_v<T2> &&
7462 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7463 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7464 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7465 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7466 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ||
7467 MaxSize_v<T2,0UL> != DefaultMaxSize_v ) &&
7468 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ||
7469 MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7470{
7471 static constexpr bool SO1 = StorageOrder_v<T1>;
7472 static constexpr bool SO2 = StorageOrder_v<T2>;
7473
7474 static constexpr bool SO = ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7475 ? ( IsSymmetric_v<T1>
7476 ? SO2
7477 : SO1 )
7478 : SO1 && SO2 );
7479
7480 using Type = HybridMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
7481 , min( size_t( MaxSize_v<T1,0UL> ), size_t( MaxSize_v<T2,0UL> ) )
7482 , min( size_t( MaxSize_v<T1,1UL> ), size_t( MaxSize_v<T2,1UL> ) )
7483 , SO
7486 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7487};
7489//*************************************************************************************************
7490
7491
7492
7493
7494//=================================================================================================
7495//
7496// MULTTRAIT SPECIALIZATIONS
7497//
7498//=================================================================================================
7499
7500//*************************************************************************************************
7502template< typename T1, typename T2 >
7503struct MultTraitEval2< T1, T2
7504 , EnableIf_t< IsMatrix_v<T1> &&
7505 IsScalar_v<T2> &&
7506 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7507 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7508 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ) &&
7509 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ) > >
7510{
7511 using Type = HybridMatrix< MultTrait_t< ElementType_t<T1>, T2 >
7512 , MaxSize_v<T1,0UL>
7513 , MaxSize_v<T1,1UL>
7514 , StorageOrder_v<T1>
7517 , MultTrait_t< TagType_t<T1>, T2 > >;
7518};
7519
7520template< typename T1, typename T2 >
7521struct MultTraitEval2< T1, T2
7522 , EnableIf_t< IsScalar_v<T1> &&
7523 IsMatrix_v<T2> &&
7524 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7525 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7526 ( MaxSize_v<T2,0UL> != DefaultMaxSize_v ) &&
7527 ( MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7528{
7529 using Type = HybridMatrix< MultTrait_t< T1, ElementType_t<T2> >
7530 , MaxSize_v<T2,0UL>
7531 , MaxSize_v<T2,1UL>
7532 , StorageOrder_v<T2>
7535 , MultTrait_t< T1, TagType_t<T2> > >;
7536};
7537
7538template< typename T1, typename T2 >
7539struct MultTraitEval2< T1, T2
7541 IsRowVector_v<T2> &&
7542 ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
7543 ( Size_v<T2,0UL> == DefaultSize_v ) ) &&
7544 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ) &&
7545 ( MaxSize_v<T2,0UL> != DefaultMaxSize_v ) > >
7546{
7547 using Type = HybridMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
7548 , MaxSize_v<T1,0UL>
7549 , MaxSize_v<T2,0UL>
7550 , false
7553 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7554};
7555
7556template< typename T1, typename T2 >
7557struct MultTraitEval2< T1, T2
7558 , EnableIf_t< IsMatrix_v<T1> &&
7559 IsMatrix_v<T2> &&
7560 ( ( Size_v<T1,0UL> == DefaultSize_v &&
7561 ( !IsSquare_v<T1> || Size_v<T2,0UL> == DefaultSize_v ) ) ||
7562 ( Size_v<T2,1UL> == DefaultSize_v &&
7563 ( !IsSquare_v<T2> || Size_v<T1,1UL> == DefaultSize_v ) ) ) &&
7564 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ||
7565 ( IsSquare_v<T1> && MaxSize_v<T2,0UL> != DefaultMaxSize_v ) ) &&
7566 ( MaxSize_v<T2,1UL> != DefaultMaxSize_v ||
7567 ( IsSquare_v<T2> && MaxSize_v<T1,1UL> != DefaultMaxSize_v ) ) > >
7568{
7569 using MultType = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7570 using MultTag = MultTrait_t< TagType_t<T1>, TagType_t<T2> >;
7571
7572 using Type = HybridMatrix< AddTrait_t<MultType,MultType>
7573 , ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ? MaxSize_v<T1,0UL> : MaxSize_v<T2,0UL> )
7574 , ( MaxSize_v<T2,1UL> != DefaultMaxSize_v ? MaxSize_v<T2,1UL> : MaxSize_v<T1,1UL> )
7575 , ( IsSparseMatrix_v<T1> ? StorageOrder_v<T2> : StorageOrder_v<T1> )
7578 , AddTrait_t<MultTag,MultTag> >;
7579};
7581//*************************************************************************************************
7582
7583
7584
7585
7586//=================================================================================================
7587//
7588// KRONTRAIT SPECIALIZATIONS
7589//
7590//=================================================================================================
7591
7592//*************************************************************************************************
7594template< typename T1, typename T2 >
7595struct KronTraitEval2< T1, T2
7596 , EnableIf_t< IsDenseMatrix_v<T1> &&
7597 IsDenseMatrix_v<T2> &&
7598 ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
7599 ( Size_v<T2,0UL> == DefaultSize_v ) ||
7600 ( Size_v<T1,1UL> == DefaultSize_v ) ||
7601 ( Size_v<T2,1UL> == DefaultSize_v ) ) &&
7602 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ) &&
7603 ( MaxSize_v<T2,0UL> != DefaultMaxSize_v ) &&
7604 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ) &&
7605 ( MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7606{
7607 using Type = HybridMatrix< MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >
7608 , MaxSize_v<T1,0UL> * MaxSize_v<T2,0UL>
7609 , MaxSize_v<T1,1UL> * MaxSize_v<T2,1UL>
7610 , StorageOrder_v<T2>
7613 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7614};
7616//*************************************************************************************************
7617
7618
7619
7620
7621//=================================================================================================
7622//
7623// DIVTRAIT SPECIALIZATIONS
7624//
7625//=================================================================================================
7626
7627//*************************************************************************************************
7629template< typename T1, typename T2 >
7630struct DivTraitEval2< T1, T2
7631 , EnableIf_t< IsMatrix_v<T1> &&
7632 IsScalar_v<T2> &&
7633 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7634 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7635 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ) &&
7636 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ) > >
7637{
7638 using Type = HybridMatrix< DivTrait_t< ElementType_t<T1>, T2 >
7639 , MaxSize_v<T1,0UL>
7640 , MaxSize_v<T1,1UL>
7641 , StorageOrder_v<T1>
7644 , DivTrait_t< TagType_t<T1>, T2 > >;
7645};
7647//*************************************************************************************************
7648
7649
7650
7651
7652//=================================================================================================
7653//
7654// MAPTRAIT SPECIALIZATIONS
7655//
7656//=================================================================================================
7657
7658//*************************************************************************************************
7660template< typename T, typename OP >
7661struct UnaryMapTraitEval2< T, OP
7662 , EnableIf_t< IsMatrix_v<T> &&
7663 ( Size_v<T,0UL> == DefaultSize_v ||
7664 Size_v<T,1UL> == DefaultSize_v ) &&
7665 MaxSize_v<T,0UL> != DefaultMaxSize_v &&
7666 MaxSize_v<T,1UL> != DefaultMaxSize_v > >
7667{
7668 using ElementType = decltype( std::declval<OP>()( std::declval< ElementType_t<T> >() ) );
7669
7670 using Type = HybridMatrix< EvaluateTrait_t<ElementType>
7671 , MaxSize_v<T,0UL>
7672 , MaxSize_v<T,1UL>
7673 , StorageOrder_v<T>
7676 , MapTrait_t< TagType_t<T>, OP > >;
7677};
7679//*************************************************************************************************
7680
7681
7682//*************************************************************************************************
7684template< typename T1, typename T2, typename OP >
7685struct BinaryMapTraitEval2< T1, T2, OP
7687 IsRowVector_v<T2> &&
7688 ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
7689 ( Size_v<T2,0UL> == DefaultSize_v ) ) &&
7690 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ) &&
7691 ( MaxSize_v<T2,0UL> != DefaultMaxSize_v ) > >
7692{
7693 using ElementType = decltype( std::declval<OP>()( std::declval< ElementType_t<T1> >()
7694 , std::declval< ElementType_t<T2> >() ) );
7695
7696 using Type = HybridMatrix< EvaluateTrait_t<ElementType>
7697 , MaxSize_v<T1,0UL>
7698 , MaxSize_v<T2,0UL>
7699 , false
7702 , MapTrait_t< TagType_t<T1>, TagType_t<T2>, OP > >;
7703};
7704
7705template< typename T1, typename T2, typename OP >
7706struct BinaryMapTraitEval2< T1, T2, OP
7707 , EnableIf_t< IsMatrix_v<T1> &&
7708 IsMatrix_v<T2> &&
7709 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7710 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7711 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7712 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7713 ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ||
7714 MaxSize_v<T2,0UL> != DefaultMaxSize_v ) &&
7715 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ||
7716 MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7717{
7718 using ElementType = decltype( std::declval<OP>()( std::declval< ElementType_t<T1> >()
7719 , std::declval< ElementType_t<T2> >() ) );
7720
7721 static constexpr bool SO1 = StorageOrder_v<T1>;
7722 static constexpr bool SO2 = StorageOrder_v<T2>;
7723
7724 static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
7725 ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7726 ? ( IsSymmetric_v<T1>
7727 ? SO2
7728 : SO1 )
7729 : SO1 && SO2 )
7730 : ( IsDenseMatrix_v<T1>
7731 ? SO1
7732 : SO2 ) );
7733
7734 using Type = HybridMatrix< EvaluateTrait_t<ElementType>
7735 , min( size_t( MaxSize_v<T1,0UL> ), size_t( MaxSize_v<T2,0UL> ) )
7736 , min( size_t( MaxSize_v<T1,1UL> ), size_t( MaxSize_v<T2,1UL> ) )
7737 , SO
7740 , MapTrait_t< TagType_t<T1>, TagType_t<T2>, OP > >;
7741};
7743//*************************************************************************************************
7744
7745
7746
7747
7748//=================================================================================================
7749//
7750// EXPANDTRAIT SPECIALIZATIONS
7751//
7752//=================================================================================================
7753
7754//*************************************************************************************************
7756template< typename T, size_t E >
7757struct ExpandTraitEval2< T, E
7759 ( E != inf ) &&
7760 ( Size_v<T,0UL> == DefaultSize_v ) &&
7761 ( MaxSize_v<T,0UL> != DefaultMaxSize_v ) > >
7762{
7763 using Type = HybridMatrix< ElementType_t<T>
7764 , ( IsColumnVector_v<T> ? MaxSize_v<T,0UL> : E )
7765 , ( IsColumnVector_v<T> ? E : MaxSize_v<T,0UL> )
7766 , ( IsColumnVector_v<T> ? columnMajor : rowMajor )
7769 , TagType_t<T> >;
7770};
7772//*************************************************************************************************
7773
7774
7775
7776
7777//=================================================================================================
7778//
7779// REPEATTRAIT SPECIALIZATIONS
7780//
7781//=================================================================================================
7782
7783//*************************************************************************************************
7785template< typename T, size_t R0, size_t R1 >
7786struct RepeatTraitEval2< T, R0, R1, inf
7788 ( R0 != inf ) &&
7789 ( R1 != inf ) &&
7790 ( Size_v<T,0UL> == DefaultSize_v ||
7791 Size_v<T,1UL> == DefaultSize_v ) &&
7792 ( MaxSize_v<T,0UL> != DefaultMaxSize_v ) &&
7793 ( MaxSize_v<T,1UL> != DefaultMaxSize_v ) > >
7794{
7795 using Type = HybridMatrix< ElementType_t<T>
7796 , R0*MaxSize_v<T,0UL>
7797 , R1*MaxSize_v<T,1UL>
7798 , StorageOrder_v<T>
7801 , TagType_t<T> >;
7802};
7804//*************************************************************************************************
7805
7806
7807
7808
7809//=================================================================================================
7810//
7811// SOLVETRAIT SPECIALIZATIONS
7812//
7813//=================================================================================================
7814
7815//*************************************************************************************************
7817template< typename T1, typename T2 >
7818struct SolveTraitEval2< T1, T2
7819 , EnableIf_t< IsDenseMatrix_v<T1> &&
7820 IsDenseMatrix_v<T2> &&
7821 ( ( ( Size_v<T1,0UL> == DefaultSize_v ) &&
7822 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7823 ( Size_v<T2,0UL> == DefaultSize_v ) ) ||
7824 ( Size_v<T2,1UL> == DefaultSize_v ) ) &&
7825 ( ( MaxSize_v<T1,0UL> != DefaultMaxSize_v ) ||
7826 ( MaxSize_v<T1,1UL> != DefaultMaxSize_v ) ||
7827 ( MaxSize_v<T2,0UL> != DefaultMaxSize_v ) ) &&
7828 ( MaxSize_v<T2,1UL> != DefaultMaxSize_v ) > >
7829{
7830 static constexpr size_t M = ( MaxSize_v<T1,0UL> != DefaultMaxSize_v
7831 ?( MaxSize_v<T1,1UL> != DefaultMaxSize_v
7832 ?( MaxSize_v<T2,0UL> != DefaultMaxSize_v
7833 ? min( MaxSize_v<T1,0UL>, MaxSize_v<T1,1UL>, MaxSize_v<T2,0UL> )
7834 : min( MaxSize_v<T1,0UL>, MaxSize_v<T1,1UL> ) )
7835 :( MaxSize_v<T2,0UL> != DefaultMaxSize_v
7836 ? min( MaxSize_v<T1,0UL>, MaxSize_v<T2,0UL> )
7837 : MaxSize_v<T1,0UL> ) )
7838 :( MaxSize_v<T1,1UL> != DefaultMaxSize_v
7839 ?( MaxSize_v<T2,0UL> != DefaultMaxSize_v
7840 ? min( MaxSize_v<T1,1UL>, MaxSize_v<T2,0UL> )
7841 : MaxSize_v<T1,1UL> )
7842 : MaxSize_v<T2,0UL> ) );
7843
7844 using Type = HybridMatrix< ElementType_t<T2>
7845 , M
7846 , MaxSize_v<T2,1UL>
7847 , StorageOrder_v<T2>
7850 , TagType_t<T2> >;
7851};
7853//*************************************************************************************************
7854
7855
7856
7857
7858//=================================================================================================
7859//
7860// HIGHTYPE SPECIALIZATIONS
7861//
7862//=================================================================================================
7863
7864//*************************************************************************************************
7866template< typename T1, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag, typename T2 >
7867struct HighType< HybridMatrix<T1,M,N,SO,AF,PF,Tag>, HybridMatrix<T2,M,N,SO,AF,PF,Tag> >
7868{
7869 using Type = HybridMatrix< typename HighType<T1,T2>::Type, M, N, SO, AF, PF, Tag >;
7870};
7872//*************************************************************************************************
7873
7874
7875
7876
7877//=================================================================================================
7878//
7879// LOWTYPE SPECIALIZATIONS
7880//
7881//=================================================================================================
7882
7883//*************************************************************************************************
7885template< typename T1, size_t M, size_t N, bool SO, AlignmentFlag AF, PaddingFlag PF, typename Tag, typename T2 >
7886struct LowType< HybridMatrix<T1,M,N,SO,AF,PF,Tag>, HybridMatrix<T2,M,N,SO,AF,PF,Tag> >
7887{
7888 using Type = HybridMatrix< typename LowType<T1,T2>::Type, M, N, SO, AF, PF, Tag >;
7889};
7891//*************************************************************************************************
7892
7893
7894
7895
7896//=================================================================================================
7897//
7898// SUBMATRIXTRAIT SPECIALIZATIONS
7899//
7900//=================================================================================================
7901
7902//*************************************************************************************************
7904template< typename MT >
7905struct SubmatrixTraitEval2< MT, inf, inf, inf, inf
7906 , EnableIf_t< IsDenseMatrix_v<MT> &&
7907 ( ( Size_v<MT,0UL> != DefaultSize_v &&
7908 Size_v<MT,1UL> != DefaultSize_v ) ||
7909 ( MaxSize_v<MT,0UL> != DefaultMaxSize_v &&
7910 MaxSize_v<MT,1UL> != DefaultMaxSize_v ) ) > >
7911{
7912 using Type = HybridMatrix< RemoveConst_t< ElementType_t<MT> >
7913 , max( Size_v<MT,0UL>, MaxSize_v<MT,0UL> )
7914 , max( Size_v<MT,1UL>, MaxSize_v<MT,1UL> )
7915 , StorageOrder_v<MT>
7918 , TagType_t<MT> >;
7919};
7921//*************************************************************************************************
7922
7923
7924
7925
7926//=================================================================================================
7927//
7928// ROWSTRAIT SPECIALIZATIONS
7929//
7930//=================================================================================================
7931
7932//*************************************************************************************************
7934template< typename MT, size_t M >
7935struct RowsTraitEval2< MT, M
7936 , EnableIf_t< M != 0UL &&
7937 IsDenseMatrix_v<MT> &&
7938 Size_v<MT,1UL> == DefaultSize_v &&
7939 MaxSize_v<MT,1UL> != DefaultMaxSize_v > >
7940{
7941 using Type = HybridMatrix< RemoveConst_t< ElementType_t<MT> >
7942 , M
7943 , MaxSize_v<MT,1UL>
7944 , false
7947 , TagType_t<MT> >;
7948};
7950//*************************************************************************************************
7951
7952
7953
7954
7955//=================================================================================================
7956//
7957// COLUMNSTRAIT SPECIALIZATIONS
7958//
7959//=================================================================================================
7960
7961//*************************************************************************************************
7963template< typename MT, size_t N >
7964struct ColumnsTraitEval2< MT, N
7965 , EnableIf_t< N != 0UL &&
7966 IsDenseMatrix_v<MT> &&
7967 Size_v<MT,0UL> == DefaultSize_v &&
7968 MaxSize_v<MT,0UL> != DefaultMaxSize_v > >
7969{
7970 using Type = HybridMatrix< RemoveConst_t< ElementType_t<MT> >
7971 , MaxSize_v<MT,0UL>
7972 , N
7973 , true
7976 , TagType_t<MT> >;
7977};
7979//*************************************************************************************************
7980
7981} // namespace blaze
7982
7983#endif
Header file for the addition trait.
Header file for auxiliary alias declarations.
typename ResultType_t< T >::TagType TagType_t
Alias declaration for nested TagType type definitions.
Definition: Aliases.h:530
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for the AlignedArray implementation.
Header file for the alignment check function.
Header file for the alignment flag enumeration.
Header file for the AlignmentOf type trait.
Header file for run time assertion macros.
Header file for the columns trait.
Header file for the conjugate shim.
Constraint on the data type.
Header file for the DenseIterator class template.
Constraint on the data type.
Header file for the division trait.
Header file for the EnableIf class template.
Header file for the EvaluateTrait class template.
Header file for the expand trait.
Constraint on the data type.
Header file for the HasConstDataAccess type trait.
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.
Header file for the HighType type trait.
Header file for the IntegralConstant class template.
Header file for the IsAligned type trait.
Header file for the IsColumnMajorMatrix type trait.
Header file for the IsColumnVector type trait.
Header file for the IsContiguous type trait.
Header file for the isDefault shim.
Header file for the IsDenseMatrix type trait.
Header file for the IsDenseVector type trait.
Header file for the IsDiagonal type trait.
Header file for the IsLower type trait.
Header file for the IsMatrix type trait.
Header file for the IsNumeric type trait.
Header file for the IsPadded type trait.
Header file for the IsRowMajorMatrix type trait.
Header file for the IsRowVector type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSame and IsStrictlySame type traits.
Header file for the IsScalar type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsSquare type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsUpper type trait.
Header file for the IsVectorizable type trait.
Header file for the Kron product trait.
Header file for the LowType type trait.
Header file for the map trait.
Header file for the MaxSize type trait.
Header file for the MAYBE_UNUSED function template.
Header file for memory allocation and deallocation functionality.
Header file for the multiplication trait.
Header file for the nextMultiple shim.
Header file for the padding flag enumeration.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Header file for the relaxation flag enumeration.
Header file for the RemoveCV type trait.
Header file for the RemoveConst type trait.
Header file for the repeat trait.
Header file for the rows trait.
Header file for all SIMD functionality.
Data type constraint.
Header file for the Schur product trait.
Header file for the Solver trait.
Compile time assertion.
Header file for the subtraction trait.
Header file for the submatrix trait.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Implementation of a generic iterator for dense vectors and matrices.
Definition: DenseIterator.h:60
Base class for dense matrices.
Definition: DenseMatrix.h:82
Efficient implementation of a dynamically sized matrix with static memory.
Definition: HybridMatrix.h:256
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2874
constexpr size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: HybridMatrix.h:1932
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: HybridMatrix.h:311
static constexpr size_t Alignment
Alignment of the data elements.
Definition: HybridMatrix.h:556
void swap(HybridMatrix &m) noexcept
Swapping the contents of two hybrid matrices.
Definition: HybridMatrix.h:2265
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:576
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: HybridMatrix.h:317
HybridMatrix< Type, M, N,!SO, AF, PF, Tag > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: HybridMatrix.h:266
SIMDTrait_t< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: HybridMatrix.h:272
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: HybridMatrix.h:2913
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:577
constexpr void reset()
Reset to the default initial values.
Definition: HybridMatrix.h:2086
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: HybridMatrix.h:1155
static constexpr size_t NN
Alignment adjustment.
Definition: HybridMatrix.h:442
constexpr ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1375
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:280
static constexpr size_t capacity() noexcept
Returns the maximum capacity of the matrix.
Definition: HybridMatrix.h:1973
constexpr void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: HybridMatrix.h:2190
auto schurAssign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedSchurAssign_v< MT > >
Default implementation of the Schur product assignment of a dense matrix.
Definition: HybridMatrix.h:3544
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2801
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the matrix.
Definition: HybridMatrix.h:2988
Type ElementType
Type of the matrix elements.
Definition: HybridMatrix.h:271
constexpr void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: HybridMatrix.h:2244
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2834
auto assign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedAssign_v< MT > >
Default implementation of the assignment of a dense matrix.
Definition: HybridMatrix.h:3065
Type * Pointer
Pointer to a non-constant matrix value.
Definition: HybridMatrix.h:279
constexpr Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1402
const This & CompositeType
Data type for composite expression templates.
Definition: HybridMatrix.h:275
constexpr ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1456
HybridMatrix & transpose()
In-place transpose of the matrix.
Definition: HybridMatrix.h:2310
HybridMatrix< Type, M, N, SO, AF, PF, Tag > This
Type of this HybridMatrix instance.
Definition: HybridMatrix.h:260
constexpr Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: HybridMatrix.h:1220
auto subAssign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedSubAssign_v< MT > >
Default implementation of the subtraction assignment of a dense matrix.
Definition: HybridMatrix.h:3376
constexpr Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1321
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: HybridMatrix.h:439
constexpr void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:2140
AlignedArray< Type, M *NN, Alignment > AlignedStorage
Type of the aligned storage.
Definition: HybridMatrix.h:560
constexpr size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: HybridMatrix.h:1913
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: HybridMatrix.h:282
constexpr Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: HybridMatrix.h:1100
constexpr HybridMatrix & operator=(const Type &set) &
Homogenous assignment to all matrix elements.
Definition: HybridMatrix.h:1486
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: HybridMatrix.h:283
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2748
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:277
static constexpr bool isAligned() noexcept
Returns whether the matrix is properly aligned in memory.
Definition: HybridMatrix.h:2771
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const SIMDType &value) noexcept
Aligned store of a SIMD element of the matrix.
Definition: HybridMatrix.h:2947
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: HybridMatrix.h:2723
auto addAssign(const DenseMatrix< MT, SO2 > &rhs) -> DisableIf_t< VectorizedAddAssign_v< MT > >
Default implementation of the addition assignment of a row-major dense matrix.
Definition: HybridMatrix.h:3208
Tag TagType
Tag type of this StaticMatrix instance.
Definition: HybridMatrix.h:273
DenseMatrix< This, SO > BaseType
Base type of this HybridMatrix instance.
Definition: HybridMatrix.h:262
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:2025
This ResultType
Result type for expression template evaluations.
Definition: HybridMatrix.h:263
constexpr HybridMatrix()
The default constructor for HybridMatrix.
Definition: HybridMatrix.h:638
HybridMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: HybridMatrix.h:2369
AlignedStorage v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:566
const Type & ConstReference
Reference to a constant matrix value.
Definition: HybridMatrix.h:278
BLAZE_ALWAYS_INLINE void stream(size_t i, size_t j, const SIMDType &value) noexcept
Aligned, non-temporal store of a SIMD element of the matrix.
Definition: HybridMatrix.h:3028
constexpr bool isIntact() const noexcept
Returns whether the invariants of the hybrid matrix are intact.
Definition: HybridMatrix.h:2670
HybridMatrix< Type, N, M,!SO, AF, PF, Tag > TransposeType
Transpose type for expression template evaluations.
Definition: HybridMatrix.h:269
const Type & ReturnType
Return type for expression template evaluations.
Definition: HybridMatrix.h:274
static constexpr size_t spacing() noexcept
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1954
Base class for matrices.
Definition: Matrix.h:85
SIMD characteristics of data types.
Definition: SIMDTrait.h:297
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Initializer list type of the Blaze library.
Header file for the DenseMatrix base class.
Header file for the SparseMatrix base class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#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_CONST(T)
Constraint on the data type.
Definition: Const.h:79
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TAG(A, B)
Data type constraint.
Definition: SameTag.h:68
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1339
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
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
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
decltype(auto) inv(const DenseMatrix< MT, SO > &dm)
Calculation of the inverse of the given dense matrix.
Definition: DMatInvExpr.h:405
bool isDefault(const HybridMatrix< Type, M, N, SO, AF, PF, Tag > &m)
Returns whether the given hybrid matrix is in default state.
Definition: HybridMatrix.h:7178
void swap(HybridMatrix< Type, M, N, SO, AF, PF, Tag > &a, HybridMatrix< Type, M, N, SO, AF, PF, Tag > &b) noexcept
Swapping the contents of two hybrid matrices.
Definition: HybridMatrix.h:7232
bool isIntact(const HybridMatrix< Type, M, N, SO, AF, PF, Tag > &m) noexcept
Returns whether the invariants of the given hybrid matrix are intact.
Definition: HybridMatrix.h:7210
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Diagonal.h:79
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric_v< T >)
Swapping two conjugated values/objects.
Definition: Conjugate.h:193
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:118
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr ptrdiff_t DefaultMaxSize_v
Default size of the MaxSize type trait.
Definition: MaxSize.h:72
constexpr ptrdiff_t MaxSize_v
Auxiliary variable template for the MaxSize type trait.
Definition: MaxSize.h:175
constexpr bool IsScalar_v
Auxiliary variable template for the IsScalar type trait.
Definition: IsScalar.h:104
constexpr bool IsRowMajorMatrix_v
Auxiliary variable template for the IsRowMajorMatrix type trait.
Definition: IsRowMajorMatrix.h:129
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr ptrdiff_t DefaultSize_v
Default size of the Size type trait.
Definition: Size.h:72
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.
Definition: IsDiagonal.h:148
constexpr bool IsColumnMajorMatrix_v
Auxiliary variable template for the IsColumnMajorMatrix type trait.
Definition: IsColumnMajorMatrix.h:129
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.
Definition: IsMatrix.h:124
constexpr bool IsColumnVector_v
Auxiliary variable template for the IsColumnVector type trait.
Definition: IsColumnVector.h:126
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
constexpr bool IsDenseMatrix_v
Auxiliary variable template for the IsDenseMatrix type trait.
Definition: IsDenseMatrix.h:124
constexpr bool IsDenseVector_v
Auxiliary variable template for the IsDenseVector type trait.
Definition: IsDenseVector.h:124
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
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 Infinity inf
Global Infinity instance.
Definition: Infinity.h:1080
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:107
BLAZE_ALWAYS_INLINE constexpr auto nextMultiple(T1 value, T2 factor) noexcept
Rounds up an integral value to the next multiple of a given factor.
Definition: NextMultiple.h:68
PaddingFlag
Padding flag for (un-)padded vectors and matrices.
Definition: PaddingFlag.h:77
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.
Definition: AlignmentFlag.h:63
@ padded
Flag for padded vectors and matrices.
Definition: PaddingFlag.h:79
@ unpadded
Flag for unpadded vectors and matrices.
Definition: PaddingFlag.h:78
@ unaligned
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
@ aligned
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
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
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
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
#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 const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.
Definition: SIMDTrait.h:315
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
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.
Definition: StaticAssert.h:112
constexpr PaddingFlag defaultPaddingFlag
The default padding flag for all vectors and matrices of the Blaze library.
Definition: Padding.h:74
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
constexpr AlignmentFlag defaultAlignmentFlag
The default alignment for all vectors and matrices of the Blaze library.
Definition: Alignment.h:75
constexpr bool IsVectorizable_v
Auxiliary variable template for the IsVectorizable type trait.
Definition: IsVectorizable.h:157
constexpr size_t AlignmentOf_v
Auxiliary variable template for the AlignmentOf type trait.
Definition: AlignmentOf.h:239
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
void deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
IntegralConstant< ptrdiff_t, N > Ptrdiff_t
Compile time integral constant wrapper for ptrdiff_t.
Definition: IntegralConstant.h:237
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
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.
Definition: IntegralConstant.h:110
#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
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
#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
Header file for the exception macros of the math module.
Header file for all forward declarations of the math module.
Header file for the extended initializer_list functionality.
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Header file for all forward declarations for dense vectors and matrices.
Header file for the Size type trait.
Header file for the StorageOrder type trait.
Header file for the clear shim.
Header file for the serial shim.
Rebind mechanism to obtain a HybridMatrix with different data/element type.
Definition: HybridMatrix.h:290
HybridMatrix< NewType, M, N, SO, AF, PF, Tag > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:291
Resize mechanism to obtain a HybridMatrix with different fixed dimensions.
Definition: HybridMatrix.h:300
HybridMatrix< Type, NewM, NewN, SO, AF, PF, Tag > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:301
Header file for the default alignment for all vectors and matrices of the Blaze library.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the default padding flag for all vectors and matrices of the Blaze library.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.