Blaze 3.9
CustomMatrix.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_DENSE_CUSTOMMATRIX_H_
36#define _BLAZE_MATH_DENSE_CUSTOMMATRIX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <array>
44#include <algorithm>
45#include <utility>
46#include <blaze/math/Aliases.h>
59#include <blaze/math/Forward.h>
71#include <blaze/math/SIMD.h>
93#include <blaze/system/Inline.h>
98#include <blaze/util/Assert.h>
105#include <blaze/util/EnableIf.h>
109#include <blaze/util/mpl/If.h>
110#include <blaze/util/Types.h>
115
116
117namespace blaze {
118
119//=================================================================================================
120//
121// CLASS DEFINITION
122//
123//=================================================================================================
124
125//*************************************************************************************************
415template< typename Type // Data type of the matrix
416 , AlignmentFlag AF // Alignment flag
417 , PaddingFlag PF // Padding flag
418 , bool SO // Storage order
419 , typename Tag // Type tag
420 , typename RT > // Result type
422 : public DenseMatrix< CustomMatrix<Type,AF,PF,SO,Tag,RT>, SO >
423{
424 public:
425 //**Type definitions****************************************************************************
428
430 using ResultType = RT;
431
434
437
438 using ElementType = Type;
440 using TagType = Tag;
441 using ReturnType = const Type&;
442 using CompositeType = const This&;
443
444 using Reference = Type&;
445 using ConstReference = const Type&;
446 using Pointer = Type*;
447 using ConstPointer = const Type*;
448
451 //**********************************************************************************************
452
453 //**Rebind struct definition********************************************************************
456 template< typename NewType > // Data type of the other matrix
457 struct Rebind {
460 };
461 //**********************************************************************************************
462
463 //**Resize struct definition********************************************************************
466 template< size_t NewM // Number of rows of the other matrix
467 , size_t NewN > // Number of columns of the other matrix
468 struct Resize {
471 };
472 //**********************************************************************************************
473
474 //**Compilation flags***************************************************************************
476
480 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
481
483
486 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
487 //**********************************************************************************************
488
489 //**Constructors********************************************************************************
492 inline CustomMatrix();
493 inline CustomMatrix( Type* ptr, size_t m, size_t n );
494 inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn );
495 inline CustomMatrix( const CustomMatrix& m );
496 inline CustomMatrix( CustomMatrix&& m ) noexcept;
498 //**********************************************************************************************
499
500 //**Destructor**********************************************************************************
503 inline ~CustomMatrix();
505 //**********************************************************************************************
506
507 //**Data access functions***********************************************************************
510 inline Reference operator()( size_t i, size_t j ) noexcept;
511 inline ConstReference operator()( size_t i, size_t j ) const noexcept;
512 inline Reference at( size_t i, size_t j );
513 inline ConstReference at( size_t i, size_t j ) const;
514 inline Pointer data () noexcept;
515 inline ConstPointer data () const noexcept;
516 inline Pointer data ( size_t i ) noexcept;
517 inline ConstPointer data ( size_t i ) const noexcept;
518 inline Iterator begin ( size_t i ) noexcept;
519 inline ConstIterator begin ( size_t i ) const noexcept;
520 inline ConstIterator cbegin( size_t i ) const noexcept;
521 inline Iterator end ( size_t i ) noexcept;
522 inline ConstIterator end ( size_t i ) const noexcept;
523 inline ConstIterator cend ( size_t i ) const noexcept;
525 //**********************************************************************************************
526
527 //**Assignment operators************************************************************************
530 inline CustomMatrix& operator=( const Type& set );
531 inline CustomMatrix& operator=( initializer_list< initializer_list<Type> > list );
532
533 template< typename Other, size_t Rows, size_t Cols >
534 inline CustomMatrix& operator=( const Other (&array)[Rows][Cols] );
535
536 template< typename Other, size_t Rows, size_t Cols >
537 inline CustomMatrix& operator=( const std::array<std::array<Other,Cols>,Rows>& array );
538
539 inline CustomMatrix& operator=( const CustomMatrix& rhs );
540 inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
541
542 template< typename MT, bool SO2 > inline CustomMatrix& operator= ( const Matrix<MT,SO2>& rhs );
543 template< typename MT, bool SO2 > inline CustomMatrix& operator+=( const Matrix<MT,SO2>& rhs );
544 template< typename MT, bool SO2 > inline CustomMatrix& operator-=( const Matrix<MT,SO2>& rhs );
545 template< typename MT, bool SO2 > inline CustomMatrix& operator%=( const Matrix<MT,SO2>& rhs );
547 //**********************************************************************************************
548
549 //**Utility functions***************************************************************************
552 inline size_t rows() const noexcept;
553 inline size_t columns() const noexcept;
554 inline size_t spacing() const noexcept;
555 inline size_t capacity() const noexcept;
556 inline size_t capacity( size_t i ) const noexcept;
557 inline size_t nonZeros() const;
558 inline size_t nonZeros( size_t i ) const;
559 inline void reset();
560 inline void reset( size_t i );
561 inline void clear();
562 inline void swap( CustomMatrix& m ) noexcept;
564 //**********************************************************************************************
565
566 //**Numeric functions***************************************************************************
569 inline CustomMatrix& transpose();
570 inline CustomMatrix& ctranspose();
571
572 template< typename Other > inline CustomMatrix& scale( const Other& scalar );
574 //**********************************************************************************************
575
576 //**Resource management functions***************************************************************
579 inline void reset( Type* ptr, size_t m, size_t n );
580 inline void reset( Type* ptr, size_t m, size_t n, size_t nn );
582 //**********************************************************************************************
583
584 private:
585 //**********************************************************************************************
587
588 template< typename MT >
589 static constexpr bool VectorizedAssign_v =
590 ( useOptimizedKernels &&
591 simdEnabled && MT::simdEnabled &&
592 IsSIMDCombinable_v< Type, ElementType_t<MT> > );
594 //**********************************************************************************************
595
596 //**********************************************************************************************
598
599 template< typename MT >
600 static constexpr bool VectorizedAddAssign_v =
601 ( VectorizedAssign_v<MT> &&
602 HasSIMDAdd_v< Type, ElementType_t<MT> > &&
603 !IsDiagonal_v<MT> );
605 //**********************************************************************************************
606
607 //**********************************************************************************************
609
610 template< typename MT >
611 static constexpr bool VectorizedSubAssign_v =
612 ( VectorizedAssign_v<MT> &&
613 HasSIMDSub_v< Type, ElementType_t<MT> > &&
614 !IsDiagonal_v<MT> );
616 //**********************************************************************************************
617
618 //**********************************************************************************************
620
621 template< typename MT >
622 static constexpr bool VectorizedSchurAssign_v =
623 ( VectorizedAssign_v<MT> &&
624 HasSIMDMult_v< Type, ElementType_t<MT> > );
626 //**********************************************************************************************
627
628 //**SIMD properties*****************************************************************************
630 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
631 //**********************************************************************************************
632
633 public:
634 //**Expression template evaluation functions****************************************************
637 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
638 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
639
640 inline bool isAligned () const noexcept;
641 inline bool canSMPAssign() const noexcept;
642
643 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
644 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
645 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
646
647 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
648 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
649 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
650 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
651
652 template< typename MT >
653 inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
654
655 template< typename MT >
656 inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
657
658 template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
659 template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
660 template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
661
662 template< typename MT >
663 inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
664
665 template< typename MT >
666 inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
667
668 template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
669 template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
670 template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
671
672 template< typename MT >
673 inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
674
675 template< typename MT >
676 inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
677
678 template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
679 template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
680 template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
681
682 template< typename MT >
683 inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
684
685 template< typename MT >
686 inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
687
688 template< typename MT > inline void schurAssign( const DenseMatrix<MT,!SO>& rhs );
689 template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
690 template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
692 //**********************************************************************************************
693
694 private:
695 //**Member variables****************************************************************************
698 size_t m_;
699 size_t n_;
700 size_t nn_;
701 Type* v_;
712 //**********************************************************************************************
713
714 //**Compile time checks*************************************************************************
720 //**********************************************************************************************
721};
722//*************************************************************************************************
723
724
725
726
727//=================================================================================================
728//
729// CONSTRUCTORS
730//
731//=================================================================================================
732
733//*************************************************************************************************
736template< typename Type // Data type of the matrix
737 , AlignmentFlag AF // Alignment flag
738 , PaddingFlag PF // Padding flag
739 , bool SO // Storage order
740 , typename Tag // Type tag
741 , typename RT > // Result type
742inline CustomMatrix<Type,AF,PF,SO,Tag,RT>::CustomMatrix()
743 : m_ ( 0UL ) // The current number of rows of the matrix
744 , n_ ( 0UL ) // The current number of columns of the matrix
745 , nn_( 0UL ) // The number of elements between two rows
746 , v_ ( nullptr ) // The custom array of elements
747{}
748//*************************************************************************************************
749
750
751//*************************************************************************************************
771template< typename Type // Data type of the matrix
772 , AlignmentFlag AF // Alignment flag
773 , PaddingFlag PF // Padding flag
774 , bool SO // Storage order
775 , typename Tag // Type tag
776 , typename RT > // Result type
777inline CustomMatrix<Type,AF,PF,SO,Tag,RT>::CustomMatrix( Type* ptr, size_t m, size_t n )
778 : m_ ( m ) // The current number of rows of the matrix
779 , n_ ( n ) // The current number of columns of the matrix
780 , nn_( n ) // The number of elements between two rows
781 , v_ ( ptr ) // The custom array of elements
782{
784
785 if( ptr == nullptr ) {
786 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
787 }
788
789 if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
790 BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
791 }
792}
793//*************************************************************************************************
794
795
796//*************************************************************************************************
818template< typename Type // Data type of the matrix
819 , AlignmentFlag AF // Alignment flag
820 , PaddingFlag PF // Padding flag
821 , bool SO // Storage order
822 , typename Tag // Type tag
823 , typename RT > // Result type
824inline CustomMatrix<Type,AF,PF,SO,Tag,RT>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t nn )
825 : m_ ( m ) // The current number of rows of the matrix
826 , n_ ( n ) // The current number of columns of the matrix
827 , nn_( nn ) // The number of elements between two rows
828 , v_ ( ptr ) // The custom array of elements
829{
830 using blaze::clear;
831
832 using ClearFunctor = If_t< PF || !IsConst_v<Type>, Clear, Noop >;
833
834 if( ptr == nullptr ) {
835 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
836 }
837
838 if( AF && ( !checkAlignment( ptr ) || nn_ % SIMDSIZE != 0UL ) ) {
839 BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
840 }
841
842 if( PF && IsVectorizable_v<Type> && ( nn_ < nextMultiple<size_t>( n_, SIMDSIZE ) ) ) {
843 BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
844 }
845
846 if( PF && IsVectorizable_v<Type> ) {
847 ClearFunctor clear;
848 for( size_t i=0UL; i<m_; ++i ) {
849 for( size_t j=n_; j<nn_; ++j )
850 clear( v_[i*nn_+j] );
851 }
852 }
853}
854//*************************************************************************************************
855
856
857//*************************************************************************************************
864template< typename Type // Data type of the matrix
865 , AlignmentFlag AF // Alignment flag
866 , PaddingFlag PF // Padding flag
867 , bool SO // Storage order
868 , typename Tag // Type tag
869 , typename RT > // Result type
871 : m_ ( m.m_ ) // The current number of rows of the matrix
872 , n_ ( m.n_ ) // The current number of columns of the matrix
873 , nn_( m.nn_ ) // The number of elements between two rows
874 , v_ ( m.v_ ) // The custom array of elements
875{}
876//*************************************************************************************************
877
878
879//*************************************************************************************************
884template< typename Type // Data type of the matrix
885 , AlignmentFlag AF // Alignment flag
886 , PaddingFlag PF // Padding flag
887 , bool SO // Storage order
888 , typename Tag // Type tag
889 , typename RT > // Result type
891 : m_ ( m.m_ ) // The current number of rows of the matrix
892 , n_ ( m.n_ ) // The current number of columns of the matrix
893 , nn_( m.nn_ ) // The number of elements between two rows
894 , v_ ( m.v_ ) // The custom array of elements
895{
896 m.m_ = 0UL;
897 m.n_ = 0UL;
898 m.nn_ = 0UL;
899 m.v_ = nullptr;
900
901 BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
902}
903//*************************************************************************************************
904
905
906
907
908//=================================================================================================
909//
910// DESTRUCTOR
911//
912//=================================================================================================
913
914//*************************************************************************************************
917template< typename Type // Data type of the matrix
918 , AlignmentFlag AF // Alignment flag
919 , PaddingFlag PF // Padding flag
920 , bool SO // Storage order
921 , typename Tag // Type tag
922 , typename RT > // Result type
924{
929}
930//*************************************************************************************************
931
932
933
934
935//=================================================================================================
936//
937// DATA ACCESS FUNCTIONS
938//
939//=================================================================================================
940
941//*************************************************************************************************
951template< typename Type // Data type of the matrix
952 , AlignmentFlag AF // Alignment flag
953 , PaddingFlag PF // Padding flag
954 , bool SO // Storage order
955 , typename Tag // Type tag
956 , typename RT > // Result type
959{
960 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
961 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
962 return v_[i*nn_+j];
963}
964//*************************************************************************************************
965
966
967//*************************************************************************************************
977template< typename Type // Data type of the matrix
978 , AlignmentFlag AF // Alignment flag
979 , PaddingFlag PF // Padding flag
980 , bool SO // Storage order
981 , typename Tag // Type tag
982 , typename RT > // Result type
984 CustomMatrix<Type,AF,PF,SO,Tag,RT>::operator()( size_t i, size_t j ) const noexcept
985{
986 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
987 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
988 return v_[i*nn_+j];
989}
990//*************************************************************************************************
991
992
993//*************************************************************************************************
1004template< typename Type // Data type of the matrix
1005 , AlignmentFlag AF // Alignment flag
1006 , PaddingFlag PF // Padding flag
1007 , bool SO // Storage order
1008 , typename Tag // Type tag
1009 , typename RT > // Result type
1012{
1013 if( i >= m_ ) {
1014 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1015 }
1016 if( j >= n_ ) {
1017 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1018 }
1019 return (*this)(i,j);
1020}
1021//*************************************************************************************************
1022
1023
1024//*************************************************************************************************
1035template< typename Type // Data type of the matrix
1036 , AlignmentFlag AF // Alignment flag
1037 , PaddingFlag PF // Padding flag
1038 , bool SO // Storage order
1039 , typename Tag // Type tag
1040 , typename RT > // Result type
1042 CustomMatrix<Type,AF,PF,SO,Tag,RT>::at( size_t i, size_t j ) const
1043{
1044 if( i >= m_ ) {
1045 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1046 }
1047 if( j >= n_ ) {
1048 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1049 }
1050 return (*this)(i,j);
1051}
1052//*************************************************************************************************
1053
1054
1055//*************************************************************************************************
1067template< typename Type // Data type of the matrix
1068 , AlignmentFlag AF // Alignment flag
1069 , PaddingFlag PF // Padding flag
1070 , bool SO // Storage order
1071 , typename Tag // Type tag
1072 , typename RT > // Result type
1075{
1076 return v_;
1077}
1078//*************************************************************************************************
1079
1080
1081//*************************************************************************************************
1093template< typename Type // Data type of the matrix
1094 , AlignmentFlag AF // Alignment flag
1095 , PaddingFlag PF // Padding flag
1096 , bool SO // Storage order
1097 , typename Tag // Type tag
1098 , typename RT > // Result type
1101{
1102 return v_;
1103}
1104//*************************************************************************************************
1105
1106
1107//*************************************************************************************************
1115template< typename Type // Data type of the matrix
1116 , AlignmentFlag AF // Alignment flag
1117 , PaddingFlag PF // Padding flag
1118 , bool SO // Storage order
1119 , typename Tag // Type tag
1120 , typename RT > // Result type
1123{
1124 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1125 return v_+i*nn_;
1126}
1127//*************************************************************************************************
1128
1129
1130//*************************************************************************************************
1138template< typename Type // Data type of the matrix
1139 , AlignmentFlag AF // Alignment flag
1140 , PaddingFlag PF // Padding flag
1141 , bool SO // Storage order
1142 , typename Tag // Type tag
1143 , typename RT > // Result type
1146{
1147 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1148 return v_+i*nn_;
1149}
1150//*************************************************************************************************
1151
1152
1153//*************************************************************************************************
1164template< typename Type // Data type of the matrix
1165 , AlignmentFlag AF // Alignment flag
1166 , PaddingFlag PF // Padding flag
1167 , bool SO // Storage order
1168 , typename Tag // Type tag
1169 , typename RT > // Result type
1172{
1173 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1174 return Iterator( v_+i*nn_ );
1175}
1176//*************************************************************************************************
1177
1178
1179//*************************************************************************************************
1190template< typename Type // Data type of the matrix
1191 , AlignmentFlag AF // Alignment flag
1192 , PaddingFlag PF // Padding flag
1193 , bool SO // Storage order
1194 , typename Tag // Type tag
1195 , typename RT > // Result type
1198{
1199 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1200 return ConstIterator( v_+i*nn_ );
1201}
1202//*************************************************************************************************
1203
1204
1205//*************************************************************************************************
1216template< typename Type // Data type of the matrix
1217 , AlignmentFlag AF // Alignment flag
1218 , PaddingFlag PF // Padding flag
1219 , bool SO // Storage order
1220 , typename Tag // Type tag
1221 , typename RT > // Result type
1224{
1225 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1226 return ConstIterator( v_+i*nn_ );
1227}
1228//*************************************************************************************************
1229
1230
1231//*************************************************************************************************
1242template< typename Type // Data type of the matrix
1243 , AlignmentFlag AF // Alignment flag
1244 , PaddingFlag PF // Padding flag
1245 , bool SO // Storage order
1246 , typename Tag // Type tag
1247 , typename RT > // Result type
1250{
1251 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1252 return Iterator( v_+i*nn_+n_ );
1253}
1254//*************************************************************************************************
1255
1256
1257//*************************************************************************************************
1268template< typename Type // Data type of the matrix
1269 , AlignmentFlag AF // Alignment flag
1270 , PaddingFlag PF // Padding flag
1271 , bool SO // Storage order
1272 , typename Tag // Type tag
1273 , typename RT > // Result type
1276{
1277 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1278 return ConstIterator( v_+i*nn_+n_ );
1279}
1280//*************************************************************************************************
1281
1282
1283//*************************************************************************************************
1294template< typename Type // Data type of the matrix
1295 , AlignmentFlag AF // Alignment flag
1296 , PaddingFlag PF // Padding flag
1297 , bool SO // Storage order
1298 , typename Tag // Type tag
1299 , typename RT > // Result type
1302{
1303 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1304 return ConstIterator( v_+i*nn_+n_ );
1305}
1306//*************************************************************************************************
1307
1308
1309
1310
1311//=================================================================================================
1312//
1313// ASSIGNMENT OPERATORS
1314//
1315//=================================================================================================
1316
1317//*************************************************************************************************
1323template< typename Type // Data type of the matrix
1324 , AlignmentFlag AF // Alignment flag
1325 , PaddingFlag PF // Padding flag
1326 , bool SO // Storage order
1327 , typename Tag // Type tag
1328 , typename RT > // Result type
1331{
1332 for( size_t i=0UL; i<m_; ++i )
1333 for( size_t j=0UL; j<n_; ++j )
1334 v_[i*nn_+j] = rhs;
1335
1336 return *this;
1337}
1338//*************************************************************************************************
1339
1340
1341//*************************************************************************************************
1369template< typename Type // Data type of the matrix
1370 , AlignmentFlag AF // Alignment flag
1371 , PaddingFlag PF // Padding flag
1372 , bool SO // Storage order
1373 , typename Tag // Type tag
1374 , typename RT > // Result type
1376 CustomMatrix<Type,AF,PF,SO,Tag,RT>::operator=( initializer_list< initializer_list<Type> > list )
1377{
1378 if( list.size() != m_ || determineColumns( list ) > n_ ) {
1379 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
1380 }
1381
1382 size_t i( 0UL );
1383
1384 for( const auto& rowList : list ) {
1385 std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ),
1386 v_+i*nn_+( PF ? nn_ : n_ ), Type() );
1387 ++i;
1388 }
1389
1390 return *this;
1391}
1392//*************************************************************************************************
1393
1394
1395//*************************************************************************************************
1424template< typename Type // Data type of the matrix
1425 , AlignmentFlag AF // Alignment flag
1426 , PaddingFlag PF // Padding flag
1427 , bool SO // Storage order
1428 , typename Tag // Type tag
1429 , typename RT > // Result type
1430template< typename Other // Data type of the static array
1431 , size_t Rows // Number of rows of the static array
1432 , size_t Cols > // Number of columns of the static array
1434 CustomMatrix<Type,AF,PF,SO,Tag,RT>::operator=( const Other (&array)[Rows][Cols] )
1435{
1436 if( m_ != Rows || n_ != Cols ) {
1437 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1438 }
1439
1440 for( size_t i=0UL; i<Rows; ++i )
1441 for( size_t j=0UL; j<Cols; ++j )
1442 v_[i*nn_+j] = array[i][j];
1443
1444 return *this;
1445}
1446//*************************************************************************************************
1447
1448
1449//*************************************************************************************************
1478template< typename Type // Data type of the matrix
1479 , AlignmentFlag AF // Alignment flag
1480 , PaddingFlag PF // Padding flag
1481 , bool SO // Storage order
1482 , typename Tag // Type tag
1483 , typename RT > // Result type
1484template< typename Other // Data type of the static array
1485 , size_t Rows // Number of rows of the static array
1486 , size_t Cols > // Number of columns of the static array
1488 CustomMatrix<Type,AF,PF,SO,Tag,RT>::operator=( const std::array<std::array<Other,Cols>,Rows>& array )
1489{
1490 if( m_ != Rows || n_ != Cols ) {
1491 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
1492 }
1493
1494 for( size_t i=0UL; i<Rows; ++i )
1495 for( size_t j=0UL; j<Cols; ++j )
1496 v_[i*nn_+j] = array[i][j];
1497
1498 return *this;
1499}
1500//*************************************************************************************************
1501
1502
1503//*************************************************************************************************
1513template< typename Type // Data type of the matrix
1514 , AlignmentFlag AF // Alignment flag
1515 , PaddingFlag PF // Padding flag
1516 , bool SO // Storage order
1517 , typename Tag // Type tag
1518 , typename RT > // Result type
1521{
1522 if( rhs.rows() != m_ || rhs.columns() != n_ ) {
1523 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1524 }
1525
1526 smpAssign( *this, *rhs );
1527
1528 return *this;
1529}
1530//*************************************************************************************************
1531
1532
1533//*************************************************************************************************
1539template< typename Type // Data type of the matrix
1540 , AlignmentFlag AF // Alignment flag
1541 , PaddingFlag PF // Padding flag
1542 , bool SO // Storage order
1543 , typename Tag // Type tag
1544 , typename RT > // Result type
1547{
1548 m_ = rhs.m_;
1549 n_ = rhs.n_;
1550 nn_ = rhs.nn_;
1551 v_ = rhs.v_;
1552
1553 rhs.m_ = 0UL;
1554 rhs.n_ = 0UL;
1555 rhs.nn_ = 0UL;
1556 rhs.v_ = nullptr;
1557
1558 BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
1559
1560 return *this;
1561}
1562//*************************************************************************************************
1563
1564
1565//*************************************************************************************************
1575template< typename Type // Data type of the matrix
1576 , AlignmentFlag AF // Alignment flag
1577 , PaddingFlag PF // Padding flag
1578 , bool SO // Storage order
1579 , typename Tag // Type tag
1580 , typename RT > // Result type
1581template< typename MT // Type of the right-hand side matrix
1582 , bool SO2 > // Storage order of the right-hand side matrix
1585{
1586 using TT = decltype( trans( *this ) );
1587 using CT = decltype( ctrans( *this ) );
1588 using IT = decltype( inv( *this ) );
1589
1591
1592 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1593 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1594 }
1595
1596 if( IsSame_v<MT,TT> && (*rhs).isAliased( this ) ) {
1597 transpose();
1598 }
1599 else if( IsSame_v<MT,CT> && (*rhs).isAliased( this ) ) {
1600 ctranspose();
1601 }
1602 else if( !IsSame_v<MT,IT> && (*rhs).canAlias( this ) ) {
1603 const ResultType_t<MT> tmp( *rhs );
1604 smpAssign( *this, tmp );
1605 }
1606 else {
1607 if( IsSparseMatrix_v<MT> )
1608 reset();
1609 smpAssign( *this, *rhs );
1610 }
1611
1612 return *this;
1613}
1614//*************************************************************************************************
1615
1616
1617//*************************************************************************************************
1627template< typename Type // Data type of the matrix
1628 , AlignmentFlag AF // Alignment flag
1629 , PaddingFlag PF // Padding flag
1630 , bool SO // Storage order
1631 , typename Tag // Type tag
1632 , typename RT > // Result type
1633template< typename MT // Type of the right-hand side matrix
1634 , bool SO2 > // Storage order of the right-hand side matrix
1637{
1639
1640 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1641 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1642 }
1643
1644 if( (*rhs).canAlias( this ) ) {
1645 const ResultType_t<MT> tmp( *rhs );
1646 smpAddAssign( *this, tmp );
1647 }
1648 else {
1649 smpAddAssign( *this, *rhs );
1650 }
1651
1652 return *this;
1653}
1654//*************************************************************************************************
1655
1656
1657//*************************************************************************************************
1667template< typename Type // Data type of the matrix
1668 , AlignmentFlag AF // Alignment flag
1669 , PaddingFlag PF // Padding flag
1670 , bool SO // Storage order
1671 , typename Tag // Type tag
1672 , typename RT > // Result type
1673template< typename MT // Type of the right-hand side matrix
1674 , bool SO2 > // Storage order of the right-hand side matrix
1677{
1679
1680 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1681 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1682 }
1683
1684 if( (*rhs).canAlias( this ) ) {
1685 const ResultType_t<MT> tmp( *rhs );
1686 smpSubAssign( *this, tmp );
1687 }
1688 else {
1689 smpSubAssign( *this, *rhs );
1690 }
1691
1692 return *this;
1693}
1694//*************************************************************************************************
1695
1696
1697//*************************************************************************************************
1707template< typename Type // Data type of the matrix
1708 , AlignmentFlag AF // Alignment flag
1709 , PaddingFlag PF // Padding flag
1710 , bool SO // Storage order
1711 , typename Tag // Type tag
1712 , typename RT > // Result type
1713template< typename MT // Type of the right-hand side matrix
1714 , bool SO2 > // Storage order of the right-hand side matrix
1717{
1719
1720 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1721 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1722 }
1723
1724 if( (*rhs).canAlias( this ) ) {
1725 const ResultType_t<MT> tmp( *rhs );
1726 smpSchurAssign( *this, tmp );
1727 }
1728 else {
1729 smpSchurAssign( *this, *rhs );
1730 }
1731
1732 return *this;
1733}
1734//*************************************************************************************************
1735
1736
1737
1738
1739//=================================================================================================
1740//
1741// UTILITY FUNCTIONS
1742//
1743//=================================================================================================
1744
1745//*************************************************************************************************
1750template< typename Type // Data type of the matrix
1751 , AlignmentFlag AF // Alignment flag
1752 , PaddingFlag PF // Padding flag
1753 , bool SO // Storage order
1754 , typename Tag // Type tag
1755 , typename RT > // Result type
1756inline size_t CustomMatrix<Type,AF,PF,SO,Tag,RT>::rows() const noexcept
1757{
1758 return m_;
1759}
1760//*************************************************************************************************
1761
1762
1763//*************************************************************************************************
1768template< typename Type // Data type of the matrix
1769 , AlignmentFlag AF // Alignment flag
1770 , PaddingFlag PF // Padding flag
1771 , bool SO // Storage order
1772 , typename Tag // Type tag
1773 , typename RT > // Result type
1775{
1776 return n_;
1777}
1778//*************************************************************************************************
1779
1780
1781//*************************************************************************************************
1791template< typename Type // Data type of the matrix
1792 , AlignmentFlag AF // Alignment flag
1793 , PaddingFlag PF // Padding flag
1794 , bool SO // Storage order
1795 , typename Tag // Type tag
1796 , typename RT > // Result type
1798{
1799 return nn_;
1800}
1801//*************************************************************************************************
1802
1803
1804//*************************************************************************************************
1809template< typename Type // Data type of the matrix
1810 , AlignmentFlag AF // Alignment flag
1811 , PaddingFlag PF // Padding flag
1812 , bool SO // Storage order
1813 , typename Tag // Type tag
1814 , typename RT > // Result type
1816{
1817 return m_ * nn_;
1818}
1819//*************************************************************************************************
1820
1821
1822//*************************************************************************************************
1833template< typename Type // Data type of the matrix
1834 , AlignmentFlag AF // Alignment flag
1835 , PaddingFlag PF // Padding flag
1836 , bool SO // Storage order
1837 , typename Tag // Type tag
1838 , typename RT > // Result type
1839inline size_t CustomMatrix<Type,AF,PF,SO,Tag,RT>::capacity( size_t i ) const noexcept
1840{
1841 MAYBE_UNUSED( i );
1842 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1843 return nn_;
1844}
1845//*************************************************************************************************
1846
1847
1848//*************************************************************************************************
1857template< typename Type // Data type of the matrix
1858 , AlignmentFlag AF // Alignment flag
1859 , PaddingFlag PF // Padding flag
1860 , bool SO // Storage order
1861 , typename Tag // Type tag
1862 , typename RT > // Result type
1864{
1865 size_t nonzeros( 0UL );
1866
1867 for( size_t i=0UL; i<m_; ++i )
1868 for( size_t j=0UL; j<n_; ++j )
1869 if( !isDefault<strict>( v_[i*nn_+j] ) )
1870 ++nonzeros;
1871
1872 return nonzeros;
1873}
1874//*************************************************************************************************
1875
1876
1877//*************************************************************************************************
1889template< typename Type // Data type of the matrix
1890 , AlignmentFlag AF // Alignment flag
1891 , PaddingFlag PF // Padding flag
1892 , bool SO // Storage order
1893 , typename Tag // Type tag
1894 , typename RT > // Result type
1896{
1897 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1898
1899 const size_t jend( i*nn_ + n_ );
1900 size_t nonzeros( 0UL );
1901
1902 for( size_t j=i*nn_; j<jend; ++j )
1903 if( !isDefault<strict>( v_[j] ) )
1904 ++nonzeros;
1905
1906 return nonzeros;
1907}
1908//*************************************************************************************************
1909
1910
1911//*************************************************************************************************
1916template< typename Type // Data type of the matrix
1917 , AlignmentFlag AF // Alignment flag
1918 , PaddingFlag PF // Padding flag
1919 , bool SO // Storage order
1920 , typename Tag // Type tag
1921 , typename RT > // Result type
1923{
1924 using blaze::clear;
1925
1926 for( size_t i=0UL; i<m_; ++i )
1927 for( size_t j=0UL; j<n_; ++j )
1928 clear( v_[i*nn_+j] );
1929}
1930//*************************************************************************************************
1931
1932
1933//*************************************************************************************************
1944template< typename Type // Data type of the matrix
1945 , AlignmentFlag AF // Alignment flag
1946 , PaddingFlag PF // Padding flag
1947 , bool SO // Storage order
1948 , typename Tag // Type tag
1949 , typename RT > // Result type
1951{
1952 using blaze::clear;
1953
1954 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1955 for( size_t j=0UL; j<n_; ++j )
1956 clear( v_[i*nn_+j] );
1957}
1958//*************************************************************************************************
1959
1960
1961//*************************************************************************************************
1968template< typename Type // Data type of the matrix
1969 , AlignmentFlag AF // Alignment flag
1970 , PaddingFlag PF // Padding flag
1971 , bool SO // Storage order
1972 , typename Tag // Type tag
1973 , typename RT > // Result type
1975{
1976 m_ = 0UL;
1977 n_ = 0UL;
1978 nn_ = 0UL;
1979 v_ = nullptr;
1980}
1981//*************************************************************************************************
1982
1983
1984//*************************************************************************************************
1990template< typename Type // Data type of the matrix
1991 , AlignmentFlag AF // Alignment flag
1992 , PaddingFlag PF // Padding flag
1993 , bool SO // Storage order
1994 , typename Tag // Type tag
1995 , typename RT > // Result type
1997{
1998 using std::swap;
1999
2000 swap( m_ , m.m_ );
2001 swap( n_ , m.n_ );
2002 swap( nn_, m.nn_ );
2003 swap( v_ , m.v_ );
2004}
2005//*************************************************************************************************
2006
2007
2008
2009
2010//=================================================================================================
2011//
2012// NUMERIC FUNCTIONS
2013//
2014//=================================================================================================
2015
2016//*************************************************************************************************
2024template< typename Type // Data type of the matrix
2025 , AlignmentFlag AF // Alignment flag
2026 , PaddingFlag PF // Padding flag
2027 , bool SO // Storage order
2028 , typename Tag // Type tag
2029 , typename RT > // Result type
2031{
2032 using std::swap;
2033
2034 if( m_ != n_ ) {
2035 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2036 }
2037
2038 for( size_t i=1UL; i<m_; ++i )
2039 for( size_t j=0UL; j<i; ++j )
2040 swap( v_[i*nn_+j], v_[j*nn_+i] );
2041
2042 return *this;
2043}
2044//*************************************************************************************************
2045
2046
2047//*************************************************************************************************
2055template< typename Type // Data type of the matrix
2056 , AlignmentFlag AF // Alignment flag
2057 , PaddingFlag PF // Padding flag
2058 , bool SO // Storage order
2059 , typename Tag // Type tag
2060 , typename RT > // Result type
2062{
2063 if( m_ != n_ ) {
2064 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2065 }
2066
2067 for( size_t i=0UL; i<m_; ++i ) {
2068 for( size_t j=0UL; j<i; ++j ) {
2069 cswap( v_[i*nn_+j], v_[j*nn_+i] );
2070 }
2071 conjugate( v_[i*nn_+i] );
2072 }
2073
2074 return *this;
2075}
2076//*************************************************************************************************
2077
2078
2079//*************************************************************************************************
2100template< typename Type // Data type of the matrix
2101 , AlignmentFlag AF // Alignment flag
2102 , PaddingFlag PF // Padding flag
2103 , bool SO // Storage order
2104 , typename Tag // Type tag
2105 , typename RT > // Result type
2106template< typename Other > // Data type of the scalar value
2109{
2110 for( size_t i=0UL; i<m_; ++i )
2111 for( size_t j=0UL; j<n_; ++j )
2112 v_[i*nn_+j] *= scalar;
2113
2114 return *this;
2115}
2116//*************************************************************************************************
2117
2118
2119
2120
2121//=================================================================================================
2122//
2123// RESOURCE MANAGEMENT FUNCTIONS
2124//
2125//=================================================================================================
2126
2127//*************************************************************************************************
2150template< typename Type // Data type of the matrix
2151 , AlignmentFlag AF // Alignment flag
2152 , PaddingFlag PF // Padding flag
2153 , bool SO // Storage order
2154 , typename Tag // Type tag
2155 , typename RT > // Result type
2156inline void CustomMatrix<Type,AF,PF,SO,Tag,RT>::reset( Type* ptr, size_t m, size_t n )
2157{
2159
2160 CustomMatrix tmp( ptr, m, n );
2161 swap( tmp );
2162}
2163//*************************************************************************************************
2164
2165
2166//*************************************************************************************************
2189template< typename Type // Data type of the matrix
2190 , AlignmentFlag AF // Alignment flag
2191 , PaddingFlag PF // Padding flag
2192 , bool SO // Storage order
2193 , typename Tag // Type tag
2194 , typename RT > // Result type
2195inline void CustomMatrix<Type,AF,PF,SO,Tag,RT>::reset( Type* ptr, size_t m, size_t n, size_t nn )
2196{
2197 CustomMatrix tmp( ptr, m, n, nn );
2198 swap( tmp );
2199}
2200//*************************************************************************************************
2201
2202
2203
2204
2205//=================================================================================================
2206//
2207// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2208//
2209//=================================================================================================
2210
2211//*************************************************************************************************
2221template< typename Type // Data type of the matrix
2222 , AlignmentFlag AF // Alignment flag
2223 , PaddingFlag PF // Padding flag
2224 , bool SO // Storage order
2225 , typename Tag // Type tag
2226 , typename RT > // Result type
2227template< typename Other > // Data type of the foreign expression
2228inline bool CustomMatrix<Type,AF,PF,SO,Tag,RT>::canAlias( const Other* alias ) const noexcept
2229{
2230 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2231}
2232//*************************************************************************************************
2233
2234
2235//*************************************************************************************************
2245template< typename Type // Data type of the matrix
2246 , AlignmentFlag AF // Alignment flag
2247 , PaddingFlag PF // Padding flag
2248 , bool SO // Storage order
2249 , typename Tag // Type tag
2250 , typename RT > // Result type
2251template< typename Other > // Data type of the foreign expression
2252inline bool CustomMatrix<Type,AF,PF,SO,Tag,RT>::isAliased( const Other* alias ) const noexcept
2253{
2254 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2255}
2256//*************************************************************************************************
2257
2258
2259//*************************************************************************************************
2268template< typename Type // Data type of the matrix
2269 , AlignmentFlag AF // Alignment flag
2270 , PaddingFlag PF // Padding flag
2271 , bool SO // Storage order
2272 , typename Tag // Type tag
2273 , typename RT > // Result type
2275{
2276 return ( AF || ( checkAlignment( v_ ) && columns() % SIMDSIZE == 0UL ) );
2277}
2278//*************************************************************************************************
2279
2280
2281//*************************************************************************************************
2291template< typename Type // Data type of the matrix
2292 , AlignmentFlag AF // Alignment flag
2293 , PaddingFlag PF // Padding flag
2294 , bool SO // Storage order
2295 , typename Tag // Type tag
2296 , typename RT > // Result type
2298{
2299 return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2300}
2301//*************************************************************************************************
2302
2303
2304//*************************************************************************************************
2319template< typename Type // Data type of the matrix
2320 , AlignmentFlag AF // Alignment flag
2321 , PaddingFlag PF // Padding flag
2322 , bool SO // Storage order
2323 , typename Tag // Type tag
2324 , typename RT > // Result type
2326 CustomMatrix<Type,AF,PF,SO,Tag,RT>::load( size_t i, size_t j ) const noexcept
2327{
2328 if( AF && PF )
2329 return loada( i, j );
2330 else
2331 return loadu( i, j );
2332}
2333//*************************************************************************************************
2334
2335
2336//*************************************************************************************************
2351template< typename Type // Data type of the matrix
2352 , AlignmentFlag AF // Alignment flag
2353 , PaddingFlag PF // Padding flag
2354 , bool SO // Storage order
2355 , typename Tag // Type tag
2356 , typename RT > // Result type
2358 CustomMatrix<Type,AF,PF,SO,Tag,RT>::loada( size_t i, size_t j ) const noexcept
2359{
2360 using blaze::loada;
2361
2363
2364 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2365 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2366 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2367 BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2368 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2369
2370 return loada( v_+i*nn_+j );
2371}
2372//*************************************************************************************************
2373
2374
2375//*************************************************************************************************
2390template< typename Type // Data type of the matrix
2391 , AlignmentFlag AF // Alignment flag
2392 , PaddingFlag PF // Padding flag
2393 , bool SO // Storage order
2394 , typename Tag // Type tag
2395 , typename RT > // Result type
2397 CustomMatrix<Type,AF,PF,SO,Tag,RT>::loadu( size_t i, size_t j ) const noexcept
2398{
2399 using blaze::loadu;
2400
2402
2403 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2404 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2405 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2406
2407 return loadu( v_+i*nn_+j );
2408}
2409//*************************************************************************************************
2410
2411
2412//*************************************************************************************************
2428template< typename Type // Data type of the matrix
2429 , AlignmentFlag AF // Alignment flag
2430 , PaddingFlag PF // Padding flag
2431 , bool SO // Storage order
2432 , typename Tag // Type tag
2433 , typename RT > // Result type
2435 CustomMatrix<Type,AF,PF,SO,Tag,RT>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2436{
2437 if( AF && PF )
2438 storea( i, j, value );
2439 else
2440 storeu( i, j, value );
2441}
2442//*************************************************************************************************
2443
2444
2445//*************************************************************************************************
2461template< typename Type // Data type of the matrix
2462 , AlignmentFlag AF // Alignment flag
2463 , PaddingFlag PF // Padding flag
2464 , bool SO // Storage order
2465 , typename Tag // Type tag
2466 , typename RT > // Result type
2468 CustomMatrix<Type,AF,PF,SO,Tag,RT>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2469{
2470 using blaze::storea;
2471
2473
2474 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2475 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2476 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2477 BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2478 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2479
2480 storea( v_+i*nn_+j, value );
2481}
2482//*************************************************************************************************
2483
2484
2485//*************************************************************************************************
2501template< typename Type // Data type of the matrix
2502 , AlignmentFlag AF // Alignment flag
2503 , PaddingFlag PF // Padding flag
2504 , bool SO // Storage order
2505 , typename Tag // Type tag
2506 , typename RT > // Result type
2508 CustomMatrix<Type,AF,PF,SO,Tag,RT>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2509{
2510 using blaze::storeu;
2511
2513
2514 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2515 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2516 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2517
2518 storeu( v_+i*nn_+j, value );
2519}
2520//*************************************************************************************************
2521
2522
2523//*************************************************************************************************
2540template< typename Type // Data type of the matrix
2541 , AlignmentFlag AF // Alignment flag
2542 , PaddingFlag PF // Padding flag
2543 , bool SO // Storage order
2544 , typename Tag // Type tag
2545 , typename RT > // Result type
2547 CustomMatrix<Type,AF,PF,SO,Tag,RT>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2548{
2549 using blaze::stream;
2550
2552
2553 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2554 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2555 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= ( PF ? nn_ : n_ ), "Invalid column access index" );
2556 BLAZE_INTERNAL_ASSERT( !PF || j % SIMDSIZE == 0UL, "Invalid column access index" );
2557 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2558
2559 stream( v_+i*nn_+j, value );
2560}
2561//*************************************************************************************************
2562
2563
2564//*************************************************************************************************
2575template< typename Type // Data type of the matrix
2576 , AlignmentFlag AF // Alignment flag
2577 , PaddingFlag PF // Padding flag
2578 , bool SO // Storage order
2579 , typename Tag // Type tag
2580 , typename RT > // Result type
2581template< typename MT > // Type of the right-hand side dense matrix
2584{
2585 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2586 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2587
2588 const size_t jpos( prevMultiple( n_, 2UL ) );
2589 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
2590
2591 for( size_t i=0UL; i<m_; ++i ) {
2592 for( size_t j=0UL; j<jpos; j+=2UL ) {
2593 v_[i*nn_+j ] = (*rhs)(i,j );
2594 v_[i*nn_+j+1UL] = (*rhs)(i,j+1UL);
2595 }
2596 if( jpos < n_ ) {
2597 v_[i*nn_+jpos] = (*rhs)(i,jpos);
2598 }
2599 }
2600}
2601//*************************************************************************************************
2602
2603
2604//*************************************************************************************************
2615template< typename Type // Data type of the matrix
2616 , AlignmentFlag AF // Alignment flag
2617 , PaddingFlag PF // Padding flag
2618 , bool SO // Storage order
2619 , typename Tag // Type tag
2620 , typename RT > // Result type
2621template< typename MT > // Type of the right-hand side dense matrix
2624{
2626
2627 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2628 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2629
2630 constexpr bool remainder( !PF || !IsPadded_v<MT> );
2631
2632 const size_t jpos( remainder ? prevMultiple( n_, SIMDSIZE ): n_ );
2633 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
2634
2635 if( AF && PF && useStreaming &&
2636 ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(*rhs).isAliased( this ) )
2637 {
2638 for( size_t i=0UL; i<m_; ++i )
2639 {
2640 size_t j( 0UL );
2641 Iterator left( begin(i) );
2642 ConstIterator_t<MT> right( (*rhs).begin(i) );
2643
2644 for( ; j<jpos; j+=SIMDSIZE ) {
2645 left.stream( right.load() ); left += SIMDSIZE, right += SIMDSIZE;
2646 }
2647 for( ; remainder && j<n_; ++j ) {
2648 *left = *right; ++left; ++right;
2649 }
2650 }
2651 }
2652 else
2653 {
2654 for( size_t i=0UL; i<m_; ++i )
2655 {
2656 size_t j( 0UL );
2657 Iterator left( begin(i) );
2658 ConstIterator_t<MT> right( (*rhs).begin(i) );
2659
2660 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2661 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2662 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2663 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2664 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2665 }
2666 for( ; j<jpos; j+=SIMDSIZE ) {
2667 left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2668 }
2669 for( ; remainder && j<n_; ++j ) {
2670 *left = *right; ++left; ++right;
2671 }
2672 }
2673 }
2674}
2675//*************************************************************************************************
2676
2677
2678//*************************************************************************************************
2689template< typename Type // Data type of the matrix
2690 , AlignmentFlag AF // Alignment flag
2691 , PaddingFlag PF // Padding flag
2692 , bool SO // Storage order
2693 , typename Tag // Type tag
2694 , typename RT > // Result type
2695template< typename MT > // Type of the right-hand side dense matrix
2697{
2699
2700 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2701 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2702
2703 constexpr size_t block( BLOCK_SIZE );
2704
2705 for( size_t ii=0UL; ii<m_; ii+=block ) {
2706 const size_t iend( min( m_, ii+block ) );
2707 for( size_t jj=0UL; jj<n_; jj+=block ) {
2708 const size_t jend( min( n_, jj+block ) );
2709 for( size_t i=ii; i<iend; ++i ) {
2710 for( size_t j=jj; j<jend; ++j ) {
2711 v_[i*nn_+j] = (*rhs)(i,j);
2712 }
2713 }
2714 }
2715 }
2716}
2717//*************************************************************************************************
2718
2719
2720//*************************************************************************************************
2731template< typename Type // Data type of the matrix
2732 , AlignmentFlag AF // Alignment flag
2733 , PaddingFlag PF // Padding flag
2734 , bool SO // Storage order
2735 , typename Tag // Type tag
2736 , typename RT > // Result type
2737template< typename MT > // Type of the right-hand side sparse matrix
2739{
2740 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2741 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2742
2743 for( size_t i=0UL; i<m_; ++i )
2744 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2745 v_[i*nn_+element->index()] = element->value();
2746}
2747//*************************************************************************************************
2748
2749
2750//*************************************************************************************************
2761template< typename Type // Data type of the matrix
2762 , AlignmentFlag AF // Alignment flag
2763 , PaddingFlag PF // Padding flag
2764 , bool SO // Storage order
2765 , typename Tag // Type tag
2766 , typename RT > // Result type
2767template< typename MT > // Type of the right-hand side sparse matrix
2769{
2771
2772 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2773 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2774
2775 for( size_t j=0UL; j<n_; ++j )
2776 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2777 v_[element->index()*nn_+j] = element->value();
2778}
2779//*************************************************************************************************
2780
2781
2782//*************************************************************************************************
2793template< typename Type // Data type of the matrix
2794 , AlignmentFlag AF // Alignment flag
2795 , PaddingFlag PF // Padding flag
2796 , bool SO // Storage order
2797 , typename Tag // Type tag
2798 , typename RT > // Result type
2799template< typename MT > // Type of the right-hand side dense matrix
2802{
2803 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2804 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2805
2806 for( size_t i=0UL; i<m_; ++i )
2807 {
2808 if( IsDiagonal_v<MT> )
2809 {
2810 v_[i*nn_+i] += (*rhs)(i,i);
2811 }
2812 else
2813 {
2814 const size_t jbegin( ( IsUpper_v<MT> )
2815 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2816 :( 0UL ) );
2817 const size_t jend ( ( IsLower_v<MT> )
2818 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2819 :( n_ ) );
2820 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2821
2822 size_t j( jbegin );
2823
2824 for( ; (j+2UL) <= jend; j+=2UL ) {
2825 v_[i*nn_+j ] += (*rhs)(i,j );
2826 v_[i*nn_+j+1UL] += (*rhs)(i,j+1UL);
2827 }
2828 if( j < jend ) {
2829 v_[i*nn_+j] += (*rhs)(i,j);
2830 }
2831 }
2832 }
2833}
2834//*************************************************************************************************
2835
2836
2837//*************************************************************************************************
2848template< typename Type // Data type of the matrix
2849 , AlignmentFlag AF // Alignment flag
2850 , PaddingFlag PF // Padding flag
2851 , bool SO // Storage order
2852 , typename Tag // Type tag
2853 , typename RT > // Result type
2854template< typename MT > // Type of the right-hand side dense matrix
2857{
2860
2861 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2862 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2863
2864 constexpr bool remainder( !PF || !IsPadded_v<MT> );
2865
2866 for( size_t i=0UL; i<m_; ++i )
2867 {
2868 const size_t jbegin( ( IsUpper_v<MT> )
2869 ?( prevMultiple( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), SIMDSIZE ) )
2870 :( 0UL ) );
2871 const size_t jend ( ( IsLower_v<MT> )
2872 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2873 :( n_ ) );
2874 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2875
2876 const size_t jpos( remainder ? prevMultiple( jend, SIMDSIZE ) : jend );
2877 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
2878
2879 size_t j( jbegin );
2880 Iterator left( begin(i) + jbegin );
2881 ConstIterator_t<MT> right( (*rhs).begin(i) + jbegin );
2882
2883 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2884 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2885 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2886 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2887 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2888 }
2889 for( ; j<jpos; j+=SIMDSIZE ) {
2890 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2891 }
2892 for( ; remainder && j<jend; ++j ) {
2893 *left += *right; ++left; ++right;
2894 }
2895 }
2896}
2897//*************************************************************************************************
2898
2899
2900//*************************************************************************************************
2911template< typename Type // Data type of the matrix
2912 , AlignmentFlag AF // Alignment flag
2913 , PaddingFlag PF // Padding flag
2914 , bool SO // Storage order
2915 , typename Tag // Type tag
2916 , typename RT > // Result type
2917template< typename MT > // Type of the right-hand side dense matrix
2919{
2921
2922 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2923 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2924
2925 constexpr size_t block( BLOCK_SIZE );
2926
2927 for( size_t ii=0UL; ii<m_; ii+=block ) {
2928 const size_t iend( min( m_, ii+block ) );
2929 for( size_t jj=0UL; jj<n_; jj+=block )
2930 {
2931 if( IsLower_v<MT> && ii < jj ) break;
2932 if( IsUpper_v<MT> && ii > jj ) continue;
2933
2934 for( size_t i=ii; i<iend; ++i )
2935 {
2936 const size_t jbegin( ( IsUpper_v<MT> )
2937 ?( max( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), jj ) )
2938 :( jj ) );
2939 const size_t jend ( ( IsLower_v<MT> )
2940 ?( min( ( IsStrictlyLower_v<MT> ? i : i+1UL ), n_, jj+block ) )
2941 :( min( n_, jj+block ) ) );
2942 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2943
2944 for( size_t j=jbegin; j<jend; ++j ) {
2945 v_[i*nn_+j] += (*rhs)(i,j);
2946 }
2947 }
2948 }
2949 }
2950}
2951//*************************************************************************************************
2952
2953
2954//*************************************************************************************************
2965template< typename Type // Data type of the matrix
2966 , AlignmentFlag AF // Alignment flag
2967 , PaddingFlag PF // Padding flag
2968 , bool SO // Storage order
2969 , typename Tag // Type tag
2970 , typename RT > // Result type
2971template< typename MT > // Type of the right-hand side sparse matrix
2973{
2974 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2975 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2976
2977 for( size_t i=0UL; i<m_; ++i )
2978 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2979 v_[i*nn_+element->index()] += element->value();
2980}
2981//*************************************************************************************************
2982
2983
2984//*************************************************************************************************
2995template< typename Type // Data type of the matrix
2996 , AlignmentFlag AF // Alignment flag
2997 , PaddingFlag PF // Padding flag
2998 , bool SO // Storage order
2999 , typename Tag // Type tag
3000 , typename RT > // Result type
3001template< typename MT > // Type of the right-hand side sparse matrix
3003{
3005
3006 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3007 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3008
3009 for( size_t j=0UL; j<n_; ++j )
3010 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3011 v_[element->index()*nn_+j] += element->value();
3012}
3013//*************************************************************************************************
3014
3015
3016//*************************************************************************************************
3027template< typename Type // Data type of the matrix
3028 , AlignmentFlag AF // Alignment flag
3029 , PaddingFlag PF // Padding flag
3030 , bool SO // Storage order
3031 , typename Tag // Type tag
3032 , typename RT > // Result type
3033template< typename MT > // Type of the right-hand side dense matrix
3036{
3037 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3038 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3039
3040 for( size_t i=0UL; i<m_; ++i )
3041 {
3042 if( IsDiagonal_v<MT> )
3043 {
3044 v_[i*nn_+i] -= (*rhs)(i,i);
3045 }
3046 else
3047 {
3048 const size_t jbegin( ( IsUpper_v<MT> )
3049 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
3050 :( 0UL ) );
3051 const size_t jend ( ( IsLower_v<MT> )
3052 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3053 :( n_ ) );
3054 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3055
3056 size_t j( jbegin );
3057
3058 for( ; (j+2UL) <= jend; j+=2UL ) {
3059 v_[i*nn_+j ] -= (*rhs)(i,j );
3060 v_[i*nn_+j+1UL] -= (*rhs)(i,j+1UL);
3061 }
3062 if( j < jend ) {
3063 v_[i*nn_+j] -= (*rhs)(i,j);
3064 }
3065 }
3066 }
3067}
3068//*************************************************************************************************
3069
3070
3071//*************************************************************************************************
3082template< typename Type // Data type of the matrix
3083 , AlignmentFlag AF // Alignment flag
3084 , PaddingFlag PF // Padding flag
3085 , bool SO // Storage order
3086 , typename Tag // Type tag
3087 , typename RT > // Result type
3088template< typename MT > // Type of the right-hand side dense matrix
3091{
3094
3095 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3096 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3097
3098 constexpr bool remainder( !PF || !IsPadded_v<MT> );
3099
3100 for( size_t i=0UL; i<m_; ++i )
3101 {
3102 const size_t jbegin( ( IsUpper_v<MT> )
3103 ?( prevMultiple( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), SIMDSIZE ) )
3104 :( 0UL ) );
3105 const size_t jend ( ( IsLower_v<MT> )
3106 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3107 :( n_ ) );
3108 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3109
3110 const size_t jpos( remainder ? prevMultiple( jend, SIMDSIZE ) : jend );
3111 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
3112
3113 size_t j( jbegin );
3114 Iterator left( begin(i) + jbegin );
3115 ConstIterator_t<MT> right( (*rhs).begin(i) + jbegin );
3116
3117 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3118 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3119 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3120 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3121 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3122 }
3123 for( ; j<jpos; j+=SIMDSIZE ) {
3124 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3125 }
3126 for( ; remainder && j<jend; ++j ) {
3127 *left -= *right; ++left; ++right;
3128 }
3129 }
3130}
3131//*************************************************************************************************
3132
3133
3134//*************************************************************************************************
3145template< typename Type // Data type of the matrix
3146 , AlignmentFlag AF // Alignment flag
3147 , PaddingFlag PF // Padding flag
3148 , bool SO // Storage order
3149 , typename Tag // Type tag
3150 , typename RT > // Result type
3151template< typename MT > // Type of the right-hand side dense matrix
3153{
3155
3156 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3157 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3158
3159 constexpr size_t block( BLOCK_SIZE );
3160
3161 for( size_t ii=0UL; ii<m_; ii+=block ) {
3162 const size_t iend( min( m_, ii+block ) );
3163 for( size_t jj=0UL; jj<n_; jj+=block )
3164 {
3165 if( IsLower_v<MT> && ii < jj ) break;
3166 if( IsUpper_v<MT> && ii > jj ) continue;
3167
3168 for( size_t i=ii; i<iend; ++i )
3169 {
3170 const size_t jbegin( ( IsUpper_v<MT> )
3171 ?( max( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), jj ) )
3172 :( jj ) );
3173 const size_t jend ( ( IsLower_v<MT> )
3174 ?( min( ( IsStrictlyLower_v<MT> ? i : i+1UL ), n_, jj+block ) )
3175 :( min( n_, jj+block ) ) );
3176 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3177
3178 for( size_t j=jbegin; j<jend; ++j ) {
3179 v_[i*nn_+j] -= (*rhs)(i,j);
3180 }
3181 }
3182 }
3183 }
3184}
3185//*************************************************************************************************
3186
3187
3188//*************************************************************************************************
3199template< typename Type // Data type of the matrix
3200 , AlignmentFlag AF // Alignment flag
3201 , PaddingFlag PF // Padding flag
3202 , bool SO // Storage order
3203 , typename Tag // Type tag
3204 , typename RT > // Result type
3205template< typename MT > // Type of the right-hand side sparse matrix
3207{
3208 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3209 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3210
3211 for( size_t i=0UL; i<m_; ++i )
3212 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3213 v_[i*nn_+element->index()] -= element->value();
3214}
3215//*************************************************************************************************
3216
3217
3218//*************************************************************************************************
3229template< typename Type // Data type of the matrix
3230 , AlignmentFlag AF // Alignment flag
3231 , PaddingFlag PF // Padding flag
3232 , bool SO // Storage order
3233 , typename Tag // Type tag
3234 , typename RT > // Result type
3235template< typename MT > // Type of the right-hand side sparse matrix
3237{
3239
3240 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3241 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3242
3243 for( size_t j=0UL; j<n_; ++j )
3244 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3245 v_[element->index()*nn_+j] -= element->value();
3246}
3247//*************************************************************************************************
3248
3249
3250//*************************************************************************************************
3261template< typename Type // Data type of the matrix
3262 , AlignmentFlag AF // Alignment flag
3263 , PaddingFlag PF // Padding flag
3264 , bool SO // Storage order
3265 , typename Tag // Type tag
3266 , typename RT > // Result type
3267template< typename MT > // Type of the right-hand side dense matrix
3270{
3271 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3272 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3273
3274 const size_t jpos( prevMultiple( n_, 2UL ) );
3275 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
3276
3277 for( size_t i=0UL; i<m_; ++i ) {
3278 for( size_t j=0UL; j<jpos; j+=2UL ) {
3279 v_[i*nn_+j ] *= (*rhs)(i,j );
3280 v_[i*nn_+j+1UL] *= (*rhs)(i,j+1UL);
3281 }
3282 if( jpos < n_ ) {
3283 v_[i*nn_+jpos] *= (*rhs)(i,jpos);
3284 }
3285 }
3286}
3287//*************************************************************************************************
3288
3289
3290//*************************************************************************************************
3301template< typename Type // Data type of the matrix
3302 , AlignmentFlag AF // Alignment flag
3303 , PaddingFlag PF // Padding flag
3304 , bool SO // Storage order
3305 , typename Tag // Type tag
3306 , typename RT > // Result type
3307template< typename MT > // Type of the right-hand side dense matrix
3310{
3312
3313 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3314 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3315
3316 constexpr bool remainder( !PF || !IsPadded_v<MT> );
3317
3318 for( size_t i=0UL; i<m_; ++i )
3319 {
3320 const size_t jpos( remainder ? prevMultiple( n_, SIMDSIZE ): n_ );
3321 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
3322
3323 size_t j( 0UL );
3324 Iterator left( begin(i) );
3325 ConstIterator_t<MT> right( (*rhs).begin(i) );
3326
3327 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3328 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3329 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3330 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3331 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3332 }
3333 for( ; j<jpos; j+=SIMDSIZE ) {
3334 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3335 }
3336 for( ; remainder && j<n_; ++j ) {
3337 *left *= *right; ++left; ++right;
3338 }
3339 }
3340}
3341//*************************************************************************************************
3342
3343
3344//*************************************************************************************************
3355template< typename Type // Data type of the matrix
3356 , AlignmentFlag AF // Alignment flag
3357 , PaddingFlag PF // Padding flag
3358 , bool SO // Storage order
3359 , typename Tag // Type tag
3360 , typename RT > // Result type
3361template< typename MT > // Type of the right-hand side dense matrix
3363{
3365
3366 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3367 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3368
3369 constexpr size_t block( BLOCK_SIZE );
3370
3371 for( size_t ii=0UL; ii<m_; ii+=block ) {
3372 const size_t iend( min( m_, ii+block ) );
3373 for( size_t jj=0UL; jj<n_; jj+=block ) {
3374 const size_t jend( min( n_, jj+block ) );
3375 for( size_t i=ii; i<iend; ++i ) {
3376 for( size_t j=jj; j<jend; ++j ) {
3377 v_[i*nn_+j] *= (*rhs)(i,j);
3378 }
3379 }
3380 }
3381 }
3382}
3383//*************************************************************************************************
3384
3385
3386//*************************************************************************************************
3397template< typename Type // Data type of the matrix
3398 , AlignmentFlag AF // Alignment flag
3399 , PaddingFlag PF // Padding flag
3400 , bool SO // Storage order
3401 , typename Tag // Type tag
3402 , typename RT > // Result type
3403template< typename MT > // Type of the right-hand side sparse matrix
3405{
3406 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3407 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3408
3409 const ResultType tmp( serial( *this ) );
3410
3411 reset();
3412
3413 for( size_t i=0UL; i<m_; ++i )
3414 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3415 v_[i*nn_+element->index()] = tmp(i,element->index()) * element->value();
3416}
3417//*************************************************************************************************
3418
3419
3420//*************************************************************************************************
3431template< typename Type // Data type of the matrix
3432 , AlignmentFlag AF // Alignment flag
3433 , PaddingFlag PF // Padding flag
3434 , bool SO // Storage order
3435 , typename Tag // Type tag
3436 , typename RT > // Result type
3437template< typename MT > // Type of the right-hand side sparse matrix
3439{
3441
3442 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3443 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3444
3445 const ResultType tmp( serial( *this ) );
3446
3447 reset();
3448
3449 for( size_t j=0UL; j<n_; ++j )
3450 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3451 v_[element->index()*nn_+j] = tmp(element->index(),j) * element->value();
3452}
3453//*************************************************************************************************
3454
3455
3456
3457
3458
3459
3460
3461
3462//=================================================================================================
3463//
3464// CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3465//
3466//=================================================================================================
3467
3468//*************************************************************************************************
3476template< typename Type // Data type of the matrix
3477 , AlignmentFlag AF // Alignment flag
3478 , PaddingFlag PF // Padding flag
3479 , typename Tag // Type tag
3480 , typename RT > // Result type
3481class CustomMatrix<Type,AF,PF,true,Tag,RT>
3482 : public DenseMatrix< CustomMatrix<Type,AF,PF,true,Tag,RT>, true >
3483{
3484 public:
3485 //**Type definitions****************************************************************************
3488
3490 using ResultType = RT;
3491
3494
3497
3498 using ElementType = Type;
3500 using TagType = Tag;
3501 using ReturnType = const Type&;
3502 using CompositeType = const This&;
3503
3504 using Reference = Type&;
3505 using ConstReference = const Type&;
3506 using Pointer = Type*;
3507 using ConstPointer = const Type*;
3508
3511 //**********************************************************************************************
3512
3513 //**Rebind struct definition********************************************************************
3516 template< typename NewType > // Data type of the other matrix
3517 struct Rebind {
3520 };
3521 //**********************************************************************************************
3522
3523 //**Resize struct definition********************************************************************
3526 template< size_t NewM // Number of rows of the other matrix
3527 , size_t NewN > // Number of columns of the other matrix
3528 struct Resize {
3529 using RRT = Resize_t<RT,NewM,NewN>;
3530 using Other = CustomMatrix<Type,AF,PF,true,Tag,RRT>;
3531 };
3532 //**********************************************************************************************
3533
3534 //**Compilation flags***************************************************************************
3536
3540 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
3541
3543
3546 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3547 //**********************************************************************************************
3548
3549 //**Constructors********************************************************************************
3552 inline CustomMatrix();
3553 inline CustomMatrix( Type* ptr, size_t m, size_t n );
3554 inline CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm );
3555 inline CustomMatrix( const CustomMatrix& m );
3556 inline CustomMatrix( CustomMatrix&& m ) noexcept;
3558 //**********************************************************************************************
3559
3560 //**Destructor**********************************************************************************
3563 inline ~CustomMatrix();
3565 //**********************************************************************************************
3566
3567 //**Data access functions***********************************************************************
3570 inline Reference operator()( size_t i, size_t j ) noexcept;
3571 inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3572 inline Reference at( size_t i, size_t j );
3573 inline ConstReference at( size_t i, size_t j ) const;
3574 inline Pointer data () noexcept;
3575 inline ConstPointer data () const noexcept;
3576 inline Pointer data ( size_t j ) noexcept;
3577 inline ConstPointer data ( size_t j ) const noexcept;
3578 inline Iterator begin ( size_t j ) noexcept;
3579 inline ConstIterator begin ( size_t j ) const noexcept;
3580 inline ConstIterator cbegin( size_t j ) const noexcept;
3581 inline Iterator end ( size_t j ) noexcept;
3582 inline ConstIterator end ( size_t j ) const noexcept;
3583 inline ConstIterator cend ( size_t j ) const noexcept;
3585 //**********************************************************************************************
3586
3587 //**Assignment operators************************************************************************
3590 inline CustomMatrix& operator=( const Type& set );
3591 inline CustomMatrix& operator=( initializer_list< initializer_list<Type> > list );
3592
3593 template< typename Other, size_t Rows, size_t Cols >
3594 inline CustomMatrix& operator=( const Other (&array)[Rows][Cols] );
3595
3596 template< typename Other, size_t Rows, size_t Cols >
3597 inline CustomMatrix& operator=( const std::array<std::array<Other,Cols>,Rows>& array );
3598
3599 inline CustomMatrix& operator=( const CustomMatrix& rhs );
3600 inline CustomMatrix& operator=( CustomMatrix&& rhs ) noexcept;
3601
3602 template< typename MT, bool SO > inline CustomMatrix& operator= ( const Matrix<MT,SO>& rhs );
3603 template< typename MT, bool SO > inline CustomMatrix& operator+=( const Matrix<MT,SO>& rhs );
3604 template< typename MT, bool SO > inline CustomMatrix& operator-=( const Matrix<MT,SO>& rhs );
3605 template< typename MT, bool SO > inline CustomMatrix& operator%=( const Matrix<MT,SO>& rhs );
3607 //**********************************************************************************************
3608
3609 //**Utility functions***************************************************************************
3612 inline size_t rows() const noexcept;
3613 inline size_t columns() const noexcept;
3614 inline size_t spacing() const noexcept;
3615 inline size_t capacity() const noexcept;
3616 inline size_t capacity( size_t j ) const noexcept;
3617 inline size_t nonZeros() const;
3618 inline size_t nonZeros( size_t j ) const;
3619 inline void reset();
3620 inline void reset( size_t j );
3621 inline void clear();
3622 inline void swap( CustomMatrix& m ) noexcept;
3624 //**********************************************************************************************
3625
3626 //**Numeric functions***************************************************************************
3629 inline CustomMatrix& transpose();
3630 inline CustomMatrix& ctranspose();
3631
3632 template< typename Other > inline CustomMatrix& scale( const Other& scalar );
3634 //**********************************************************************************************
3635
3636 //**Resource management functions***************************************************************
3639 inline void reset( Type* ptr, size_t m, size_t n );
3640 inline void reset( Type* ptr, size_t m, size_t n, size_t mm );
3642 //**********************************************************************************************
3643
3644 private:
3645 //**********************************************************************************************
3647 template< typename MT >
3648 static constexpr bool VectorizedAssign_v =
3649 ( useOptimizedKernels &&
3650 simdEnabled && MT::simdEnabled &&
3651 IsSIMDCombinable_v< Type, ElementType_t<MT> > );
3652 //**********************************************************************************************
3653
3654 //**********************************************************************************************
3656 template< typename MT >
3657 static constexpr bool VectorizedAddAssign_v =
3658 ( VectorizedAssign_v<MT> &&
3659 HasSIMDAdd_v< Type, ElementType_t<MT> > &&
3660 !IsDiagonal_v<MT> );
3661 //**********************************************************************************************
3662
3663 //**********************************************************************************************
3665 template< typename MT >
3666 static constexpr bool VectorizedSubAssign_v =
3667 ( VectorizedAssign_v<MT> &&
3668 HasSIMDSub_v< Type, ElementType_t<MT> > &&
3669 !IsDiagonal_v<MT> );
3670 //**********************************************************************************************
3671
3672 //**********************************************************************************************
3674 template< typename MT >
3675 static constexpr bool VectorizedSchurAssign_v =
3676 ( VectorizedAssign_v<MT> &&
3677 HasSIMDMult_v< Type, ElementType_t<MT> > );
3678 //**********************************************************************************************
3679
3680 //**SIMD properties*****************************************************************************
3682 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
3683 //**********************************************************************************************
3684
3685 public:
3686 //**Expression template evaluation functions****************************************************
3689 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3690 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3691
3692 inline bool isAligned () const noexcept;
3693 inline bool canSMPAssign() const noexcept;
3694
3695 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3696 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3697 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3698
3699 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3700 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3701 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3702 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3703
3704 template< typename MT >
3705 inline auto assign( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
3706
3707 template< typename MT >
3708 inline auto assign( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
3709
3710 template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3711 template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3712 template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3713
3714 template< typename MT >
3715 inline auto addAssign( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
3716
3717 template< typename MT >
3718 inline auto addAssign( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
3719
3720 template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3721 template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3722 template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3723
3724 template< typename MT >
3725 inline auto subAssign ( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
3726
3727 template< typename MT >
3728 inline auto subAssign ( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
3729
3730 template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3731 template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3732 template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3733
3734 template< typename MT >
3735 inline auto schurAssign ( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
3736
3737 template< typename MT >
3738 inline auto schurAssign ( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
3739
3740 template< typename MT > inline void schurAssign( const DenseMatrix<MT,false>& rhs );
3741 template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3742 template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3744 //**********************************************************************************************
3745
3746 private:
3747 //**Member variables****************************************************************************
3750 size_t m_;
3751 size_t mm_;
3752 size_t n_;
3753 Type* v_;
3757 //**********************************************************************************************
3758
3759 //**Compile time checks*************************************************************************
3763 //**********************************************************************************************
3764};
3766//*************************************************************************************************
3767
3768
3769
3770
3771//=================================================================================================
3772//
3773// CONSTRUCTORS
3774//
3775//=================================================================================================
3776
3777//*************************************************************************************************
3781template< typename Type // Data type of the matrix
3782 , AlignmentFlag AF // Alignment flag
3783 , PaddingFlag PF // Padding flag
3784 , typename Tag // Type tag
3785 , typename RT > // Result type
3786inline CustomMatrix<Type,AF,PF,true,Tag,RT>::CustomMatrix()
3787 : m_ ( 0UL ) // The current number of rows of the matrix
3788 , mm_( 0UL ) // The number of elements between two columns
3789 , n_ ( 0UL ) // The current number of columns of the matrix
3790 , v_ ( nullptr ) // The custom array of elements
3791{}
3793//*************************************************************************************************
3794
3795
3796//*************************************************************************************************
3817template< typename Type // Data type of the matrix
3818 , AlignmentFlag AF // Alignment flag
3819 , PaddingFlag PF // Padding flag
3820 , typename Tag // Type tag
3821 , typename RT > // Result type
3822inline CustomMatrix<Type,AF,PF,true,Tag,RT>::CustomMatrix( Type* ptr, size_t m, size_t n )
3823 : m_ ( m ) // The current number of rows of the matrix
3824 , mm_( m ) // The number of elements between two columns
3825 , n_ ( n ) // The current number of columns of the matrix
3826 , v_ ( ptr ) // The custom array of elements
3827{
3829
3830 if( ptr == nullptr ) {
3831 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3832 }
3833
3834 if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3835 BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3836 }
3837}
3839//*************************************************************************************************
3840
3841
3842//*************************************************************************************************
3865template< typename Type // Data type of the matrix
3866 , AlignmentFlag AF // Alignment flag
3867 , PaddingFlag PF // Padding flag
3868 , typename Tag // Type tag
3869 , typename RT > // Result type
3870inline CustomMatrix<Type,AF,PF,true,Tag,RT>::CustomMatrix( Type* ptr, size_t m, size_t n, size_t mm )
3871 : m_ ( m ) // The current number of rows of the matrix
3872 , mm_( mm ) // The number of elements between two columns
3873 , n_ ( n ) // The current number of columns of the matrix
3874 , v_ ( ptr ) // The custom array of elements
3875{
3876 using blaze::clear;
3877
3878 using ClearFunctor = If_t< PF || !IsConst_v<Type>, Clear, Noop >;
3879
3880 if( ptr == nullptr ) {
3881 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array of elements" );
3882 }
3883
3884 if( AF && ( !checkAlignment( ptr ) || mm_ % SIMDSIZE != 0UL ) ) {
3885 BLAZE_THROW_INVALID_ARGUMENT( "Invalid alignment detected" );
3886 }
3887
3888 if( PF && IsVectorizable_v<Type> && ( mm_ < nextMultiple<size_t>( m_, SIMDSIZE ) ) ) {
3889 BLAZE_THROW_INVALID_ARGUMENT( "Insufficient capacity for padded matrix" );
3890 }
3891
3892 if( PF && IsVectorizable_v<Type> ) {
3893 ClearFunctor clear;
3894 for( size_t j=0UL; j<n_; ++j )
3895 for( size_t i=m_; i<mm_; ++i ) {
3896 clear( v_[i+j*mm_] );
3897 }
3898 }
3899}
3901//*************************************************************************************************
3902
3903
3904//*************************************************************************************************
3913template< typename Type // Data type of the matrix
3914 , AlignmentFlag AF // Alignment flag
3915 , PaddingFlag PF // Padding flag
3916 , typename Tag // Type tag
3917 , typename RT > // Result type
3918inline CustomMatrix<Type,AF,PF,true,Tag,RT>::CustomMatrix( const CustomMatrix& m )
3919 : m_ ( m.m_ ) // The current number of rows of the matrix
3920 , mm_( m.mm_ ) // The number of elements between two columns
3921 , n_ ( m.n_ ) // The current number of columns of the matrix
3922 , v_ ( m.v_ ) // The custom array of elements
3923{}
3925//*************************************************************************************************
3926
3927
3928//*************************************************************************************************
3934template< typename Type // Data type of the matrix
3935 , AlignmentFlag AF // Alignment flag
3936 , PaddingFlag PF // Padding flag
3937 , typename Tag // Type tag
3938 , typename RT > // Result type
3939inline CustomMatrix<Type,AF,PF,true,Tag,RT>::CustomMatrix( CustomMatrix&& m ) noexcept
3940 : m_ ( m.m_ ) // The current number of rows of the matrix
3941 , mm_( m.mm_ ) // The number of elements between two columns
3942 , n_ ( m.n_ ) // The current number of columns of the matrix
3943 , v_ ( m.v_ ) // The custom array of elements
3944{
3945 m.m_ = 0UL;
3946 m.mm_ = 0UL;
3947 m.n_ = 0UL;
3948 m.v_ = nullptr;
3949
3950 BLAZE_INTERNAL_ASSERT( m.data() == nullptr, "Invalid data reference detected" );
3951}
3953//*************************************************************************************************
3954
3955
3956
3957
3958//=================================================================================================
3959//
3960// DESTRUCTOR
3961//
3962//=================================================================================================
3963
3964//*************************************************************************************************
3968template< typename Type // Data type of the matrix
3969 , AlignmentFlag AF // Alignment flag
3970 , PaddingFlag PF // Padding flag
3971 , typename Tag // Type tag
3972 , typename RT > // Result type
3974{
3979}
3981//*************************************************************************************************
3982
3983
3984
3985
3986//=================================================================================================
3987//
3988// DATA ACCESS FUNCTIONS
3989//
3990//=================================================================================================
3991
3992//*************************************************************************************************
4003template< typename Type // Data type of the matrix
4004 , AlignmentFlag AF // Alignment flag
4005 , PaddingFlag PF // Padding flag
4006 , typename Tag // Type tag
4007 , typename RT > // Result type
4009 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator()( size_t i, size_t j ) noexcept
4010{
4011 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
4012 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
4013 return v_[i+j*mm_];
4014}
4016//*************************************************************************************************
4017
4018
4019//*************************************************************************************************
4030template< typename Type // Data type of the matrix
4031 , AlignmentFlag AF // Alignment flag
4032 , PaddingFlag PF // Padding flag
4033 , typename Tag // Type tag
4034 , typename RT > // Result type
4036 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator()( size_t i, size_t j ) const noexcept
4037{
4038 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
4039 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
4040 return v_[i+j*mm_];
4041}
4043//*************************************************************************************************
4044
4045
4046//*************************************************************************************************
4058template< typename Type // Data type of the matrix
4059 , AlignmentFlag AF // Alignment flag
4060 , PaddingFlag PF // Padding flag
4061 , typename Tag // Type tag
4062 , typename RT > // Result type
4064 CustomMatrix<Type,AF,PF,true,Tag,RT>::at( size_t i, size_t j )
4065{
4066 if( i >= m_ ) {
4067 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4068 }
4069 if( j >= n_ ) {
4070 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4071 }
4072 return (*this)(i,j);
4073}
4075//*************************************************************************************************
4076
4077
4078//*************************************************************************************************
4090template< typename Type // Data type of the matrix
4091 , AlignmentFlag AF // Alignment flag
4092 , PaddingFlag PF // Padding flag
4093 , typename Tag // Type tag
4094 , typename RT > // Result type
4096 CustomMatrix<Type,AF,PF,true,Tag,RT>::at( size_t i, size_t j ) const
4097{
4098 if( i >= m_ ) {
4099 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4100 }
4101 if( j >= n_ ) {
4102 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4103 }
4104 return (*this)(i,j);
4105}
4107//*************************************************************************************************
4108
4109
4110//*************************************************************************************************
4122template< typename Type // Data type of the matrix
4123 , AlignmentFlag AF // Alignment flag
4124 , PaddingFlag PF // Padding flag
4125 , typename Tag // Type tag
4126 , typename RT > // Result type
4129{
4130 return v_;
4131}
4133//*************************************************************************************************
4134
4135
4136//*************************************************************************************************
4148template< typename Type // Data type of the matrix
4149 , AlignmentFlag AF // Alignment flag
4150 , PaddingFlag PF // Padding flag
4151 , typename Tag // Type tag
4152 , typename RT > // Result type
4155{
4156 return v_;
4157}
4159//*************************************************************************************************
4160
4161
4162//*************************************************************************************************
4171template< typename Type // Data type of the matrix
4172 , AlignmentFlag AF // Alignment flag
4173 , PaddingFlag PF // Padding flag
4174 , typename Tag // Type tag
4175 , typename RT > // Result type
4178{
4179 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4180 return v_+j*mm_;
4181}
4183//*************************************************************************************************
4184
4185
4186//*************************************************************************************************
4195template< typename Type // Data type of the matrix
4196 , AlignmentFlag AF // Alignment flag
4197 , PaddingFlag PF // Padding flag
4198 , typename Tag // Type tag
4199 , typename RT > // Result type
4201 CustomMatrix<Type,AF,PF,true,Tag,RT>::data( size_t j ) const noexcept
4202{
4203 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4204 return v_+j*mm_;
4205}
4207//*************************************************************************************************
4208
4209
4210//*************************************************************************************************
4217template< typename Type // Data type of the matrix
4218 , AlignmentFlag AF // Alignment flag
4219 , PaddingFlag PF // Padding flag
4220 , typename Tag // Type tag
4221 , typename RT > // Result type
4224{
4225 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4226 return Iterator( v_+j*mm_ );
4227}
4229//*************************************************************************************************
4230
4231
4232//*************************************************************************************************
4239template< typename Type // Data type of the matrix
4240 , AlignmentFlag AF // Alignment flag
4241 , PaddingFlag PF // Padding flag
4242 , typename Tag // Type tag
4243 , typename RT > // Result type
4245 CustomMatrix<Type,AF,PF,true,Tag,RT>::begin( size_t j ) const noexcept
4246{
4247 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4248 return ConstIterator( v_+j*mm_ );
4249}
4251//*************************************************************************************************
4252
4253
4254//*************************************************************************************************
4261template< typename Type // Data type of the matrix
4262 , AlignmentFlag AF // Alignment flag
4263 , PaddingFlag PF // Padding flag
4264 , typename Tag // Type tag
4265 , typename RT > // Result type
4267 CustomMatrix<Type,AF,PF,true,Tag,RT>::cbegin( size_t j ) const noexcept
4268{
4269 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4270 return ConstIterator( v_+j*mm_ );
4271}
4273//*************************************************************************************************
4274
4275
4276//*************************************************************************************************
4283template< typename Type // Data type of the matrix
4284 , AlignmentFlag AF // Alignment flag
4285 , PaddingFlag PF // Padding flag
4286 , typename Tag // Type tag
4287 , typename RT > // Result type
4290{
4291 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4292 return Iterator( v_+j*mm_+m_ );
4293}
4295//*************************************************************************************************
4296
4297
4298//*************************************************************************************************
4305template< typename Type // Data type of the matrix
4306 , AlignmentFlag AF // Alignment flag
4307 , PaddingFlag PF // Padding flag
4308 , typename Tag // Type tag
4309 , typename RT > // Result type
4311 CustomMatrix<Type,AF,PF,true,Tag,RT>::end( size_t j ) const noexcept
4312{
4313 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4314 return ConstIterator( v_+j*mm_+m_ );
4315}
4317//*************************************************************************************************
4318
4319
4320//*************************************************************************************************
4327template< typename Type // Data type of the matrix
4328 , AlignmentFlag AF // Alignment flag
4329 , PaddingFlag PF // Padding flag
4330 , typename Tag // Type tag
4331 , typename RT > // Result type
4333 CustomMatrix<Type,AF,PF,true,Tag,RT>::cend( size_t j ) const noexcept
4334{
4335 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4336 return ConstIterator( v_+j*mm_+m_ );
4337}
4339//*************************************************************************************************
4340
4341
4342
4343
4344//=================================================================================================
4345//
4346// ASSIGNMENT OPERATORS
4347//
4348//=================================================================================================
4349
4350//*************************************************************************************************
4357template< typename Type // Data type of the matrix
4358 , AlignmentFlag AF // Alignment flag
4359 , PaddingFlag PF // Padding flag
4360 , typename Tag // Type tag
4361 , typename RT > // Result type
4362inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4364{
4365 for( size_t j=0UL; j<n_; ++j )
4366 for( size_t i=0UL; i<m_; ++i )
4367 v_[i+j*mm_] = rhs;
4368
4369 return *this;
4370}
4372//*************************************************************************************************
4373
4374
4375//*************************************************************************************************
4404template< typename Type // Data type of the matrix
4405 , AlignmentFlag AF // Alignment flag
4406 , PaddingFlag PF // Padding flag
4407 , typename Tag // Type tag
4408 , typename RT > // Result type
4409inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4411{
4412 using blaze::clear;
4413
4414 if( list.size() != m_ || determineColumns( list ) > n_ ) {
4415 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to custom matrix" );
4416 }
4417
4418 size_t i( 0UL );
4419
4420 for( const auto& rowList : list ) {
4421 size_t j( 0UL );
4422 for( const auto& element : rowList ) {
4423 v_[i+j*mm_] = element;
4424 ++j;
4425 }
4426 for( ; j<n_; ++j ) {
4427 clear( v_[i+j*mm_] );
4428 }
4429 ++i;
4430 }
4431
4432 return *this;
4433}
4435//*************************************************************************************************
4436
4437
4438//*************************************************************************************************
4468template< typename Type // Data type of the matrix
4469 , AlignmentFlag AF // Alignment flag
4470 , PaddingFlag PF // Padding flag
4471 , typename Tag // Type tag
4472 , typename RT > // Result type
4473template< typename Other // Data type of the static array
4474 , size_t Rows // Number of rows of the static array
4475 , size_t Cols > // Number of columns of the static array
4476inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4477 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator=( const Other (&array)[Rows][Cols] )
4478{
4479 if( m_ != Rows || n_ != Cols ) {
4480 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4481 }
4482
4483 for( size_t j=0UL; j<Cols; ++j )
4484 for( size_t i=0UL; i<Rows; ++i )
4485 v_[i+j*mm_] = array[i][j];
4486
4487 return *this;
4488}
4490//*************************************************************************************************
4491
4492
4493//*************************************************************************************************
4523template< typename Type // Data type of the matrix
4524 , AlignmentFlag AF // Alignment flag
4525 , PaddingFlag PF // Padding flag
4526 , typename Tag // Type tag
4527 , typename RT > // Result type
4528template< typename Other // Data type of the static array
4529 , size_t Rows // Number of rows of the static array
4530 , size_t Cols > // Number of columns of the static array
4531inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4532 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator=( const std::array<std::array<Other,Cols>,Rows>& array )
4533{
4534 if( m_ != Rows || n_ != Cols ) {
4535 BLAZE_THROW_INVALID_ARGUMENT( "Invalid array size" );
4536 }
4537
4538 for( size_t j=0UL; j<Cols; ++j )
4539 for( size_t i=0UL; i<Rows; ++i )
4540 v_[i+j*mm_] = array[i][j];
4541
4542 return *this;
4543}
4545//*************************************************************************************************
4546
4547
4548//*************************************************************************************************
4559template< typename Type // Data type of the matrix
4560 , AlignmentFlag AF // Alignment flag
4561 , PaddingFlag PF // Padding flag
4562 , typename Tag // Type tag
4563 , typename RT > // Result type
4564inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4565 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator=( const CustomMatrix& rhs )
4566{
4567 if( rhs.rows() != m_ || rhs.columns() != n_ ) {
4568 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4569 }
4570
4571 smpAssign( *this, *rhs );
4572
4573 return *this;
4574}
4576//*************************************************************************************************
4577
4578
4579//*************************************************************************************************
4586template< typename Type // Data type of the matrix
4587 , AlignmentFlag AF // Alignment flag
4588 , PaddingFlag PF // Padding flag
4589 , typename Tag // Type tag
4590 , typename RT > // Result type
4591inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4592 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator=( CustomMatrix&& rhs ) noexcept
4593{
4594 m_ = rhs.m_;
4595 mm_ = rhs.mm_;
4596 n_ = rhs.n_;
4597 v_ = rhs.v_;
4598
4599 rhs.m_ = 0UL;
4600 rhs.mm_ = 0UL;
4601 rhs.n_ = 0UL;
4602 rhs.v_ = nullptr;
4603
4604 BLAZE_INTERNAL_ASSERT( rhs.data() == nullptr, "Invalid data reference detected" );
4605
4606 return *this;
4607}
4609//*************************************************************************************************
4610
4611
4612//*************************************************************************************************
4623template< typename Type // Data type of the matrix
4624 , AlignmentFlag AF // Alignment flag
4625 , PaddingFlag PF // Padding flag
4626 , typename Tag // Type tag
4627 , typename RT > // Result type
4628template< typename MT // Type of the right-hand side matrix
4629 , bool SO > // Storage order of the right-hand side matrix
4630inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4631 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator=( const Matrix<MT,SO>& rhs )
4632{
4633 using TT = decltype( trans( *this ) );
4634 using CT = decltype( ctrans( *this ) );
4635 using IT = decltype( inv( *this ) );
4636
4637 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4638
4639 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4640 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4641 }
4642
4643 if( IsSame_v<MT,TT> && (*rhs).isAliased( this ) ) {
4644 transpose();
4645 }
4646 else if( IsSame_v<MT,CT> && (*rhs).isAliased( this ) ) {
4647 ctranspose();
4648 }
4649 else if( !IsSame_v<MT,IT> && (*rhs).canAlias( this ) ) {
4650 const ResultType_t<MT> tmp( *rhs );
4651 smpAssign( *this, tmp );
4652 }
4653 else {
4654 if( IsSparseMatrix_v<MT> )
4655 reset();
4656 smpAssign( *this, *rhs );
4657 }
4658
4659 return *this;
4660}
4662//*************************************************************************************************
4663
4664
4665//*************************************************************************************************
4676template< typename Type // Data type of the matrix
4677 , AlignmentFlag AF // Alignment flag
4678 , PaddingFlag PF // Padding flag
4679 , typename Tag // Type tag
4680 , typename RT > // Result type
4681template< typename MT // Type of the right-hand side matrix
4682 , bool SO > // Storage order of the right-hand side matrix
4683inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4684 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator+=( const Matrix<MT,SO>& rhs )
4685{
4686 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4687
4688 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4689 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4690 }
4691
4692 if( (*rhs).canAlias( this ) ) {
4693 const ResultType_t<MT> tmp( *rhs );
4694 smpAddAssign( *this, tmp );
4695 }
4696 else {
4697 smpAddAssign( *this, *rhs );
4698 }
4699
4700 return *this;
4701}
4703//*************************************************************************************************
4704
4705
4706//*************************************************************************************************
4717template< typename Type // Data type of the matrix
4718 , AlignmentFlag AF // Alignment flag
4719 , PaddingFlag PF // Padding flag
4720 , typename Tag // Type tag
4721 , typename RT > // Result type
4722template< typename MT // Type of the right-hand side matrix
4723 , bool SO > // Storage order of the right-hand side matrix
4724inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4725 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator-=( const Matrix<MT,SO>& rhs )
4726{
4727 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4728
4729 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4730 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4731 }
4732
4733 if( (*rhs).canAlias( this ) ) {
4734 const ResultType_t<MT> tmp( *rhs );
4735 smpSubAssign( *this, tmp );
4736 }
4737 else {
4738 smpSubAssign( *this, *rhs );
4739 }
4740
4741 return *this;
4742}
4744//*************************************************************************************************
4745
4746
4747//*************************************************************************************************
4758template< typename Type // Data type of the matrix
4759 , AlignmentFlag AF // Alignment flag
4760 , PaddingFlag PF // Padding flag
4761 , typename Tag // Type tag
4762 , typename RT > // Result type
4763template< typename MT // Type of the right-hand side matrix
4764 , bool SO > // Storage order of the right-hand side matrix
4765inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
4766 CustomMatrix<Type,AF,PF,true,Tag,RT>::operator%=( const Matrix<MT,SO>& rhs )
4767{
4768 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4769
4770 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
4771 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4772 }
4773
4774 if( (*rhs).canAlias( this ) ) {
4775 const ResultType_t<MT> tmp( *rhs );
4776 smpSchurAssign( *this, tmp );
4777 }
4778 else {
4779 smpSchurAssign( *this, *rhs );
4780 }
4781
4782 return *this;
4783}
4785//*************************************************************************************************
4786
4787
4788
4789
4790//=================================================================================================
4791//
4792// UTILITY FUNCTIONS
4793//
4794//=================================================================================================
4795
4796//*************************************************************************************************
4802template< typename Type // Data type of the matrix
4803 , AlignmentFlag AF // Alignment flag
4804 , PaddingFlag PF // Padding flag
4805 , typename Tag // Type tag
4806 , typename RT > // Result type
4807inline size_t CustomMatrix<Type,AF,PF,true,Tag,RT>::rows() const noexcept
4808{
4809 return m_;
4810}
4812//*************************************************************************************************
4813
4814
4815//*************************************************************************************************
4821template< typename Type // Data type of the matrix
4822 , AlignmentFlag AF // Alignment flag
4823 , PaddingFlag PF // Padding flag
4824 , typename Tag // Type tag
4825 , typename RT > // Result type
4826inline size_t CustomMatrix<Type,AF,PF,true,Tag,RT>::columns() const noexcept
4827{
4828 return n_;
4829}
4831//*************************************************************************************************
4832
4833
4834//*************************************************************************************************
4843template< typename Type // Data type of the matrix
4844 , AlignmentFlag AF // Alignment flag
4845 , PaddingFlag PF // Padding flag
4846 , typename Tag // Type tag
4847 , typename RT > // Result type
4848inline size_t CustomMatrix<Type,AF,PF,true,Tag,RT>::spacing() const noexcept
4849{
4850 return mm_;
4851}
4853//*************************************************************************************************
4854
4855
4856//*************************************************************************************************
4862template< typename Type // Data type of the matrix
4863 , AlignmentFlag AF // Alignment flag
4864 , PaddingFlag PF // Padding flag
4865 , typename Tag // Type tag
4866 , typename RT > // Result type
4867inline size_t CustomMatrix<Type,AF,PF,true,Tag,RT>::capacity() const noexcept
4868{
4869 return mm_ * n_;
4870}
4872//*************************************************************************************************
4873
4874
4875//*************************************************************************************************
4882template< typename Type // Data type of the matrix
4883 , AlignmentFlag AF // Alignment flag
4884 , PaddingFlag PF // Padding flag
4885 , typename Tag // Type tag
4886 , typename RT > // Result type
4887inline size_t CustomMatrix<Type,AF,PF,true,Tag,RT>::capacity( size_t j ) const noexcept
4888{
4889 MAYBE_UNUSED( j );
4890 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4891 return mm_;
4892}
4894//*************************************************************************************************
4895
4896
4897//*************************************************************************************************
4907template< typename Type // Data type of the matrix
4908 , AlignmentFlag AF // Alignment flag
4909 , PaddingFlag PF // Padding flag
4910 , typename Tag // Type tag
4911 , typename RT > // Result type
4913{
4914 size_t nonzeros( 0UL );
4915
4916 for( size_t j=0UL; j<n_; ++j )
4917 for( size_t i=0UL; i<m_; ++i )
4918 if( !isDefault<strict>( v_[i+j*mm_] ) )
4919 ++nonzeros;
4920
4921 return nonzeros;
4922}
4924//*************************************************************************************************
4925
4926
4927//*************************************************************************************************
4937template< typename Type // Data type of the matrix
4938 , AlignmentFlag AF // Alignment flag
4939 , PaddingFlag PF // Padding flag
4940 , typename Tag // Type tag
4941 , typename RT > // Result type
4942inline size_t CustomMatrix<Type,AF,PF,true,Tag,RT>::nonZeros( size_t j ) const
4943{
4944 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4945
4946 const size_t iend( j*mm_ + m_ );
4947 size_t nonzeros( 0UL );
4948
4949 for( size_t i=j*mm_; i<iend; ++i )
4950 if( !isDefault<strict>( v_[i] ) )
4951 ++nonzeros;
4952
4953 return nonzeros;
4954}
4956//*************************************************************************************************
4957
4958
4959//*************************************************************************************************
4965template< typename Type // Data type of the matrix
4966 , AlignmentFlag AF // Alignment flag
4967 , PaddingFlag PF // Padding flag
4968 , typename Tag // Type tag
4969 , typename RT > // Result type
4971{
4972 using blaze::clear;
4973
4974 for( size_t j=0UL; j<n_; ++j )
4975 for( size_t i=0UL; i<m_; ++i )
4976 clear( v_[i+j*mm_] );
4977}
4979//*************************************************************************************************
4980
4981
4982//*************************************************************************************************
4992template< typename Type // Data type of the matrix
4993 , AlignmentFlag AF // Alignment flag
4994 , PaddingFlag PF // Padding flag
4995 , typename Tag // Type tag
4996 , typename RT > // Result type
4997inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::reset( size_t j )
4998{
4999 using blaze::clear;
5000
5001 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5002 for( size_t i=0UL; i<m_; ++i )
5003 clear( v_[i+j*mm_] );
5004}
5006//*************************************************************************************************
5007
5008
5009//*************************************************************************************************
5017template< typename Type // Data type of the matrix
5018 , AlignmentFlag AF // Alignment flag
5019 , PaddingFlag PF // Padding flag
5020 , typename Tag // Type tag
5021 , typename RT > // Result type
5023{
5024 m_ = 0UL;
5025 mm_ = 0UL;
5026 n_ = 0UL;
5027 v_ = nullptr;
5028}
5030//*************************************************************************************************
5031
5032
5033//*************************************************************************************************
5040template< typename Type // Data type of the matrix
5041 , AlignmentFlag AF // Alignment flag
5042 , PaddingFlag PF // Padding flag
5043 , typename Tag // Type tag
5044 , typename RT > // Result type
5045inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::swap( CustomMatrix& m ) noexcept
5046{
5047 using std::swap;
5048
5049 swap( m_ , m.m_ );
5050 swap( mm_, m.mm_ );
5051 swap( n_ , m.n_ );
5052 swap( v_ , m.v_ );
5053}
5055//*************************************************************************************************
5056
5057
5058
5059
5060//=================================================================================================
5061//
5062// NUMERIC FUNCTIONS
5063//
5064//=================================================================================================
5065
5066//*************************************************************************************************
5075template< typename Type // Data type of the matrix
5076 , AlignmentFlag AF // Alignment flag
5077 , PaddingFlag PF // Padding flag
5078 , typename Tag // Type tag
5079 , typename RT > // Result type
5080inline CustomMatrix<Type,AF,PF,true,Tag,RT>& CustomMatrix<Type,AF,PF,true,Tag,RT>::transpose()
5081{
5082 using std::swap;
5083
5084 if( m_ != n_ ) {
5085 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5086 }
5087
5088 for( size_t j=1UL; j<n_; ++j )
5089 for( size_t i=0UL; i<j; ++i )
5090 swap( v_[i+j*mm_], v_[j+i*mm_] );
5091
5092 return *this;
5093}
5095//*************************************************************************************************
5096
5097
5098//*************************************************************************************************
5107template< typename Type // Data type of the matrix
5108 , AlignmentFlag AF // Alignment flag
5109 , PaddingFlag PF // Padding flag
5110 , typename Tag // Type tag
5111 , typename RT > // Result type
5112inline CustomMatrix<Type,AF,PF,true,Tag,RT>& CustomMatrix<Type,AF,PF,true,Tag,RT>::ctranspose()
5113{
5114 if( m_ != n_ ) {
5115 BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5116 }
5117
5118 for( size_t j=0UL; j<n_; ++j ) {
5119 for( size_t i=0UL; i<j; ++i ) {
5120 cswap( v_[i+j*mm_], v_[j+i*mm_] );
5121 }
5122 conjugate( v_[j+j*mm_] );
5123 }
5124
5125 return *this;
5126}
5128//*************************************************************************************************
5129
5130
5131//*************************************************************************************************
5153template< typename Type // Data type of the matrix
5154 , AlignmentFlag AF // Alignment flag
5155 , PaddingFlag PF // Padding flag
5156 , typename Tag // Type tag
5157 , typename RT > // Result type
5158template< typename Other > // Data type of the scalar value
5159inline CustomMatrix<Type,AF,PF,true,Tag,RT>&
5160 CustomMatrix<Type,AF,PF,true,Tag,RT>::scale( const Other& scalar )
5161{
5162 for( size_t j=0UL; j<n_; ++j )
5163 for( size_t i=0UL; i<m_; ++i )
5164 v_[i+j*mm_] *= scalar;
5165
5166 return *this;
5167}
5169//*************************************************************************************************
5170
5171
5172
5173
5174//=================================================================================================
5175//
5176// RESOURCE MANAGEMENT FUNCTIONS
5177//
5178//=================================================================================================
5179
5180//*************************************************************************************************
5204template< typename Type // Data type of the matrix
5205 , AlignmentFlag AF // Alignment flag
5206 , PaddingFlag PF // Padding flag
5207 , typename Tag // Type tag
5208 , typename RT > // Result type
5209inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::reset( Type* ptr, size_t m, size_t n )
5210{
5212
5213 CustomMatrix tmp( ptr, m, n );
5214 swap( tmp );
5215}
5217//*************************************************************************************************
5218
5219
5220//*************************************************************************************************
5244template< typename Type // Data type of the matrix
5245 , AlignmentFlag AF // Alignment flag
5246 , PaddingFlag PF // Padding flag
5247 , typename Tag // Type tag
5248 , typename RT > // Result type
5249inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::reset( Type* ptr, size_t m, size_t n, size_t mm )
5250{
5251 CustomMatrix tmp( ptr, m, n, mm );
5252 swap( tmp );
5253}
5255//*************************************************************************************************
5256
5257
5258
5259
5260//=================================================================================================
5261//
5262// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5263//
5264//=================================================================================================
5265
5266//*************************************************************************************************
5277template< typename Type // Data type of the matrix
5278 , AlignmentFlag AF // Alignment flag
5279 , PaddingFlag PF // Padding flag
5280 , typename Tag // Type tag
5281 , typename RT > // Result type
5282template< typename Other > // Data type of the foreign expression
5283inline bool CustomMatrix<Type,AF,PF,true,Tag,RT>::canAlias( const Other* alias ) const noexcept
5284{
5285 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5286}
5288//*************************************************************************************************
5289
5290
5291//*************************************************************************************************
5302template< typename Type // Data type of the matrix
5303 , AlignmentFlag AF // Alignment flag
5304 , PaddingFlag PF // Padding flag
5305 , typename Tag // Type tag
5306 , typename RT > // Result type
5307template< typename Other > // Data type of the foreign expression
5308inline bool CustomMatrix<Type,AF,PF,true,Tag,RT>::isAliased( const Other* alias ) const noexcept
5309{
5310 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5311}
5313//*************************************************************************************************
5314
5315
5316//*************************************************************************************************
5326template< typename Type // Data type of the matrix
5327 , AlignmentFlag AF // Alignment flag
5328 , PaddingFlag PF // Padding flag
5329 , typename Tag // Type tag
5330 , typename RT > // Result type
5331inline bool CustomMatrix<Type,AF,PF,true,Tag,RT>::isAligned() const noexcept
5332{
5333 return ( AF || ( checkAlignment( v_ ) && rows() % SIMDSIZE == 0UL ) );
5334}
5336//*************************************************************************************************
5337
5338
5339//*************************************************************************************************
5350template< typename Type // Data type of the matrix
5351 , AlignmentFlag AF // Alignment flag
5352 , PaddingFlag PF // Padding flag
5353 , typename Tag // Type tag
5354 , typename RT > // Result type
5355inline bool CustomMatrix<Type,AF,PF,true,Tag,RT>::canSMPAssign() const noexcept
5356{
5357 return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5358}
5360//*************************************************************************************************
5361
5362
5363//*************************************************************************************************
5378template< typename Type // Data type of the matrix
5379 , AlignmentFlag AF // Alignment flag
5380 , PaddingFlag PF // Padding flag
5381 , typename Tag // Type tag
5382 , typename RT > // Result type
5384 CustomMatrix<Type,AF,PF,true,Tag,RT>::load( size_t i, size_t j ) const noexcept
5385{
5386 if( AF && PF )
5387 return loada( i, j );
5388 else
5389 return loadu( i, j );
5390}
5392//*************************************************************************************************
5393
5394
5395//*************************************************************************************************
5410template< typename Type // Data type of the matrix
5411 , AlignmentFlag AF // Alignment flag
5412 , PaddingFlag PF // Padding flag
5413 , typename Tag // Type tag
5414 , typename RT > // Result type
5416 CustomMatrix<Type,AF,PF,true,Tag,RT>::loada( size_t i, size_t j ) const noexcept
5417{
5418 using blaze::loada;
5419
5421
5422 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5423 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5424 BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5425 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5426 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5427
5428 return loada( v_+i+j*mm_ );
5429}
5431//*************************************************************************************************
5432
5433
5434//*************************************************************************************************
5449template< typename Type // Data type of the matrix
5450 , AlignmentFlag AF // Alignment flag
5451 , PaddingFlag PF // Padding flag
5452 , typename Tag // Type tag
5453 , typename RT > // Result type
5455 CustomMatrix<Type,AF,PF,true,Tag,RT>::loadu( size_t i, size_t j ) const noexcept
5456{
5457 using blaze::loadu;
5458
5460
5461 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5462 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5463 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5464
5465 return loadu( v_+i+j*mm_ );
5466}
5468//*************************************************************************************************
5469
5470
5471//*************************************************************************************************
5487template< typename Type // Data type of the matrix
5488 , AlignmentFlag AF // Alignment flag
5489 , PaddingFlag PF // Padding flag
5490 , typename Tag // Type tag
5491 , typename RT > // Result type
5493 CustomMatrix<Type,AF,PF,true,Tag,RT>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5494{
5495 if( AF && PF )
5496 storea( i, j, value );
5497 else
5498 storeu( i, j, value );
5499}
5501//*************************************************************************************************
5502
5503
5504//*************************************************************************************************
5520template< typename Type // Data type of the matrix
5521 , AlignmentFlag AF // Alignment flag
5522 , PaddingFlag PF // Padding flag
5523 , typename Tag // Type tag
5524 , typename RT > // Result type
5526 CustomMatrix<Type,AF,PF,true,Tag,RT>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5527{
5528 using blaze::storea;
5529
5531
5532 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5533 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5534 BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5535 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5536 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5537
5538 storea( v_+i+j*mm_, value );
5539}
5541//*************************************************************************************************
5542
5543
5544//*************************************************************************************************
5560template< typename Type // Data type of the matrix
5561 , AlignmentFlag AF // Alignment flag
5562 , PaddingFlag PF // Padding flag
5563 , typename Tag // Type tag
5564 , typename RT > // Result type
5566 CustomMatrix<Type,AF,PF,true,Tag,RT>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5567{
5568 using blaze::storeu;
5569
5571
5572 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5573 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5574 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5575
5576 storeu( v_+i+j*mm_, value );
5577}
5579//*************************************************************************************************
5580
5581
5582//*************************************************************************************************
5599template< typename Type // Data type of the matrix
5600 , AlignmentFlag AF // Alignment flag
5601 , PaddingFlag PF // Padding flag
5602 , typename Tag // Type tag
5603 , typename RT > // Result type
5605 CustomMatrix<Type,AF,PF,true,Tag,RT>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5606{
5607 using blaze::stream;
5608
5610
5611 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5612 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= ( PF ? mm_ : m_ ), "Invalid row access index" );
5613 BLAZE_INTERNAL_ASSERT( !PF || i % SIMDSIZE == 0UL, "Invalid row access index" );
5614 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5615 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5616
5617 stream( v_+i+j*mm_, value );
5618}
5620//*************************************************************************************************
5621
5622
5623//*************************************************************************************************
5635template< typename Type // Data type of the matrix
5636 , AlignmentFlag AF // Alignment flag
5637 , PaddingFlag PF // Padding flag
5638 , typename Tag // Type tag
5639 , typename RT > // Result type
5640template< typename MT > // Type of the right-hand side dense matrix
5641inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::assign( const DenseMatrix<MT,true>& rhs )
5642 -> DisableIf_t< VectorizedAssign_v<MT> >
5643{
5644 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5645 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5646
5647 const size_t ipos( prevMultiple( m_, 2UL ) );
5648 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
5649
5650 for( size_t j=0UL; j<n_; ++j ) {
5651 for( size_t i=0UL; i<ipos; i+=2UL ) {
5652 v_[i +j*mm_] = (*rhs)(i ,j);
5653 v_[i+1UL+j*mm_] = (*rhs)(i+1UL,j);
5654 }
5655 if( ipos < m_ ) {
5656 v_[ipos+j*mm_] = (*rhs)(ipos,j);
5657 }
5658 }
5659}
5661//*************************************************************************************************
5662
5663
5664//*************************************************************************************************
5676template< typename Type // Data type of the matrix
5677 , AlignmentFlag AF // Alignment flag
5678 , PaddingFlag PF // Padding flag
5679 , typename Tag // Type tag
5680 , typename RT > // Result type
5681template< typename MT > // Type of the right-hand side dense matrix
5682inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::assign( const DenseMatrix<MT,true>& rhs )
5683 -> EnableIf_t< VectorizedAssign_v<MT> >
5684{
5686
5687 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5688 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5689
5690 constexpr bool remainder( !PF || !IsPadded_v<MT> );
5691
5692 const size_t ipos( remainder ? prevMultiple( m_, SIMDSIZE ) : m_ );
5693 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
5694
5695 if( AF && PF && useStreaming &&
5696 ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(*rhs).isAliased( this ) )
5697 {
5698 for( size_t j=0UL; j<n_; ++j )
5699 {
5700 size_t i( 0UL );
5701 Iterator left( begin(j) );
5702 ConstIterator_t<MT> right( (*rhs).begin(j) );
5703
5704 for( ; i<ipos; i+=SIMDSIZE ) {
5705 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5706 }
5707 for( ; remainder && i<m_; ++i ) {
5708 *left = *right; ++left; ++right;
5709 }
5710 }
5711 }
5712 else
5713 {
5714 for( size_t j=0UL; j<n_; ++j )
5715 {
5716 size_t i( 0UL );
5717 Iterator left( begin(j) );
5718 ConstIterator_t<MT> right( (*rhs).begin(j) );
5719
5720 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5721 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5722 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5723 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5724 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5725 }
5726 for( ; i<ipos; i+=SIMDSIZE ) {
5727 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5728 }
5729 for( ; remainder && i<m_; ++i ) {
5730 *left = *right; ++left; ++right;
5731 }
5732 }
5733 }
5734}
5736//*************************************************************************************************
5737
5738
5739//*************************************************************************************************
5751template< typename Type // Data type of the matrix
5752 , AlignmentFlag AF // Alignment flag
5753 , PaddingFlag PF // Padding flag
5754 , typename Tag // Type tag
5755 , typename RT > // Result type
5756template< typename MT > // Type of the right-hand side dense matrix
5757inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::assign( const DenseMatrix<MT,false>& rhs )
5758{
5760
5761 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5762 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5763
5764 constexpr size_t block( BLOCK_SIZE );
5765
5766 for( size_t jj=0UL; jj<n_; jj+=block ) {
5767 const size_t jend( min( n_, jj+block ) );
5768 for( size_t ii=0UL; ii<m_; ii+=block ) {
5769 const size_t iend( min( m_, ii+block ) );
5770 for( size_t j=jj; j<jend; ++j ) {
5771 for( size_t i=ii; i<iend; ++i ) {
5772 v_[i+j*mm_] = (*rhs)(i,j);
5773 }
5774 }
5775 }
5776 }
5777}
5779//*************************************************************************************************
5780
5781
5782//*************************************************************************************************
5794template< typename Type // Data type of the matrix
5795 , AlignmentFlag AF // Alignment flag
5796 , PaddingFlag PF // Padding flag
5797 , typename Tag // Type tag
5798 , typename RT > // Result type
5799template< typename MT > // Type of the right-hand side sparse matrix
5800inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::assign( const SparseMatrix<MT,true>& rhs )
5801{
5802 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5803 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5804
5805 for( size_t j=0UL; j<(*rhs).columns(); ++j )
5806 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5807 v_[element->index()+j*mm_] = element->value();
5808}
5810//*************************************************************************************************
5811
5812
5813//*************************************************************************************************
5825template< typename Type // Data type of the matrix
5826 , AlignmentFlag AF // Alignment flag
5827 , PaddingFlag PF // Padding flag
5828 , typename Tag // Type tag
5829 , typename RT > // Result type
5830template< typename MT > // Type of the right-hand side sparse matrix
5831inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::assign( const SparseMatrix<MT,false>& rhs )
5832{
5834
5835 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5836 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5837
5838 for( size_t i=0UL; i<(*rhs).rows(); ++i )
5839 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5840 v_[i+element->index()*mm_] = element->value();
5841}
5843//*************************************************************************************************
5844
5845
5846//*************************************************************************************************
5858template< typename Type // Data type of the matrix
5859 , AlignmentFlag AF // Alignment flag
5860 , PaddingFlag PF // Padding flag
5861 , typename Tag // Type tag
5862 , typename RT > // Result type
5863template< typename MT > // Type of the right-hand side dense matrix
5864inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::addAssign( const DenseMatrix<MT,true>& rhs )
5865 -> DisableIf_t< VectorizedAddAssign_v<MT> >
5866{
5867 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5868 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5869
5870 for( size_t j=0UL; j<n_; ++j )
5871 {
5872 if( IsDiagonal_v<MT> )
5873 {
5874 v_[j+j*mm_] += (*rhs)(j,j);
5875 }
5876 else
5877 {
5878 const size_t ibegin( ( IsLower_v<MT> )
5879 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5880 :( 0UL ) );
5881 const size_t iend ( ( IsUpper_v<MT> )
5882 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5883 :( m_ ) );
5884 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5885
5886 size_t i( ibegin );
5887
5888 for( ; (i+2UL) <= iend; i+=2UL ) {
5889 v_[i +j*mm_] += (*rhs)(i ,j);
5890 v_[i+1UL+j*mm_] += (*rhs)(i+1UL,j);
5891 }
5892 if( i < iend ) {
5893 v_[i+j*mm_] += (*rhs)(i,j);
5894 }
5895 }
5896 }
5897}
5899//*************************************************************************************************
5900
5901
5902//*************************************************************************************************
5914template< typename Type // Data type of the matrix
5915 , AlignmentFlag AF // Alignment flag
5916 , PaddingFlag PF // Padding flag
5917 , typename Tag // Type tag
5918 , typename RT > // Result type
5919template< typename MT > // Type of the right-hand side dense matrix
5920inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::addAssign( const DenseMatrix<MT,true>& rhs )
5921 -> EnableIf_t< VectorizedAddAssign_v<MT> >
5922{
5925
5926 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5927 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5928
5929 constexpr bool remainder( !PF || !IsPadded_v<MT> );
5930
5931 for( size_t j=0UL; j<n_; ++j )
5932 {
5933 const size_t ibegin( ( IsLower_v<MT> )
5934 ?( prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
5935 :( 0UL ) );
5936 const size_t iend ( ( IsUpper_v<MT> )
5937 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5938 :( m_ ) );
5939 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5940
5941 const size_t ipos( remainder ? prevMultiple( iend, SIMDSIZE ) : iend );
5942 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
5943
5944 size_t i( ibegin );
5945 Iterator left( begin(j) + ibegin );
5946 ConstIterator_t<MT> right( (*rhs).begin(j) + ibegin );
5947
5948 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5949 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5950 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5951 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5952 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5953 }
5954 for( ; i<ipos; i+=SIMDSIZE ) {
5955 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5956 }
5957 for( ; remainder && i<iend; ++i ) {
5958 *left += *right; ++left; ++right;
5959 }
5960 }
5961}
5963//*************************************************************************************************
5964
5965
5966//*************************************************************************************************
5978template< typename Type // Data type of the matrix
5979 , AlignmentFlag AF // Alignment flag
5980 , PaddingFlag PF // Padding flag
5981 , typename Tag // Type tag
5982 , typename RT > // Result type
5983template< typename MT > // Type of the right-hand side dense matrix
5984inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::addAssign( const DenseMatrix<MT,false>& rhs )
5985{
5987
5988 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
5989 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
5990
5991 constexpr size_t block( BLOCK_SIZE );
5992
5993 for( size_t jj=0UL; jj<n_; jj+=block ) {
5994 const size_t jend( min( n_, jj+block ) );
5995 for( size_t ii=0UL; ii<m_; ii+=block )
5996 {
5997 if( IsLower_v<MT> && ii < jj ) continue;
5998 if( IsUpper_v<MT> && ii > jj ) break;
5999
6000 for( size_t j=jj; j<jend; ++j )
6001 {
6002 const size_t ibegin( ( IsLower_v<MT> )
6003 ?( max( ( IsStrictlyLower_v<MT> ? j+1UL : j ), ii ) )
6004 :( ii ) );
6005 const size_t iend ( ( IsUpper_v<MT> )
6006 ?( min( ( IsStrictlyUpper_v<MT> ? j : j+1UL ), m_, ii+block ) )
6007 :( min( m_, ii+block ) ) );
6008 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6009
6010 for( size_t i=ibegin; i<iend; ++i ) {
6011 v_[i+j*mm_] += (*rhs)(i,j);
6012 }
6013 }
6014 }
6015 }
6016}
6018//*************************************************************************************************
6019
6020
6021//*************************************************************************************************
6033template< typename Type // Data type of the matrix
6034 , AlignmentFlag AF // Alignment flag
6035 , PaddingFlag PF // Padding flag
6036 , typename Tag // Type tag
6037 , typename RT > // Result type
6038template< typename MT > // Type of the right-hand side sparse matrix
6039inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::addAssign( const SparseMatrix<MT,true>& rhs )
6040{
6041 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6042 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6043
6044 for( size_t j=0UL; j<(*rhs).columns(); ++j )
6045 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6046 v_[element->index()+j*mm_] += element->value();
6047}
6049//*************************************************************************************************
6050
6051
6052//*************************************************************************************************
6064template< typename Type // Data type of the matrix
6065 , AlignmentFlag AF // Alignment flag
6066 , PaddingFlag PF // Padding flag
6067 , typename Tag // Type tag
6068 , typename RT > // Result type
6069template< typename MT > // Type of the right-hand side sparse matrix
6070inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::addAssign( const SparseMatrix<MT,false>& rhs )
6071{
6073
6074 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6075 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6076
6077 for( size_t i=0UL; i<(*rhs).rows(); ++i )
6078 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6079 v_[i+element->index()*mm_] += element->value();
6080}
6082//*************************************************************************************************
6083
6084
6085//*************************************************************************************************
6097template< typename Type // Data type of the matrix
6098 , AlignmentFlag AF // Alignment flag
6099 , PaddingFlag PF // Padding flag
6100 , typename Tag // Type tag
6101 , typename RT > // Result type
6102template< typename MT > // Type of the right-hand side dense matrix
6103inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::subAssign( const DenseMatrix<MT,true>& rhs )
6104 -> DisableIf_t< VectorizedSubAssign_v<MT> >
6105{
6106 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6107 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6108
6109 for( size_t j=0UL; j<n_; ++j )
6110 {
6111 if( IsDiagonal_v<MT> )
6112 {
6113 v_[j+j*mm_] -= (*rhs)(j,j);
6114 }
6115 else
6116 {
6117 const size_t ibegin( ( IsLower_v<MT> )
6118 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
6119 :( 0UL ) );
6120 const size_t iend ( ( IsUpper_v<MT> )
6121 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6122 :( m_ ) );
6123 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6124
6125 size_t i( ibegin );
6126
6127 for( ; (i+2UL) <= iend; i+=2UL ) {
6128 v_[i +j*mm_] -= (*rhs)(i ,j);
6129 v_[i+1+j*mm_] -= (*rhs)(i+1,j);
6130 }
6131 if( i < iend ) {
6132 v_[i+j*mm_] -= (*rhs)(i,j);
6133 }
6134 }
6135 }
6136}
6138//*************************************************************************************************
6139
6140
6141//*************************************************************************************************
6154template< typename Type // Data type of the matrix
6155 , AlignmentFlag AF // Alignment flag
6156 , PaddingFlag PF // Padding flag
6157 , typename Tag // Type tag
6158 , typename RT > // Result type
6159template< typename MT > // Type of the right-hand side dense matrix
6160inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::subAssign( const DenseMatrix<MT,true>& rhs )
6161 -> EnableIf_t< VectorizedSubAssign_v<MT> >
6162{
6165
6166 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6167 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6168
6169 constexpr bool remainder( !PF || !IsPadded_v<MT> );
6170
6171 for( size_t j=0UL; j<n_; ++j )
6172 {
6173 const size_t ibegin( ( IsLower_v<MT> )
6174 ?( prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6175 :( 0UL ) );
6176 const size_t iend ( ( IsUpper_v<MT> )
6177 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6178 :( m_ ) );
6179 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6180
6181 const size_t ipos( remainder ? prevMultiple( iend, SIMDSIZE ) : iend );
6182 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
6183
6184 size_t i( ibegin );
6185 Iterator left( begin(j) + ibegin );
6186 ConstIterator_t<MT> right( (*rhs).begin(j) + ibegin );
6187
6188 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6189 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6190 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6191 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6192 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6193 }
6194 for( ; i<ipos; i+=SIMDSIZE ) {
6195 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6196 }
6197 for( ; remainder && i<iend; ++i ) {
6198 *left -= *right; ++left; ++right;
6199 }
6200 }
6201}
6203//*************************************************************************************************
6204
6205
6206//*************************************************************************************************
6218template< typename Type // Data type of the matrix
6219 , AlignmentFlag AF // Alignment flag
6220 , PaddingFlag PF // Padding flag
6221 , typename Tag // Type tag
6222 , typename RT > // Result type
6223template< typename MT > // Type of the right-hand side dense matrix
6224inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::subAssign( const DenseMatrix<MT,false>& rhs )
6225{
6227
6228 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6229 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6230
6231 constexpr size_t block( BLOCK_SIZE );
6232
6233 for( size_t jj=0UL; jj<n_; jj+=block ) {
6234 const size_t jend( min( n_, jj+block ) );
6235 for( size_t ii=0UL; ii<m_; ii+=block )
6236 {
6237 if( IsLower_v<MT> && ii < jj ) continue;
6238 if( IsUpper_v<MT> && ii > jj ) break;
6239
6240 for( size_t j=jj; j<jend; ++j )
6241 {
6242 const size_t ibegin( ( IsLower_v<MT> )
6243 ?( max( ( IsStrictlyLower_v<MT> ? j+1UL : j ), ii ) )
6244 :( ii ) );
6245 const size_t iend ( ( IsUpper_v<MT> )
6246 ?( min( ( IsStrictlyUpper_v<MT> ? j : j+1UL ), m_, ii+block ) )
6247 :( min( m_, ii+block ) ) );
6248 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6249
6250 for( size_t i=ibegin; i<iend; ++i ) {
6251 v_[i+j*mm_] -= (*rhs)(i,j);
6252 }
6253 }
6254 }
6255 }
6256}
6258//*************************************************************************************************
6259
6260
6261//*************************************************************************************************
6273template< typename Type // Data type of the matrix
6274 , AlignmentFlag AF // Alignment flag
6275 , PaddingFlag PF // Padding flag
6276 , typename Tag // Type tag
6277 , typename RT > // Result type
6278template< typename MT > // Type of the right-hand side sparse matrix
6279inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::subAssign( const SparseMatrix<MT,true>& rhs )
6280{
6281 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6282 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6283
6284 for( size_t j=0UL; j<(*rhs).columns(); ++j )
6285 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6286 v_[element->index()+j*mm_] -= element->value();
6287}
6289//*************************************************************************************************
6290
6291
6292//*************************************************************************************************
6304template< typename Type // Data type of the matrix
6305 , AlignmentFlag AF // Alignment flag
6306 , PaddingFlag PF // Padding flag
6307 , typename Tag // Type tag
6308 , typename RT > // Result type
6309template< typename MT > // Type of the right-hand side sparse matrix
6310inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::subAssign( const SparseMatrix<MT,false>& rhs )
6311{
6313
6314 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6315 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6316
6317 for( size_t i=0UL; i<(*rhs).rows(); ++i )
6318 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6319 v_[i+element->index()*mm_] -= element->value();
6320}
6322//*************************************************************************************************
6323
6324
6325//*************************************************************************************************
6337template< typename Type // Data type of the matrix
6338 , AlignmentFlag AF // Alignment flag
6339 , PaddingFlag PF // Padding flag
6340 , typename Tag // Type tag
6341 , typename RT > // Result type
6342template< typename MT > // Type of the right-hand side dense matrix
6343inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::schurAssign( const DenseMatrix<MT,true>& rhs )
6344 -> DisableIf_t< VectorizedSchurAssign_v<MT> >
6345{
6346 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6347 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6348
6349 const size_t ipos( prevMultiple( m_, 2UL ) );
6350 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6351
6352 for( size_t j=0UL; j<n_; ++j ) {
6353 for( size_t i=0UL; i<ipos; i+=2UL ) {
6354 v_[i +j*mm_] *= (*rhs)(i ,j);
6355 v_[i+1UL+j*mm_] *= (*rhs)(i+1UL,j);
6356 }
6357 if( ipos < m_ ) {
6358 v_[ipos+j*mm_] *= (*rhs)(ipos,j);
6359 }
6360 }
6361}
6363//*************************************************************************************************
6364
6365
6366//*************************************************************************************************
6379template< typename Type // Data type of the matrix
6380 , AlignmentFlag AF // Alignment flag
6381 , PaddingFlag PF // Padding flag
6382 , typename Tag // Type tag
6383 , typename RT > // Result type
6384template< typename MT > // Type of the right-hand side dense matrix
6385inline auto CustomMatrix<Type,AF,PF,true,Tag,RT>::schurAssign( const DenseMatrix<MT,true>& rhs )
6386 -> EnableIf_t< VectorizedSchurAssign_v<MT> >
6387{
6389
6390 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6391 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6392
6393 constexpr bool remainder( !PF || !IsPadded_v<MT> );
6394
6395 for( size_t j=0UL; j<n_; ++j )
6396 {
6397 const size_t ipos( remainder ? prevMultiple( m_, SIMDSIZE ) : m_ );
6398 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6399
6400 size_t i( 0UL );
6401 Iterator left( begin(j) );
6402 ConstIterator_t<MT> right( (*rhs).begin(j) );
6403
6404 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6405 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6406 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6407 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6408 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6409 }
6410 for( ; i<ipos; i+=SIMDSIZE ) {
6411 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6412 }
6413 for( ; remainder && i<m_; ++i ) {
6414 *left *= *right; ++left; ++right;
6415 }
6416 }
6417}
6419//*************************************************************************************************
6420
6421
6422//*************************************************************************************************
6434template< typename Type // Data type of the matrix
6435 , AlignmentFlag AF // Alignment flag
6436 , PaddingFlag PF // Padding flag
6437 , typename Tag // Type tag
6438 , typename RT > // Result type
6439template< typename MT > // Type of the right-hand side dense matrix
6440inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::schurAssign( const DenseMatrix<MT,false>& rhs )
6441{
6443
6444 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6445 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6446
6447 constexpr size_t block( BLOCK_SIZE );
6448
6449 for( size_t jj=0UL; jj<n_; jj+=block ) {
6450 const size_t jend( min( n_, jj+block ) );
6451 for( size_t ii=0UL; ii<m_; ii+=block ) {
6452 const size_t iend( min( m_, ii+block ) );
6453 for( size_t j=jj; j<jend; ++j ) {
6454 for( size_t i=ii; i<iend; ++i ) {
6455 v_[i+j*mm_] *= (*rhs)(i,j);
6456 }
6457 }
6458 }
6459 }
6460}
6462//*************************************************************************************************
6463
6464
6465//*************************************************************************************************
6477template< typename Type // Data type of the matrix
6478 , AlignmentFlag AF // Alignment flag
6479 , PaddingFlag PF // Padding flag
6480 , typename Tag // Type tag
6481 , typename RT > // Result type
6482template< typename MT > // Type of the right-hand side sparse matrix
6483inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::schurAssign( const SparseMatrix<MT,true>& rhs )
6484{
6485 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6486 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6487
6488 const ResultType tmp( serial( *this ) );
6489
6490 reset();
6491
6492 for( size_t j=0UL; j<(*rhs).columns(); ++j )
6493 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6494 v_[element->index()+j*mm_] = tmp(element->index(),j) * element->value();
6495}
6497//*************************************************************************************************
6498
6499
6500//*************************************************************************************************
6512template< typename Type // Data type of the matrix
6513 , AlignmentFlag AF // Alignment flag
6514 , PaddingFlag PF // Padding flag
6515 , typename Tag // Type tag
6516 , typename RT > // Result type
6517template< typename MT > // Type of the right-hand side sparse matrix
6518inline void CustomMatrix<Type,AF,PF,true,Tag,RT>::schurAssign( const SparseMatrix<MT,false>& rhs )
6519{
6521
6522 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6523 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6524
6525 const ResultType tmp( serial( *this ) );
6526
6527 reset();
6528
6529 for( size_t i=0UL; i<(*rhs).rows(); ++i )
6530 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6531 v_[i+element->index()*mm_] = tmp(i,element->index()) * element->value();
6532}
6534//*************************************************************************************************
6535
6536
6537
6538
6539
6540
6541
6542
6543//=================================================================================================
6544//
6545// CUSTOMMATRIX OPERATORS
6546//
6547//=================================================================================================
6548
6549//*************************************************************************************************
6552template< RelaxationFlag RF, typename Type, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6553bool isDefault( const CustomMatrix<Type,AF,PF,SO,Tag,RT>& m );
6554
6555template< typename Type, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6556bool isIntact( const CustomMatrix<Type,AF,PF,SO,Tag,RT>& m );
6557
6558template< typename Type, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6559void swap( CustomMatrix<Type,AF,PF,SO,Tag,RT>& a, CustomMatrix<Type,AF,PF,SO,Tag,RT>& b ) noexcept;
6561//*************************************************************************************************
6562
6563
6564//*************************************************************************************************
6592template< RelaxationFlag RF // Relaxation flag
6593 , typename Type // Data type of the matrix
6594 , AlignmentFlag AF // Alignment flag
6595 , PaddingFlag PF // Padding flag
6596 , bool SO // Storage order
6597 , typename Tag // Type tag
6598 , typename RT > // Result type
6600{
6601 return ( m.rows() == 0UL && m.columns() == 0UL );
6602}
6603//*************************************************************************************************
6604
6605
6606//*************************************************************************************************
6627template< typename Type // Data type of the matrix
6628 , AlignmentFlag AF // Alignment flag
6629 , PaddingFlag PF // Padding flag
6630 , bool SO // Storage order
6631 , typename Tag // Type tag
6632 , typename RT > // Result type
6634{
6635 return ( m.rows() * m.columns() <= m.capacity() );
6636}
6637//*************************************************************************************************
6638
6639
6640//*************************************************************************************************
6648template< typename Type // Data type of the matrix
6649 , AlignmentFlag AF // Alignment flag
6650 , PaddingFlag PF // Padding flag
6651 , bool SO // Storage order
6652 , typename Tag // Type tag
6653 , typename RT > // Result type
6655{
6656 a.swap( b );
6657}
6658//*************************************************************************************************
6659
6660
6661
6662
6663//=================================================================================================
6664//
6665// HASCONSTDATAACCESS SPECIALIZATIONS
6666//
6667//=================================================================================================
6668
6669//*************************************************************************************************
6671template< typename T, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6672struct HasConstDataAccess< CustomMatrix<T,AF,PF,SO,Tag,RT> >
6673 : public TrueType
6674{};
6676//*************************************************************************************************
6677
6678
6679
6680
6681//=================================================================================================
6682//
6683// HASMUTABLEDATAACCESS SPECIALIZATIONS
6684//
6685//=================================================================================================
6686
6687//*************************************************************************************************
6689template< typename T, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6690struct HasMutableDataAccess< CustomMatrix<T,AF,PF,SO,Tag,RT> >
6691 : public TrueType
6692{};
6694//*************************************************************************************************
6695
6696
6697
6698
6699//=================================================================================================
6700//
6701// ISCUSTOM SPECIALIZATIONS
6702//
6703//=================================================================================================
6704
6705//*************************************************************************************************
6707template< typename T, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6708struct IsCustom< CustomMatrix<T,AF,PF,SO,Tag,RT> >
6709 : public TrueType
6710{};
6712//*************************************************************************************************
6713
6714
6715
6716
6717//=================================================================================================
6718//
6719// ISALIGNED SPECIALIZATIONS
6720//
6721//=================================================================================================
6722
6723//*************************************************************************************************
6725template< typename T, PaddingFlag PF, bool SO, typename Tag, typename RT >
6726struct IsAligned< CustomMatrix<T,aligned,PF,SO,Tag,RT> >
6727 : public TrueType
6728{};
6730//*************************************************************************************************
6731
6732
6733
6734
6735//=================================================================================================
6736//
6737// ISCONTIGUOUS SPECIALIZATIONS
6738//
6739//=================================================================================================
6740
6741//*************************************************************************************************
6743template< typename T, AlignmentFlag AF, PaddingFlag PF, bool SO, typename Tag, typename RT >
6744struct IsContiguous< CustomMatrix<T,AF,PF,SO,Tag,RT> >
6745 : public TrueType
6746{};
6748//*************************************************************************************************
6749
6750
6751
6752
6753
6754//=================================================================================================
6755//
6756// ISPADDED SPECIALIZATIONS
6757//
6758//=================================================================================================
6759
6760//*************************************************************************************************
6762template< typename T, AlignmentFlag AF, bool SO, typename Tag, typename RT >
6763struct IsPadded< CustomMatrix<T,AF,padded,SO,Tag,RT> >
6764 : public TrueType
6765{};
6767//*************************************************************************************************
6768
6769} // namespace blaze
6770
6771#endif
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 T1::template Rebind< T2 >::Other Rebind_t
Alias declaration for nested Rebind class templates.
Definition: Aliases.h:350
typename T::template Resize< Ns... >::Other Resize_t
Alias declaration for nested Resize class templates.
Definition: Aliases.h:430
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
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.
Definition: Aliases.h:130
Header file for the alignment check function.
Header file for the alignment flag enumeration.
Header file for run time assertion macros.
Header file for kernel specific block sizes.
Constraints on the storage order of matrix types.
Header file for the conjugate shim.
Constraint on the data type.
Header file for the CustomOppositeType type trait.
Header file for the CustomTransposeType type trait.
Header file for the DenseIterator class template.
Constraint on the data type.
Header file for the EnableIf class template.
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 If class template.
Header file for the IntegralConstant class template.
Header file for the IsAligned type trait.
Header file for the IsConst type trait.
Header file for the IsContiguous type trait.
Header file for the IsCustom type trait.
Header file for the isDefault shim.
Header file for the IsDiagonal type trait.
Header file for the IsLower type trait.
Header file for the IsPadded type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSMPAssignable type trait.
Header file for the IsSame and IsStrictlySame type traits.
Header file for the IsSparseMatrix type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsUpper type trait.
Header file for the IsVectorizable type trait.
Header file for the MAYBE_UNUSED function template.
Header file for the misalignment function.
Header file for the nextMultiple shim.
Header file for the Noop functor.
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 RemoveConst type trait.
Constraints on the storage order of matrix types.
Header file for all SIMD functionality.
Data type constraint.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Efficient implementation of a customizable matrix.
Definition: CustomMatrix.h:423
size_t n_
The current number of columns of the matrix.
Definition: CustomMatrix.h:699
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: CustomMatrix.h:2297
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: CustomMatrix.h:1011
CustomMatrix()
The default constructor for CustomMatrix.
Definition: CustomMatrix.h:742
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1171
void reset()
Reset to the default initial values.
Definition: CustomMatrix.h:1922
auto addAssign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedAddAssign_v< MT > >
Default implementation of the addition assignment of a row-major dense matrix.
Definition: CustomMatrix.h:2800
void clear()
Clearing the matrix.
Definition: CustomMatrix.h:1974
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CustomMatrix.h:486
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: CustomMatrix.h:1815
CustomTransposeType_t< RT > TransposeType
Transpose type for expression template evaluations.
Definition: CustomMatrix.h:436
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: CustomMatrix.h:1756
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: CustomMatrix.h:2274
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: CustomMatrix.h:630
CustomMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: CustomMatrix.h:1330
DenseIterator< Type, AF > Iterator
Iterator over non-constant elements.
Definition: CustomMatrix.h:449
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: CustomMatrix.h:2228
Tag TagType
Tag type of this CustomMatrix instance.
Definition: CustomMatrix.h:440
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2358
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: CustomMatrix.h:1797
Type * Pointer
Pointer to a non-constant matrix value.
Definition: CustomMatrix.h:446
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: CustomMatrix.h:1863
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1301
const Type & ConstReference
Reference to a constant matrix value.
Definition: CustomMatrix.h:445
SIMDTrait_t< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: CustomMatrix.h:439
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2397
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: CustomMatrix.h:1249
const This & CompositeType
Data type for composite expression templates.
Definition: CustomMatrix.h:442
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: CustomMatrix.h:2508
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: CustomMatrix.h:480
auto assign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedAssign_v< MT > >
Default implementation of the assignment of a row-major dense matrix.
Definition: CustomMatrix.h:2582
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: CustomMatrix.h:1223
auto schurAssign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedSchurAssign_v< MT > >
Default implementation of the Schur product assignment of a row-major dense matrix.
Definition: CustomMatrix.h:3268
CustomMatrix< Type, AF, PF, SO, Tag, RT > This
Type of this CustomMatrix instance.
Definition: CustomMatrix.h:426
CustomMatrix & transpose()
In-place transpose of the matrix.
Definition: CustomMatrix.h:2030
const Type & ReturnType
Return type for expression template evaluations.
Definition: CustomMatrix.h:441
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: CustomMatrix.h:2435
size_t nn_
The number of elements between two rows.
Definition: CustomMatrix.h:700
DenseIterator< const Type, AF > ConstIterator
Iterator over constant elements.
Definition: CustomMatrix.h:450
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: CustomMatrix.h:1074
Type ElementType
Type of the matrix elements.
Definition: CustomMatrix.h:438
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: CustomMatrix.h:1774
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: CustomMatrix.h:958
void swap(CustomMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: CustomMatrix.h:1996
Type & Reference
Reference to a non-constant matrix value.
Definition: CustomMatrix.h:444
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: CustomMatrix.h:2252
auto subAssign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedSubAssign_v< MT > >
Default implementation of the subtraction assignment of a row-major dense matrix.
Definition: CustomMatrix.h:3034
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: CustomMatrix.h:447
size_t m_
The current number of rows of the matrix.
Definition: CustomMatrix.h:698
DenseMatrix< This, SO > BaseType
Base type of this CustomMatrix instance.
Definition: CustomMatrix.h:427
~CustomMatrix()
The destructor for CustomMatrix.
Definition: CustomMatrix.h:923
Type * v_
The custom array of elements.
Definition: CustomMatrix.h:701
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: CustomMatrix.h:2326
RT ResultType
Result type for expression template evaluations.
Definition: CustomMatrix.h:430
CustomMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: CustomMatrix.h:2061
CustomOppositeType_t< RT > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CustomMatrix.h:433
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: CustomMatrix.h:2468
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: CustomMatrix.h:2547
Implementation of a generic iterator for dense vectors and matrices.
Definition: DenseIterator.h:60
Base class for dense matrices.
Definition: DenseMatrix.h:82
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.
Constraint on the data type.
Header file for the DenseMatrix base class.
Header file for the SparseMatrix base class.
Header file for the Clear functor.
#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
void swap(CustomMatrix< Type, AF, PF, SO, Tag, RT > &a, CustomMatrix< Type, AF, PF, SO, Tag, RT > &b) noexcept
Swapping the contents of two custom matrices.
Definition: CustomMatrix.h:6654
bool isIntact(const CustomMatrix< Type, AF, PF, SO, Tag, RT > &m)
Returns whether the invariants of the given custom matrix are intact.
Definition: CustomMatrix.h:6633
bool isDefault(const CustomMatrix< Type, AF, PF, SO, Tag, RT > &m)
Returns whether the given custom matrix is in default state.
Definition: CustomMatrix.h:6599
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
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Diagonal.h:79
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
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 bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.
Definition: IsDiagonal.h:148
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
typename CustomOppositeType< T >::Type CustomOppositeType_t
Auxiliary alias declaration for the CustomOppositeType type trait.
Definition: CustomOppositeType.h:83
typename CustomTransposeType< T >::Type CustomTransposeType_t
Auxiliary alias declaration for the CustomTransposeType type trait.
Definition: CustomTransposeType.h:83
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 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
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
@ 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 ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:1195
#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
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.
Definition: StaticAssert.h:112
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
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
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#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.
Header file for all forward declarations for dense vectors and matrices.
Header file for the clear shim.
Header file for the serial shim.
Generic wrapper for the clear() function.
Definition: Clear.h:61
Rebind mechanism to obtain a CustomMatrix with different data/element type.
Definition: CustomMatrix.h:457
Rebind_t< RT, RemoveConst_t< NewType > > RRT
The rebound result type.
Definition: CustomMatrix.h:458
CustomMatrix< NewType, AF, PF, SO, Tag, RRT > Other
The type of the other CustomMatrix.
Definition: CustomMatrix.h:459
Resize mechanism to obtain a CustomMatrix with different fixed dimensions.
Definition: CustomMatrix.h:468
CustomMatrix< Type, AF, PF, SO, Tag, RRT > Other
The type of the other CustomMatrix.
Definition: CustomMatrix.h:470
Resize_t< RT, NewM, NewN > RRT
The resized result type.
Definition: CustomMatrix.h:469
Generic wrapper for the null function.
Definition: Noop.h:62
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for basic type definitions.
Header file for the generic max algorithm.
Header file for the generic min algorithm.