Blaze 3.9
DynamicMatrix.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
36#define _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <array>
44#include <algorithm>
45#include <memory>
46#include <utility>
47#include <blaze/math/Aliases.h>
57#include <blaze/math/Forward.h>
66#include <blaze/math/SIMD.h>
114#include <blaze/system/Inline.h>
122#include <blaze/util/Assert.h>
128#include <blaze/util/EnableIf.h>
131#include <blaze/util/Memory.h>
132#include <blaze/util/Types.h>
138
139
140namespace blaze {
141
142//=================================================================================================
143//
144// CLASS DEFINITION
145//
146//=================================================================================================
147
148//*************************************************************************************************
236template< typename Type // Data type of the matrix
237 , bool SO // Storage order
238 , typename Alloc // Type of the allocator
239 , typename Tag > // Type tag
241 : public DenseMatrix< DynamicMatrix<Type,SO,Alloc,Tag>, SO >
242{
243 private:
244 //**********************************************************************************************
246 static constexpr AlignmentFlag align = ( usePadding ? aligned : unaligned );
247 //**********************************************************************************************
248
249 public:
250 //**Type definitions****************************************************************************
253 using ResultType = This;
254
257
260
261 using ElementType = Type;
264 using TagType = Tag;
265 using ReturnType = const Type&;
266 using CompositeType = const This&;
267
268 using Reference = Type&;
269 using ConstReference = const Type&;
270 using Pointer = Type*;
271 using ConstPointer = const Type*;
272
275 //**********************************************************************************************
276
277 //**Rebind struct definition********************************************************************
280 template< typename NewType > // Data type of the other matrix
281 struct Rebind
282 {
284 using NewAlloc = typename std::allocator_traits<Alloc>::template rebind_alloc<NewType>;
285
288 };
289 //**********************************************************************************************
290
291 //**Resize struct definition********************************************************************
294 template< size_t NewM // Number of rows of the other matrix
295 , size_t NewN > // Number of columns of the other matrix
296 struct Resize
297 {
299 };
300 //**********************************************************************************************
301
302 //**Compilation flags***************************************************************************
304
308 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
309
311
314 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
315 //**********************************************************************************************
316
317 //**Constructors********************************************************************************
320 inline DynamicMatrix( const Alloc& alloc = Alloc{} ) noexcept;
321 inline DynamicMatrix( size_t m, size_t n, const Alloc& alloc = Alloc{} );
322 inline DynamicMatrix( size_t m, size_t n, const Type& init, const Alloc& alloc = Alloc{} );
323 inline DynamicMatrix( initializer_list< initializer_list<Type> > list, const Alloc& alloc = Alloc{} );
324
325 template< typename Other >
326 inline DynamicMatrix( size_t m, size_t n, const Other* array, const Alloc& alloc = Alloc{} );
327
328 template< typename Other, size_t Rows, size_t Cols >
329 inline DynamicMatrix( const Other (&array)[Rows][Cols], const Alloc& alloc = Alloc{} );
330
331 template< typename Other, size_t Rows, size_t Cols >
332 inline DynamicMatrix( const std::array<std::array<Other,Cols>,Rows>& array, const Alloc& alloc = Alloc{} );
333
334 inline DynamicMatrix( const DynamicMatrix& m );
335 inline DynamicMatrix( DynamicMatrix&& m ) noexcept;
336
337 template< typename MT, bool SO2 >
338 inline DynamicMatrix( const Matrix<MT,SO2>& m );
340 //**********************************************************************************************
341
342 //**Destructor**********************************************************************************
345 inline ~DynamicMatrix();
347 //**********************************************************************************************
348
349 //**Data access functions***********************************************************************
352 inline Reference operator()( size_t i, size_t j ) noexcept;
353 inline ConstReference operator()( size_t i, size_t j ) const noexcept;
354 inline Reference at( size_t i, size_t j );
355 inline ConstReference at( size_t i, size_t j ) const;
356 inline Pointer data () noexcept;
357 inline ConstPointer data () const noexcept;
358 inline Pointer data ( size_t i ) noexcept;
359 inline ConstPointer data ( size_t i ) const noexcept;
360 inline Iterator begin ( size_t i ) noexcept;
361 inline ConstIterator begin ( size_t i ) const noexcept;
362 inline ConstIterator cbegin( size_t i ) const noexcept;
363 inline Iterator end ( size_t i ) noexcept;
364 inline ConstIterator end ( size_t i ) const noexcept;
365 inline ConstIterator cend ( size_t i ) const noexcept;
367 //**********************************************************************************************
368
369 //**Assignment operators************************************************************************
372 inline DynamicMatrix& operator=( const Type& rhs ) &;
373 inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list ) &;
374
375 template< typename Other, size_t Rows, size_t Cols >
376 inline DynamicMatrix& operator=( const Other (&array)[Rows][Cols] ) &;
377
378 template< typename Other, size_t Rows, size_t Cols >
379 inline DynamicMatrix& operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &;
380
381 inline DynamicMatrix& operator=( const DynamicMatrix& rhs ) &;
382 inline DynamicMatrix& operator=( DynamicMatrix&& rhs ) & noexcept;
383
384 template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs ) &;
385 template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs ) &;
386 template< typename MT, bool SO2 > inline DynamicMatrix& operator-=( const Matrix<MT,SO2>& rhs ) &;
387 template< typename MT, bool SO2 > inline DynamicMatrix& operator%=( const Matrix<MT,SO2>& rhs ) &;
389 //**********************************************************************************************
390
391 //**Utility functions***************************************************************************
394 inline size_t rows() const noexcept;
395 inline size_t columns() const noexcept;
396 inline size_t spacing() const noexcept;
397 inline size_t capacity() const noexcept;
398 inline size_t capacity( size_t i ) const noexcept;
399 inline size_t nonZeros() const;
400 inline size_t nonZeros( size_t i ) const;
401 inline void reset();
402 inline void reset( size_t i );
403 inline void clear();
404 void resize ( size_t m, size_t n, bool preserve=true );
405 inline void extend ( size_t m, size_t n, bool preserve=true );
406 inline void reserve( size_t elements );
407 inline void shrinkToFit();
408 inline void swap( DynamicMatrix& m ) noexcept;
410 //**********************************************************************************************
411
412 //**Numeric functions***************************************************************************
415 inline DynamicMatrix& transpose();
416 inline DynamicMatrix& ctranspose();
417
418 template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
420 //**********************************************************************************************
421
422 private:
423 //**********************************************************************************************
425
426 template< typename MT >
427 static constexpr bool VectorizedAssign_v =
428 ( useOptimizedKernels &&
429 simdEnabled && MT::simdEnabled &&
430 IsSIMDCombinable_v< Type, ElementType_t<MT> > );
432 //**********************************************************************************************
433
434 //**********************************************************************************************
436
437 template< typename MT >
438 static constexpr bool VectorizedAddAssign_v =
439 ( VectorizedAssign_v<MT> &&
440 HasSIMDAdd_v< Type, ElementType_t<MT> > &&
441 !IsDiagonal_v<MT> );
443 //**********************************************************************************************
444
445 //**********************************************************************************************
447
448 template< typename MT >
449 static constexpr bool VectorizedSubAssign_v =
450 ( VectorizedAssign_v<MT> &&
451 HasSIMDSub_v< Type, ElementType_t<MT> > &&
452 !IsDiagonal_v<MT> );
454 //**********************************************************************************************
455
456 //**********************************************************************************************
458
459 template< typename MT >
460 static constexpr bool VectorizedSchurAssign_v =
461 ( VectorizedAssign_v<MT> &&
462 HasSIMDMult_v< Type, ElementType_t<MT> > );
464 //**********************************************************************************************
465
466 //**********************************************************************************************
468 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
469 //**********************************************************************************************
470
471 public:
472 //**Debugging functions*************************************************************************
475 inline bool isIntact() const noexcept;
477 //**********************************************************************************************
478
479 //**Expression template evaluation functions****************************************************
482 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
483 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
484
485 inline bool isAligned () const noexcept;
486 inline bool canSMPAssign() const noexcept;
487
488 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
489 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
490 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
491
492 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
493 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
494 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
495 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
496
497 template< typename MT >
498 inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
499
500 template< typename MT >
501 inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
502
503 template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
504 template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
505 template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
506
507 template< typename MT >
508 inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
509
510 template< typename MT >
511 inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
512
513 template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
514 template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
515 template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
516
517 template< typename MT >
518 inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
519
520 template< typename MT >
521 inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
522
523 template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
524 template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
525 template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
526
527 template< typename MT >
528 inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
529
530 template< typename MT >
531 inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
532
533 template< typename MT > inline void schurAssign( const DenseMatrix<MT,!SO>& rhs );
534 template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
535 template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
537 //**********************************************************************************************
538
539 private:
540 //**Uninitialized struct definition*************************************************************
543 struct Uninitialized {};
544 //**********************************************************************************************
545
546 //**Constructors********************************************************************************
549 inline DynamicMatrix( size_t m, size_t n, size_t nn, const Alloc& alloc, Uninitialized );
550 inline DynamicMatrix( size_t m, size_t n, size_t nn, size_t capa, const Alloc& alloc, Uninitialized );
552 //**********************************************************************************************
553
554 //**Utility functions***************************************************************************
557 inline size_t addPadding( size_t value ) const noexcept;
559 //**********************************************************************************************
560
561 //**Member variables****************************************************************************
564 size_t m_;
565 size_t n_;
566 size_t nn_;
567 size_t capacity_;
568
580 BLAZE_NO_UNIQUE_ADDRESS Alloc alloc_;
582 //**********************************************************************************************
583
584 //**Compile time checks*************************************************************************
591 //**********************************************************************************************
592};
593//*************************************************************************************************
594
595
596
597
598//=================================================================================================
599//
600// DEDUCTION GUIDES
601//
602//=================================================================================================
603
604//*************************************************************************************************
605#if BLAZE_CPP17_MODE
606
607template< typename Type >
608DynamicMatrix( size_t, size_t, Type* ) -> DynamicMatrix< RemoveCV_t<Type> >;
609
610template< typename Type, size_t M, size_t N >
612
613template< typename Type, size_t M, size_t N >
614DynamicMatrix( std::array<std::array<Type,N>,M> ) -> DynamicMatrix<Type>;
615
616#endif
617//*************************************************************************************************
618
619
620
621
622//=================================================================================================
623//
624// CONSTRUCTORS
625//
626//=================================================================================================
627
628//*************************************************************************************************
633template< typename Type // Data type of the matrix
634 , bool SO // Storage order
635 , typename Alloc // Type of the allocator
636 , typename Tag > // Type tag
637inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( const Alloc& alloc ) noexcept
638 : m_ ( 0UL ) // The current number of rows of the matrix
639 , n_ ( 0UL ) // The current number of columns of the matrix
640 , nn_ ( 0UL ) // The alignment adjusted number of columns
641 , capacity_( 0UL ) // The maximum capacity of the matrix
642 , v_ ( nullptr ) // The matrix elements
643 , alloc_ ( alloc ) // The allocator of the matrix
644{}
645//*************************************************************************************************
646
647
648//*************************************************************************************************
657template< typename Type // Data type of the matrix
658 , bool SO // Storage order
659 , typename Alloc // Type of the allocator
660 , typename Tag > // Type tag
661inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, size_t nn, const Alloc& alloc, Uninitialized )
662 : DynamicMatrix( m, n, nn, m*nn, alloc, Uninitialized{} )
663{}
664//*************************************************************************************************
665
666
667//*************************************************************************************************
677template< typename Type // Data type of the matrix
678 , bool SO // Storage order
679 , typename Alloc // Type of the allocator
680 , typename Tag > // Type tag
681inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, size_t nn, size_t capa, const Alloc& alloc, Uninitialized )
682 : m_ ( m ) // The current number of rows of the matrix
683 , n_ ( n ) // The current number of columns of the matrix
684 , nn_ ( nn ) // The alignment adjusted number of columns
685 , capacity_( capa ) // The maximum capacity of the matrix
686 , v_ ( nullptr ) // The matrix elements
687 , alloc_ ( alloc ) // The allocator of the matrix
688{
689 v_ = alloc_.allocate( capacity_ );
690
691 if( !checkAlignment( v_ ) ) {
692 alloc_.deallocate( v_, capacity_ );
694 }
695}
696//*************************************************************************************************
697
698
699//*************************************************************************************************
710template< typename Type // Data type of the matrix
711 , bool SO // Storage order
712 , typename Alloc // Type of the allocator
713 , typename Tag > // Type tag
714inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, const Alloc& alloc )
715 : DynamicMatrix( m, n, addPadding(n), alloc, Uninitialized{} )
716{
717 using blaze::clear;
718
720
721 if( IsVectorizable_v<Type> && IsBuiltin_v<Type> ) {
722 for( size_t i=0UL; i<m_; ++i ) {
723 for( size_t j=n_; j<nn_; ++j ) {
724 clear( v_[i*nn_+j] );
725 }
726 }
727 }
728
729 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
730}
731//*************************************************************************************************
732
733
734//*************************************************************************************************
744template< typename Type // Data type of the matrix
745 , bool SO // Storage order
746 , typename Alloc // Type of the allocator
747 , typename Tag > // Type tag
748inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, const Type& init, const Alloc& alloc )
749 : DynamicMatrix( m, n, alloc )
750{
751 for( size_t i=0UL; i<m; ++i ) {
752 for( size_t j=0UL; j<n_; ++j ) {
753 v_[i*nn_+j] = init;
754 }
755 }
756
757 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
758}
759//*************************************************************************************************
760
761
762//*************************************************************************************************
783template< typename Type // Data type of the matrix
784 , bool SO // Storage order
785 , typename Alloc // Type of the allocator
786 , typename Tag > // Type tag
787inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( initializer_list< initializer_list<Type> > list, const Alloc& alloc )
788 : DynamicMatrix( list.size(), determineColumns( list ), alloc )
789{
790 size_t i( 0UL );
791
792 for( const auto& rowList : list ) {
793 std::fill( std::copy( rowList.begin(), rowList.end(), begin(i) ), end(i), Type() );
794 ++i;
795 }
796
797 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
798}
799//*************************************************************************************************
800
801
802//*************************************************************************************************
826template< typename Type // Data type of the matrix
827 , bool SO // Storage order
828 , typename Alloc // Type of the allocator
829 , typename Tag > // Type tag
830template< typename Other > // Data type of the initialization array
831inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, const Other* array, const Alloc& alloc )
832 : DynamicMatrix( m, n, alloc )
833{
834 for( size_t i=0UL; i<m; ++i ) {
835 for( size_t j=0UL; j<n; ++j ) {
836 v_[i*nn_+j] = array[i*n+j];
837 }
838 }
839
840 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
841}
842//*************************************************************************************************
843
844
845//*************************************************************************************************
867template< typename Type // Data type of the matrix
868 , bool SO // Storage order
869 , typename Alloc // Type of the allocator
870 , typename Tag > // Type tag
871template< typename Other // Data type of the static array
872 , size_t Rows // Number of rows of the static array
873 , size_t Cols > // Number of columns of the static array
874inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( const Other (&array)[Rows][Cols], const Alloc& alloc )
875 : DynamicMatrix( Rows, Cols, alloc )
876{
877 for( size_t i=0UL; i<Rows; ++i ) {
878 for( size_t j=0UL; j<Cols; ++j ) {
879 v_[i*nn_+j] = array[i][j];
880 }
881 }
882
883 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
884}
885//*************************************************************************************************
886
887
888//*************************************************************************************************
910template< typename Type // Data type of the matrix
911 , bool SO // Storage order
912 , typename Alloc // Type of the allocator
913 , typename Tag > // Type tag
914template< typename Other // Data type of the std::array
915 , size_t Rows // Number of rows of the std::array
916 , size_t Cols > // Number of columns of the std::array
917inline DynamicMatrix<Type,SO,Alloc,Tag>::DynamicMatrix( const std::array<std::array<Other,Cols>,Rows>& array, const Alloc& alloc )
918 : DynamicMatrix( Rows, Cols, alloc )
919{
920 for( size_t i=0UL; i<Rows; ++i ) {
921 for( size_t j=0UL; j<Cols; ++j ) {
922 v_[i*nn_+j] = array[i][j];
923 }
924 }
925
926 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
927}
928//*************************************************************************************************
929
930
931//*************************************************************************************************
939template< typename Type // Data type of the matrix
940 , bool SO // Storage order
941 , typename Alloc // Type of the allocator
942 , typename Tag > // Type tag
944 : DynamicMatrix( m.m_, m.n_ )
945{
946 BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
947
948 smpAssign( *this, m );
949
950 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
951}
952//*************************************************************************************************
953
954
955//*************************************************************************************************
960template< typename Type // Data type of the matrix
961 , bool SO // Storage order
962 , typename Alloc // Type of the allocator
963 , typename Tag > // Type tag
965 : m_ ( m.m_ ) // The current number of rows of the matrix
966 , n_ ( m.n_ ) // The current number of columns of the matrix
967 , nn_ ( m.nn_ ) // The alignment adjusted number of columns
968 , capacity_( m.capacity_ ) // The maximum capacity of the matrix
969 , v_ ( m.v_ ) // The matrix elements
970{
971 m.m_ = 0UL;
972 m.n_ = 0UL;
973 m.nn_ = 0UL;
974 m.capacity_ = 0UL;
975 m.v_ = nullptr;
976}
977//*************************************************************************************************
978
979
980//*************************************************************************************************
985template< typename Type // Data type of the matrix
986 , bool SO // Storage order
987 , typename Alloc // Type of the allocator
988 , typename Tag > // Type tag
989template< typename MT // Type of the foreign matrix
990 , bool SO2 > // Storage order of the foreign matrix
992 : DynamicMatrix( (*m).rows(), (*m).columns() )
993{
995
996 if( IsSparseMatrix_v<MT> && IsBuiltin_v<Type> ) {
997 reset();
998 }
999
1000 smpAssign( *this, *m );
1001
1002 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1003}
1004//*************************************************************************************************
1005
1006
1007
1008
1009//=================================================================================================
1010//
1011// DESTRUCTOR
1012//
1013//=================================================================================================
1014
1015//*************************************************************************************************
1018template< typename Type // Data type of the matrix
1019 , bool SO // Storage order
1020 , typename Alloc // Type of the allocator
1021 , typename Tag > // Type tag
1023{
1024 blaze::destroy_n( v_, capacity_ );
1025 alloc_.deallocate( v_, capacity_ );
1026}
1027//*************************************************************************************************
1028
1029
1030
1031
1032//=================================================================================================
1033//
1034// DATA ACCESS FUNCTIONS
1035//
1036//=================================================================================================
1037
1038//*************************************************************************************************
1048template< typename Type // Data type of the matrix
1049 , bool SO // Storage order
1050 , typename Alloc // Type of the allocator
1051 , typename Tag > // Type tag
1054{
1055 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1056 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1057 return v_[i*nn_+j];
1058}
1059//*************************************************************************************************
1060
1061
1062//*************************************************************************************************
1072template< typename Type // Data type of the matrix
1073 , bool SO // Storage order
1074 , typename Alloc // Type of the allocator
1075 , typename Tag > // Type tag
1077 DynamicMatrix<Type,SO,Alloc,Tag>::operator()( size_t i, size_t j ) const noexcept
1078{
1079 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
1080 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
1081 return v_[i*nn_+j];
1082}
1083//*************************************************************************************************
1084
1085
1086//*************************************************************************************************
1097template< typename Type // Data type of the matrix
1098 , bool SO // Storage order
1099 , typename Alloc // Type of the allocator
1100 , typename Tag > // Type tag
1103{
1104 if( i >= m_ ) {
1105 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1106 }
1107 if( j >= n_ ) {
1108 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1109 }
1110 return (*this)(i,j);
1111}
1112//*************************************************************************************************
1113
1114
1115//*************************************************************************************************
1126template< typename Type // Data type of the matrix
1127 , bool SO // Storage order
1128 , typename Alloc // Type of the allocator
1129 , typename Tag > // Type tag
1131 DynamicMatrix<Type,SO,Alloc,Tag>::at( size_t i, size_t j ) const
1132{
1133 if( i >= m_ ) {
1134 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1135 }
1136 if( j >= n_ ) {
1137 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1138 }
1139 return (*this)(i,j);
1140}
1141//*************************************************************************************************
1142
1143
1144//*************************************************************************************************
1156template< typename Type // Data type of the matrix
1157 , bool SO // Storage order
1158 , typename Alloc // Type of the allocator
1159 , typename Tag > // Type tag
1162{
1163 return v_;
1164}
1165//*************************************************************************************************
1166
1167
1168//*************************************************************************************************
1180template< typename Type // Data type of the matrix
1181 , bool SO // Storage order
1182 , typename Alloc // Type of the allocator
1183 , typename Tag > // Type tag
1186{
1187 return v_;
1188}
1189//*************************************************************************************************
1190
1191
1192//*************************************************************************************************
1200template< typename Type // Data type of the matrix
1201 , bool SO // Storage order
1202 , typename Alloc // Type of the allocator
1203 , typename Tag > // Type tag
1206{
1207 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1208 return v_ + i*nn_;
1209}
1210//*************************************************************************************************
1211
1212
1213//*************************************************************************************************
1221template< typename Type // Data type of the matrix
1222 , bool SO // Storage order
1223 , typename Alloc // Type of the allocator
1224 , typename Tag > // Type tag
1227{
1228 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1229 return v_ + i*nn_;
1230}
1231//*************************************************************************************************
1232
1233
1234//*************************************************************************************************
1245template< typename Type // Data type of the matrix
1246 , bool SO // Storage order
1247 , typename Alloc // Type of the allocator
1248 , typename Tag > // Type tag
1251{
1252 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1253 return Iterator( v_ + i*nn_ );
1254}
1255//*************************************************************************************************
1256
1257
1258//*************************************************************************************************
1269template< typename Type // Data type of the matrix
1270 , bool SO // Storage order
1271 , typename Alloc // Type of the allocator
1272 , typename Tag > // Type tag
1275{
1276 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1277 return ConstIterator( v_ + i*nn_ );
1278}
1279//*************************************************************************************************
1280
1281
1282//*************************************************************************************************
1293template< typename Type // Data type of the matrix
1294 , bool SO // Storage order
1295 , typename Alloc // Type of the allocator
1296 , typename Tag > // Type tag
1299{
1300 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1301 return ConstIterator( v_ + i*nn_ );
1302}
1303//*************************************************************************************************
1304
1305
1306//*************************************************************************************************
1317template< typename Type // Data type of the matrix
1318 , bool SO // Storage order
1319 , typename Alloc // Type of the allocator
1320 , typename Tag > // Type tag
1323{
1324 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1325 return Iterator( v_ + i*nn_ + n_ );
1326}
1327//*************************************************************************************************
1328
1329
1330//*************************************************************************************************
1341template< typename Type // Data type of the matrix
1342 , bool SO // Storage order
1343 , typename Alloc // Type of the allocator
1344 , typename Tag > // Type tag
1346 DynamicMatrix<Type,SO,Alloc,Tag>::end( size_t i ) const noexcept
1347{
1348 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1349 return ConstIterator( v_ + i*nn_ + n_ );
1350}
1351//*************************************************************************************************
1352
1353
1354//*************************************************************************************************
1365template< typename Type // Data type of the matrix
1366 , bool SO // Storage order
1367 , typename Alloc // Type of the allocator
1368 , typename Tag > // Type tag
1371{
1372 BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1373 return ConstIterator( v_ + i*nn_ + n_ );
1374}
1375//*************************************************************************************************
1376
1377
1378
1379
1380//=================================================================================================
1381//
1382// ASSIGNMENT OPERATORS
1383//
1384//=================================================================================================
1385
1386//*************************************************************************************************
1392template< typename Type // Data type of the matrix
1393 , bool SO // Storage order
1394 , typename Alloc // Type of the allocator
1395 , typename Tag > // Type tag
1398{
1399 for( size_t i=0UL; i<m_; ++i )
1400 for( size_t j=0UL; j<n_; ++j )
1401 v_[i*nn_+j] = rhs;
1402
1403 return *this;
1404}
1405//*************************************************************************************************
1406
1407
1408//*************************************************************************************************
1429template< typename Type // Data type of the matrix
1430 , bool SO // Storage order
1431 , typename Alloc // Type of the allocator
1432 , typename Tag > // Type tag
1434 DynamicMatrix<Type,SO,Alloc,Tag>::operator=( initializer_list< initializer_list<Type> > list ) &
1435{
1436 resize( list.size(), determineColumns( list ), false );
1437
1438 size_t i( 0UL );
1439
1440 for( const auto& rowList : list ) {
1441 std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
1442 ++i;
1443 }
1444
1445 return *this;
1446}
1447//*************************************************************************************************
1448
1449
1450//*************************************************************************************************
1472template< typename Type // Data type of the matrix
1473 , bool SO // Storage order
1474 , typename Alloc // Type of the allocator
1475 , typename Tag > // Type tag
1476template< typename Other // Data type of the static array
1477 , size_t Rows // Number of rows of the static array
1478 , size_t Cols > // Number of columns of the static array
1480 DynamicMatrix<Type,SO,Alloc,Tag>::operator=( const Other (&array)[Rows][Cols] ) &
1481{
1482 resize( Rows, Cols, false );
1483
1484 for( size_t i=0UL; i<Rows; ++i )
1485 for( size_t j=0UL; j<Cols; ++j )
1486 v_[i*nn_+j] = array[i][j];
1487
1488 return *this;
1489}
1490//*************************************************************************************************
1491
1492
1493//*************************************************************************************************
1515template< typename Type // Data type of the matrix
1516 , bool SO // Storage order
1517 , typename Alloc // Type of the allocator
1518 , typename Tag > // Type tag
1519template< typename Other // Data type of the std::array
1520 , size_t Rows // Number of rows of the std::array
1521 , size_t Cols > // Number of columns of the std::array
1523 DynamicMatrix<Type,SO,Alloc,Tag>::operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &
1524{
1525 resize( Rows, Cols, false );
1526
1527 for( size_t i=0UL; i<Rows; ++i )
1528 for( size_t j=0UL; j<Cols; ++j )
1529 v_[i*nn_+j] = array[i][j];
1530
1531 return *this;
1532}
1533//*************************************************************************************************
1534
1535
1536//*************************************************************************************************
1545template< typename Type // Data type of the matrix
1546 , bool SO // Storage order
1547 , typename Alloc // Type of the allocator
1548 , typename Tag > // Type tag
1551{
1552 if( &rhs == this ) return *this;
1553
1554 resize( rhs.m_, rhs.n_, false );
1555 smpAssign( *this, *rhs );
1556
1557 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1558
1559 return *this;
1560}
1561//*************************************************************************************************
1562
1563
1564//*************************************************************************************************
1570template< typename Type // Data type of the matrix
1571 , bool SO // Storage order
1572 , typename Alloc // Type of the allocator
1573 , typename Tag > // Type tag
1576{
1577 blaze::destroy_n( v_, capacity_ );
1578 alloc_.deallocate( v_, capacity_ );
1579
1580 m_ = rhs.m_;
1581 n_ = rhs.n_;
1582 nn_ = rhs.nn_;
1583 capacity_ = rhs.capacity_;
1584 v_ = rhs.v_;
1585
1586 rhs.m_ = 0UL;
1587 rhs.n_ = 0UL;
1588 rhs.nn_ = 0UL;
1589 rhs.capacity_ = 0UL;
1590 rhs.v_ = nullptr;
1591
1592 return *this;
1593}
1594//*************************************************************************************************
1595
1596
1597//*************************************************************************************************
1606template< typename Type // Data type of the matrix
1607 , bool SO // Storage order
1608 , typename Alloc // Type of the allocator
1609 , typename Tag > // Type tag
1610template< typename MT // Type of the right-hand side matrix
1611 , bool SO2 > // Storage order of the right-hand side matrix
1612inline DynamicMatrix<Type,SO,Alloc,Tag>&
1614{
1615 using TT = decltype( trans( *this ) );
1616 using CT = decltype( ctrans( *this ) );
1617 using IT = decltype( inv( *this ) );
1618
1620
1621 if( IsSame_v<MT,TT> && (*rhs).isAliased( this ) ) {
1622 transpose();
1623 }
1624 else if( IsSame_v<MT,CT> && (*rhs).isAliased( this ) ) {
1625 ctranspose();
1626 }
1627 else if( !IsSame_v<MT,IT> && (*rhs).canAlias( this ) ) {
1628 DynamicMatrix tmp( *rhs );
1629 swap( tmp );
1630 }
1631 else {
1632 resize( (*rhs).rows(), (*rhs).columns(), false );
1633 if( IsSparseMatrix_v<MT> )
1634 reset();
1635 smpAssign( *this, *rhs );
1636 }
1637
1638 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1639
1640 return *this;
1641}
1642//*************************************************************************************************
1643
1644
1645//*************************************************************************************************
1655template< typename Type // Data type of the matrix
1656 , bool SO // Storage order
1657 , typename Alloc // Type of the allocator
1658 , typename Tag > // Type tag
1659template< typename MT // Type of the right-hand side matrix
1660 , bool SO2 > // Storage order of the right-hand side matrix
1663{
1665
1666 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1667 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1668 }
1669
1670 if( (*rhs).canAlias( this ) ) {
1671 const ResultType_t<MT> tmp( *rhs );
1672 smpAddAssign( *this, tmp );
1673 }
1674 else {
1675 smpAddAssign( *this, *rhs );
1676 }
1677
1678 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1679
1680 return *this;
1681}
1682//*************************************************************************************************
1683
1684
1685//*************************************************************************************************
1695template< typename Type // Data type of the matrix
1696 , bool SO // Storage order
1697 , typename Alloc // Type of the allocator
1698 , typename Tag > // Type tag
1699template< typename MT // Type of the right-hand side matrix
1700 , bool SO2 > // Storage order of the right-hand side matrix
1703{
1705
1706 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1707 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1708 }
1709
1710 if( (*rhs).canAlias( this ) ) {
1711 const ResultType_t<MT> tmp( *rhs );
1712 smpSubAssign( *this, tmp );
1713 }
1714 else {
1715 smpSubAssign( *this, *rhs );
1716 }
1717
1718 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1719
1720 return *this;
1721}
1722//*************************************************************************************************
1723
1724
1725//*************************************************************************************************
1735template< typename Type // Data type of the matrix
1736 , bool SO // Storage order
1737 , typename Alloc // Type of the allocator
1738 , typename Tag > // Type tag
1739template< typename MT // Type of the right-hand side matrix
1740 , bool SO2 > // Storage order of the right-hand side matrix
1743{
1745
1746 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
1747 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1748 }
1749
1750 if( (*rhs).canAlias( this ) ) {
1751 const ResultType_t<MT> tmp( *rhs );
1752 smpSchurAssign( *this, tmp );
1753 }
1754 else {
1755 smpSchurAssign( *this, *rhs );
1756 }
1757
1758 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1759
1760 return *this;
1761}
1762//*************************************************************************************************
1763
1764
1765
1766
1767//=================================================================================================
1768//
1769// UTILITY FUNCTIONS
1770//
1771//=================================================================================================
1772
1773//*************************************************************************************************
1778template< typename Type // Data type of the matrix
1779 , bool SO // Storage order
1780 , typename Alloc // Type of the allocator
1781 , typename Tag > // Type tag
1782inline size_t DynamicMatrix<Type,SO,Alloc,Tag>::rows() const noexcept
1783{
1784 return m_;
1785}
1786//*************************************************************************************************
1787
1788
1789//*************************************************************************************************
1794template< typename Type // Data type of the matrix
1795 , bool SO // Storage order
1796 , typename Alloc // Type of the allocator
1797 , typename Tag > // Type tag
1798inline size_t DynamicMatrix<Type,SO,Alloc,Tag>::columns() const noexcept
1799{
1800 return n_;
1801}
1802//*************************************************************************************************
1803
1804
1805//*************************************************************************************************
1815template< typename Type // Data type of the matrix
1816 , bool SO // Storage order
1817 , typename Alloc // Type of the allocator
1818 , typename Tag > // Type tag
1819inline size_t DynamicMatrix<Type,SO,Alloc,Tag>::spacing() const noexcept
1820{
1821 return nn_;
1822}
1823//*************************************************************************************************
1824
1825
1826//*************************************************************************************************
1831template< typename Type // Data type of the matrix
1832 , bool SO // Storage order
1833 , typename Alloc // Type of the allocator
1834 , typename Tag > // Type tag
1836{
1837 return capacity_;
1838}
1839//*************************************************************************************************
1840
1841
1842//*************************************************************************************************
1853template< typename Type // Data type of the matrix
1854 , bool SO // Storage order
1855 , typename Alloc // Type of the allocator
1856 , typename Tag > // Type tag
1857inline size_t DynamicMatrix<Type,SO,Alloc,Tag>::capacity( size_t i ) const noexcept
1858{
1859 MAYBE_UNUSED( i );
1860 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1861 return nn_;
1862}
1863//*************************************************************************************************
1864
1865
1866//*************************************************************************************************
1875template< typename Type // Data type of the matrix
1876 , bool SO // Storage order
1877 , typename Alloc // Type of the allocator
1878 , typename Tag > // Type tag
1880{
1881 size_t nonzeros( 0UL );
1882
1883 for( size_t i=0UL; i<m_; ++i )
1884 for( size_t j=0UL; j<n_; ++j )
1885 if( !isDefault<strict>( v_[i*nn_+j] ) )
1886 ++nonzeros;
1887
1888 return nonzeros;
1889}
1890//*************************************************************************************************
1891
1892
1893//*************************************************************************************************
1905template< typename Type // Data type of the matrix
1906 , bool SO // Storage order
1907 , typename Alloc // Type of the allocator
1908 , typename Tag > // Type tag
1909inline size_t DynamicMatrix<Type,SO,Alloc,Tag>::nonZeros( size_t i ) const
1910{
1911 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1912
1913 const size_t jend( i*nn_ + n_ );
1914 size_t nonzeros( 0UL );
1915
1916 for( size_t j=i*nn_; j<jend; ++j )
1917 if( !isDefault<strict>( v_[j] ) )
1918 ++nonzeros;
1919
1920 return nonzeros;
1921}
1922//*************************************************************************************************
1923
1924
1925//*************************************************************************************************
1930template< typename Type // Data type of the matrix
1931 , bool SO // Storage order
1932 , typename Alloc // Type of the allocator
1933 , typename Tag > // Type tag
1935{
1936 using blaze::clear;
1937
1938 for( size_t i=0UL; i<m_; ++i )
1939 for( size_t j=0UL; j<n_; ++j )
1940 clear( v_[i*nn_+j] );
1941}
1942//*************************************************************************************************
1943
1944
1945//*************************************************************************************************
1956template< typename Type // Data type of the matrix
1957 , bool SO // Storage order
1958 , typename Alloc // Type of the allocator
1959 , typename Tag > // Type tag
1961{
1962 using blaze::clear;
1963
1964 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1965 for( size_t j=0UL; j<n_; ++j )
1966 clear( v_[i*nn_+j] );
1967}
1968//*************************************************************************************************
1969
1970
1971//*************************************************************************************************
1978template< typename Type // Data type of the matrix
1979 , bool SO // Storage order
1980 , typename Alloc // Type of the allocator
1981 , typename Tag > // Type tag
1983{
1984 resize( 0UL, 0UL, false );
1985}
1986//*************************************************************************************************
1987
1988
1989//*************************************************************************************************
2024template< typename Type // Data type of the matrix
2025 , bool SO // Storage order
2026 , typename Alloc // Type of the allocator
2027 , typename Tag > // Type tag
2028void DynamicMatrix<Type,SO,Alloc,Tag>::resize( size_t m, size_t n, bool preserve )
2029{
2030 using blaze::clear;
2031 using blaze::min;
2032
2033 if( m == m_ && n == n_ ) return;
2034
2035 const size_t nn( addPadding( n ) );
2036
2037 if( preserve )
2038 {
2039 const size_t min_m( min( m, m_ ) );
2040 const size_t min_n( min( n, n_ ) );
2041
2042 DynamicMatrix tmp( m, n, nn, Alloc{}, Uninitialized{} );
2043
2044 for( size_t i=0UL; i<min_m; ++i ) {
2045 blaze::uninitialized_transfer( v_+i*nn_, v_+i*nn_+min_n, tmp.v_+i*nn );
2046 blaze::uninitialized_default_construct( tmp.v_+i*nn+min_n, tmp.v_+i*nn+nn );
2047 }
2048 blaze::uninitialized_default_construct( tmp.v_+min_m*nn, tmp.v_+m*nn );
2049
2050 std::swap( capacity_, tmp.capacity_ );
2051 std::swap( v_, tmp.v_ );
2052 }
2053 else if( m*nn > capacity_ )
2054 {
2055 DynamicMatrix tmp( m, n, nn, Alloc{}, Uninitialized{} );
2056
2057 blaze::uninitialized_default_construct( tmp.v_, tmp.v_+tmp.capacity_ );
2058
2059 std::swap( capacity_, tmp.capacity_ );
2060 std::swap( v_, tmp.v_ );
2061 }
2062
2063 if( IsVectorizable_v<Type> ) {
2064 for( size_t i=0UL; i<m; ++i )
2065 for( size_t j=n; j<nn; ++j )
2066 clear( v_[i*nn+j] );
2067 }
2068
2069 m_ = m;
2070 n_ = n;
2071 nn_ = nn;
2072
2073 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2074}
2075//*************************************************************************************************
2076
2077
2078//*************************************************************************************************
2092template< typename Type // Data type of the matrix
2093 , bool SO // Storage order
2094 , typename Alloc // Type of the allocator
2095 , typename Tag > // Type tag
2096inline void DynamicMatrix<Type,SO,Alloc,Tag>::extend( size_t m, size_t n, bool preserve )
2097{
2098 resize( m_+m, n_+n, preserve );
2099}
2100//*************************************************************************************************
2101
2102
2103//*************************************************************************************************
2112template< typename Type // Data type of the matrix
2113 , bool SO // Storage order
2114 , typename Alloc // Type of the allocator
2115 , typename Tag > // Type tag
2117{
2118 using blaze::clear;
2119
2120 if( elements > capacity_ )
2121 {
2122 DynamicMatrix tmp( m_, n_, nn_, elements, Alloc{}, Uninitialized{} );
2123
2124 blaze::uninitialized_transfer( v_, v_+capacity_, tmp.v_ );
2125 blaze::uninitialized_value_construct( tmp.v_+capacity_, tmp.v_+elements );
2126
2127 std::swap( capacity_, tmp.capacity_ );
2128 std::swap( v_, tmp.v_ );
2129 }
2130}
2131//*************************************************************************************************
2132
2133
2134//*************************************************************************************************
2144template< typename Type // Data type of the matrix
2145 , bool SO // Storage order
2146 , typename Alloc // Type of the allocator
2147 , typename Tag > // Type tag
2149{
2150 if( ( m_ * nn_ ) < capacity_ ) {
2151 DynamicMatrix( *this ).swap( *this );
2152 }
2153}
2154//*************************************************************************************************
2155
2156
2157//*************************************************************************************************
2163template< typename Type // Data type of the matrix
2164 , bool SO // Storage order
2165 , typename Alloc // Type of the allocator
2166 , typename Tag > // Type tag
2168{
2169 using std::swap;
2170
2171 swap( m_ , m.m_ );
2172 swap( n_ , m.n_ );
2173 swap( nn_, m.nn_ );
2174 swap( capacity_, m.capacity_ );
2175 swap( v_ , m.v_ );
2176}
2177//*************************************************************************************************
2178
2179
2180//*************************************************************************************************
2189template< typename Type // Data type of the matrix
2190 , bool SO // Storage order
2191 , typename Alloc // Type of the allocator
2192 , typename Tag > // Type tag
2193inline size_t DynamicMatrix<Type,SO,Alloc,Tag>::addPadding( size_t value ) const noexcept
2194{
2195 if( usePadding && IsVectorizable_v<Type> )
2196 return nextMultiple<size_t>( value, SIMDSIZE );
2197 else return value;
2198}
2199//*************************************************************************************************
2200
2201
2202
2203
2204//=================================================================================================
2205//
2206// NUMERIC FUNCTIONS
2207//
2208//=================================================================================================
2209
2210//*************************************************************************************************
2215template< typename Type // Data type of the matrix
2216 , bool SO // Storage order
2217 , typename Alloc // Type of the allocator
2218 , typename Tag > // Type tag
2220{
2221 using std::swap;
2222
2223 constexpr size_t block( BLOCK_SIZE );
2224
2225 if( m_ == n_ )
2226 {
2227 for( size_t ii=0UL; ii<m_; ii+=block ) {
2228 const size_t iend( min( ii+block, m_ ) );
2229 for( size_t jj=0UL; jj<=ii; jj+=block ) {
2230 for( size_t i=ii; i<iend; ++i ) {
2231 const size_t jend( min( jj+block, n_, i ) );
2232 for( size_t j=jj; j<jend; ++j ) {
2233 swap( v_[i*nn_+j], v_[j*nn_+i] );
2234 }
2235 }
2236 }
2237 }
2238 }
2239 else
2240 {
2241 DynamicMatrix tmp( trans(*this) );
2242 this->swap( tmp );
2243 }
2244
2245 return *this;
2246}
2247//*************************************************************************************************
2248
2249
2250//*************************************************************************************************
2255template< typename Type // Data type of the matrix
2256 , bool SO // Storage order
2257 , typename Alloc // Type of the allocator
2258 , typename Tag > // Type tag
2260{
2261 constexpr size_t block( BLOCK_SIZE );
2262
2263 if( m_ == n_ )
2264 {
2265 for( size_t ii=0UL; ii<m_; ii+=block ) {
2266 const size_t iend( min( ii+block, m_ ) );
2267 for( size_t jj=0UL; jj<ii; jj+=block ) {
2268 const size_t jend( min( jj+block, n_ ) );
2269 for( size_t i=ii; i<iend; ++i ) {
2270 for( size_t j=jj; j<jend; ++j ) {
2271 cswap( v_[i*nn_+j], v_[j*nn_+i] );
2272 }
2273 }
2274 }
2275 for( size_t i=ii; i<iend; ++i ) {
2276 for( size_t j=ii; j<i; ++j ) {
2277 cswap( v_[i*nn_+j], v_[j*nn_+i] );
2278 }
2279 conjugate( v_[i*nn_+i] );
2280 }
2281 }
2282 }
2283 else
2284 {
2285 DynamicMatrix tmp( ctrans(*this) );
2286 swap( tmp );
2287 }
2288
2289 return *this;
2290}
2291//*************************************************************************************************
2292
2293
2294//*************************************************************************************************
2311template< typename Type // Data type of the matrix
2312 , bool SO // Storage order
2313 , typename Alloc // Type of the allocator
2314 , typename Tag > // Type tag
2315template< typename Other > // Data type of the scalar value
2318{
2319 for( size_t i=0UL; i<m_; ++i )
2320 for( size_t j=0UL; j<n_; ++j )
2321 v_[i*nn_+j] *= scalar;
2322
2323 return *this;
2324}
2325//*************************************************************************************************
2326
2327
2328
2329
2330//=================================================================================================
2331//
2332// DEBUGGING FUNCTIONS
2333//
2334//=================================================================================================
2335
2336//*************************************************************************************************
2345template< typename Type // Data type of the matrix
2346 , bool SO // Storage order
2347 , typename Alloc // Type of the allocator
2348 , typename Tag > // Type tag
2350{
2351 if( n_ > nn_ || m_ * nn_ > capacity_ )
2352 return false;
2353
2354 if( IsVectorizable_v<Type> ) {
2355 for( size_t i=0UL; i<m_; ++i ) {
2356 for( size_t j=n_; j<nn_; ++j ) {
2357 if( !isDefault<strict>( v_[i*nn_+j] ) )
2358 return false;
2359 }
2360 }
2361 }
2362
2363 return true;
2364}
2365//*************************************************************************************************
2366
2367
2368
2369
2370//=================================================================================================
2371//
2372// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2373//
2374//=================================================================================================
2375
2376//*************************************************************************************************
2386template< typename Type // Data type of the matrix
2387 , bool SO // Storage order
2388 , typename Alloc // Type of the allocator
2389 , typename Tag > // Type tag
2390template< typename Other > // Data type of the foreign expression
2391inline bool DynamicMatrix<Type,SO,Alloc,Tag>::canAlias( const Other* alias ) const noexcept
2392{
2393 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2394}
2395//*************************************************************************************************
2396
2397
2398//*************************************************************************************************
2408template< typename Type // Data type of the matrix
2409 , bool SO // Storage order
2410 , typename Alloc // Type of the allocator
2411 , typename Tag > // Type tag
2412template< typename Other > // Data type of the foreign expression
2413inline bool DynamicMatrix<Type,SO,Alloc,Tag>::isAliased( const Other* alias ) const noexcept
2414{
2415 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2416}
2417//*************************************************************************************************
2418
2419
2420//*************************************************************************************************
2429template< typename Type // Data type of the matrix
2430 , bool SO // Storage order
2431 , typename Alloc // Type of the allocator
2432 , typename Tag > // Type tag
2434{
2435 return ( usePadding || columns() % SIMDSIZE == 0UL );
2436}
2437//*************************************************************************************************
2438
2439
2440//*************************************************************************************************
2450template< typename Type // Data type of the matrix
2451 , bool SO // Storage order
2452 , typename Alloc // Type of the allocator
2453 , typename Tag > // Type tag
2455{
2456 return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2457}
2458//*************************************************************************************************
2459
2460
2461//*************************************************************************************************
2476template< typename Type // Data type of the matrix
2477 , bool SO // Storage order
2478 , typename Alloc // Type of the allocator
2479 , typename Tag > // Type tag
2481 DynamicMatrix<Type,SO,Alloc,Tag>::load( size_t i, size_t j ) const noexcept
2482{
2483 if( usePadding )
2484 return loada( i, j );
2485 else
2486 return loadu( i, j );
2487}
2488//*************************************************************************************************
2489
2490
2491//*************************************************************************************************
2506template< typename Type // Data type of the matrix
2507 , bool SO // Storage order
2508 , typename Alloc // Type of the allocator
2509 , typename Tag > // Type tag
2511 DynamicMatrix<Type,SO,Alloc,Tag>::loada( size_t i, size_t j ) const noexcept
2512{
2513 using blaze::loada;
2514
2516
2517 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2518 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2519 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2520 BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2521 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2522
2523 return loada( v_+i*nn_+j );
2524}
2525//*************************************************************************************************
2526
2527
2528//*************************************************************************************************
2543template< typename Type // Data type of the matrix
2544 , bool SO // Storage order
2545 , typename Alloc // Type of the allocator
2546 , typename Tag > // Type tag
2548 DynamicMatrix<Type,SO,Alloc,Tag>::loadu( size_t i, size_t j ) const noexcept
2549{
2550 using blaze::loadu;
2551
2553
2554 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2555 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2556 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2557
2558 return loadu( v_+i*nn_+j );
2559}
2560//*************************************************************************************************
2561
2562
2563//*************************************************************************************************
2579template< typename Type // Data type of the matrix
2580 , bool SO // Storage order
2581 , typename Alloc // Type of the allocator
2582 , typename Tag > // Type tag
2584 DynamicMatrix<Type,SO,Alloc,Tag>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2585{
2586 if( usePadding )
2587 storea( i, j, value );
2588 else
2589 storeu( i, j, value );
2590}
2591//*************************************************************************************************
2592
2593
2594//*************************************************************************************************
2610template< typename Type // Data type of the matrix
2611 , bool SO // Storage order
2612 , typename Alloc // Type of the allocator
2613 , typename Tag > // Type tag
2615 DynamicMatrix<Type,SO,Alloc,Tag>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2616{
2617 using blaze::storea;
2618
2620
2621 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2622 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2623 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2624 BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2625 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2626
2627 storea( v_+i*nn_+j, value );
2628}
2629//*************************************************************************************************
2630
2631
2632//*************************************************************************************************
2648template< typename Type // Data type of the matrix
2649 , bool SO // Storage order
2650 , typename Alloc // Type of the allocator
2651 , typename Tag > // Type tag
2653 DynamicMatrix<Type,SO,Alloc,Tag>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2654{
2655 using blaze::storeu;
2656
2658
2659 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2660 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2661 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2662
2663 storeu( v_+i*nn_+j, value );
2664}
2665//*************************************************************************************************
2666
2667
2668//*************************************************************************************************
2685template< typename Type // Data type of the matrix
2686 , bool SO // Storage order
2687 , typename Alloc // Type of the allocator
2688 , typename Tag > // Type tag
2690 DynamicMatrix<Type,SO,Alloc,Tag>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2691{
2692 using blaze::stream;
2693
2695
2696 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2697 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2698 BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2699 BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2700 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2701
2702 stream( v_+i*nn_+j, value );
2703}
2704//*************************************************************************************************
2705
2706
2707//*************************************************************************************************
2718template< typename Type // Data type of the matrix
2719 , bool SO // Storage order
2720 , typename Alloc // Type of the allocator
2721 , typename Tag > // Type tag
2722template< typename MT > // Type of the right-hand side dense matrix
2725{
2726 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2727 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2728
2729 const size_t jpos( prevMultiple( n_, 2UL ) );
2730 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
2731
2732 for( size_t i=0UL; i<m_; ++i ) {
2733 for( size_t j=0UL; j<jpos; j+=2UL ) {
2734 v_[i*nn_+j ] = (*rhs)(i,j );
2735 v_[i*nn_+j+1UL] = (*rhs)(i,j+1UL);
2736 }
2737 if( jpos < n_ ) {
2738 v_[i*nn_+jpos] = (*rhs)(i,jpos);
2739 }
2740 }
2741}
2742//*************************************************************************************************
2743
2744
2745//*************************************************************************************************
2756template< typename Type // Data type of the matrix
2757 , bool SO // Storage order
2758 , typename Alloc // Type of the allocator
2759 , typename Tag > // Type tag
2760template< typename MT > // Type of the right-hand side dense matrix
2763{
2765
2766 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2767 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2768
2769 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2770
2771 const size_t jpos( remainder ? prevMultiple( n_, SIMDSIZE ) : n_ );
2772 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
2773
2774 if( usePadding && useStreaming &&
2775 ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) &&
2776 !(*rhs).isAliased( this ) )
2777 {
2778 for( size_t i=0UL; i<m_; ++i )
2779 {
2780 size_t j( 0UL );
2781 Iterator left( begin(i) );
2782 ConstIterator_t<MT> right( (*rhs).begin(i) );
2783
2784 for( ; j<jpos; j+=SIMDSIZE, left+=SIMDSIZE, right+=SIMDSIZE ) {
2785 left.stream( right.load() );
2786 }
2787 for( ; remainder && j<n_; ++j, ++left, ++right ) {
2788 *left = *right;
2789 }
2790 }
2791 }
2792 else
2793 {
2794 for( size_t i=0UL; i<m_; ++i )
2795 {
2796 size_t j( 0UL );
2797 Iterator left( begin(i) );
2798 ConstIterator_t<MT> right( (*rhs).begin(i) );
2799
2800 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2801 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2802 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2803 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2804 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2805 }
2806 for( ; j<jpos; j+=SIMDSIZE ) {
2807 left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2808 }
2809 for( ; remainder && j<n_; ++j ) {
2810 *left = *right; ++left; ++right;
2811 }
2812 }
2813 }
2814}
2815//*************************************************************************************************
2816
2817
2818//*************************************************************************************************
2829template< typename Type // Data type of the matrix
2830 , bool SO // Storage order
2831 , typename Alloc // Type of the allocator
2832 , typename Tag > // Type tag
2833template< typename MT > // Type of the right-hand side dense matrix
2835{
2837
2838 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2839 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2840
2841 constexpr size_t block( BLOCK_SIZE );
2842
2843 for( size_t ii=0UL; ii<m_; ii+=block ) {
2844 const size_t iend( min( m_, ii+block ) );
2845 for( size_t jj=0UL; jj<n_; jj+=block ) {
2846 const size_t jend( min( n_, jj+block ) );
2847 for( size_t i=ii; i<iend; ++i ) {
2848 for( size_t j=jj; j<jend; ++j ) {
2849 v_[i*nn_+j] = (*rhs)(i,j);
2850 }
2851 }
2852 }
2853 }
2854}
2855//*************************************************************************************************
2856
2857
2858//*************************************************************************************************
2869template< typename Type // Data type of the matrix
2870 , bool SO // Storage order
2871 , typename Alloc // Type of the allocator
2872 , typename Tag > // Type tag
2873template< typename MT > // Type of the right-hand side sparse matrix
2875{
2876 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2877 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2878
2879 for( size_t i=0UL; i<m_; ++i )
2880 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2881 v_[i*nn_+element->index()] = element->value();
2882}
2883//*************************************************************************************************
2884
2885
2886//*************************************************************************************************
2897template< typename Type // Data type of the matrix
2898 , bool SO // Storage order
2899 , typename Alloc // Type of the allocator
2900 , typename Tag > // Type tag
2901template< typename MT > // Type of the right-hand side sparse matrix
2903{
2905
2906 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2907 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2908
2909 for( size_t j=0UL; j<n_; ++j )
2910 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2911 v_[element->index()*nn_+j] = element->value();
2912}
2913//*************************************************************************************************
2914
2915
2916//*************************************************************************************************
2927template< typename Type // Data type of the matrix
2928 , bool SO // Storage order
2929 , typename Alloc // Type of the allocator
2930 , typename Tag > // Type tag
2931template< typename MT > // Type of the right-hand side dense matrix
2934{
2935 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2936 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2937
2938 for( size_t i=0UL; i<m_; ++i )
2939 {
2940 if( IsDiagonal_v<MT> )
2941 {
2942 v_[i*nn_+i] += (*rhs)(i,i);
2943 }
2944 else
2945 {
2946 const size_t jbegin( ( IsUpper_v<MT> )
2947 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2948 :( 0UL ) );
2949 const size_t jend ( ( IsLower_v<MT> )
2950 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2951 :( n_ ) );
2952 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2953
2954 size_t j( jbegin );
2955
2956 for( ; (j+2UL) <= jend; j+=2UL ) {
2957 v_[i*nn_+j ] += (*rhs)(i,j );
2958 v_[i*nn_+j+1UL] += (*rhs)(i,j+1UL);
2959 }
2960 if( j < jend ) {
2961 v_[i*nn_+j] += (*rhs)(i,j);
2962 }
2963 }
2964 }
2965}
2966//*************************************************************************************************
2967
2968
2969//*************************************************************************************************
2980template< typename Type // Data type of the matrix
2981 , bool SO // Storage order
2982 , typename Alloc // Type of the allocator
2983 , typename Tag > // Type tag
2984template< typename MT > // Type of the right-hand side dense matrix
2987{
2990
2991 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
2992 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
2993
2994 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2995
2996 for( size_t i=0UL; i<m_; ++i )
2997 {
2998 const size_t jbegin( ( IsUpper_v<MT> )
2999 ?( prevMultiple( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), SIMDSIZE ) )
3000 :( 0UL ) );
3001 const size_t jend ( ( IsLower_v<MT> )
3002 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3003 :( n_ ) );
3004 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3005
3006 const size_t jpos( remainder ? prevMultiple( jend, SIMDSIZE ) : jend );
3007 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
3008
3009 size_t j( jbegin );
3010 Iterator left( begin(i) + jbegin );
3011 ConstIterator_t<MT> right( (*rhs).begin(i) + jbegin );
3012
3013 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3014 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3015 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3016 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3017 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3018 }
3019 for( ; j<jpos; j+=SIMDSIZE ) {
3020 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3021 }
3022 for( ; remainder && j<jend; ++j ) {
3023 *left += *right; ++left; ++right;
3024 }
3025 }
3026}
3027//*************************************************************************************************
3028
3029
3030//*************************************************************************************************
3041template< typename Type // Data type of the matrix
3042 , bool SO // Storage order
3043 , typename Alloc // Type of the allocator
3044 , typename Tag > // Type tag
3045template< typename MT > // Type of the right-hand side dense matrix
3047{
3049
3050 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3051 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3052
3053 constexpr size_t block( BLOCK_SIZE );
3054
3055 for( size_t ii=0UL; ii<m_; ii+=block ) {
3056 const size_t iend( min( m_, ii+block ) );
3057 for( size_t jj=0UL; jj<n_; jj+=block )
3058 {
3059 if( IsLower_v<MT> && ii < jj ) break;
3060 if( IsUpper_v<MT> && ii > jj ) continue;
3061
3062 for( size_t i=ii; i<iend; ++i )
3063 {
3064 const size_t jbegin( ( IsUpper_v<MT> )
3065 ?( max( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), jj ) )
3066 :( jj ) );
3067 const size_t jend ( ( IsLower_v<MT> )
3068 ?( min( ( IsStrictlyLower_v<MT> ? i : i+1UL ), n_, jj+block ) )
3069 :( min( n_, jj+block ) ) );
3070 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3071
3072 for( size_t j=jbegin; j<jend; ++j ) {
3073 v_[i*nn_+j] += (*rhs)(i,j);
3074 }
3075 }
3076 }
3077 }
3078}
3079//*************************************************************************************************
3080
3081
3082//*************************************************************************************************
3093template< typename Type // Data type of the matrix
3094 , bool SO // Storage order
3095 , typename Alloc // Type of the allocator
3096 , typename Tag > // Type tag
3097template< typename MT > // Type of the right-hand side sparse matrix
3099{
3100 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3101 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3102
3103 for( size_t i=0UL; i<m_; ++i )
3104 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3105 v_[i*nn_+element->index()] += element->value();
3106}
3107//*************************************************************************************************
3108
3109
3110//*************************************************************************************************
3121template< typename Type // Data type of the matrix
3122 , bool SO // Storage order
3123 , typename Alloc // Type of the allocator
3124 , typename Tag > // Type tag
3125template< typename MT > // Type of the right-hand side sparse matrix
3127{
3129
3130 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3131 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3132
3133 for( size_t j=0UL; j<n_; ++j )
3134 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3135 v_[element->index()*nn_+j] += element->value();
3136}
3137//*************************************************************************************************
3138
3139
3140//*************************************************************************************************
3151template< typename Type // Data type of the matrix
3152 , bool SO // Storage order
3153 , typename Alloc // Type of the allocator
3154 , typename Tag > // Type tag
3155template< typename MT > // Type of the right-hand side dense matrix
3158{
3159 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3160 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3161
3162 for( size_t i=0UL; i<m_; ++i )
3163 {
3164 if( IsDiagonal_v<MT> )
3165 {
3166 v_[i*nn_+i] -= (*rhs)(i,i);
3167 }
3168 else
3169 {
3170 const size_t jbegin( ( IsUpper_v<MT> )
3171 ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
3172 :( 0UL ) );
3173 const size_t jend ( ( IsLower_v<MT> )
3174 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3175 :( n_ ) );
3176 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3177
3178 size_t j( jbegin );
3179
3180 for( ; (j+2UL) <= jend; j+=2UL ) {
3181 v_[i*nn_+j ] -= (*rhs)(i,j );
3182 v_[i*nn_+j+1UL] -= (*rhs)(i,j+1UL);
3183 }
3184 if( j < jend ) {
3185 v_[i*nn_+j] -= (*rhs)(i,j);
3186 }
3187 }
3188 }
3189}
3190//*************************************************************************************************
3191
3192
3193//*************************************************************************************************
3204template< typename Type // Data type of the matrix
3205 , bool SO // Storage order
3206 , typename Alloc // Type of the allocator
3207 , typename Tag > // Type tag
3208template< typename MT > // Type of the right-hand side dense matrix
3211{
3214
3215 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3216 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3217
3218 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
3219
3220 for( size_t i=0UL; i<m_; ++i )
3221 {
3222 const size_t jbegin( ( IsUpper_v<MT> )
3223 ?( prevMultiple( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), SIMDSIZE ) )
3224 :( 0UL ) );
3225 const size_t jend ( ( IsLower_v<MT> )
3226 ?( IsStrictlyLower_v<MT> ? i : i+1UL )
3227 :( n_ ) );
3228 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3229
3230 const size_t jpos( remainder ? prevMultiple( jend, SIMDSIZE ) : jend );
3231 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
3232
3233 size_t j( jbegin );
3234 Iterator left( begin(i) + jbegin );
3235 ConstIterator_t<MT> right( (*rhs).begin(i) + jbegin );
3236
3237 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3238 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3239 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3240 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3241 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3242 }
3243 for( ; j<jpos; j+=SIMDSIZE ) {
3244 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3245 }
3246 for( ; remainder && j<jend; ++j ) {
3247 *left -= *right; ++left; ++right;
3248 }
3249 }
3250}
3251//*************************************************************************************************
3252
3253
3254//*************************************************************************************************
3265template< typename Type // Data type of the matrix
3266 , bool SO // Storage order
3267 , typename Alloc // Type of the allocator
3268 , typename Tag > // Type tag
3269template< typename MT > // Type of the right-hand side dense matrix
3271{
3273
3274 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3275 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3276
3277 constexpr size_t block( BLOCK_SIZE );
3278
3279 for( size_t ii=0UL; ii<m_; ii+=block ) {
3280 const size_t iend( min( m_, ii+block ) );
3281 for( size_t jj=0UL; jj<n_; jj+=block )
3282 {
3283 if( IsLower_v<MT> && ii < jj ) break;
3284 if( IsUpper_v<MT> && ii > jj ) continue;
3285
3286 for( size_t i=ii; i<iend; ++i )
3287 {
3288 const size_t jbegin( ( IsUpper_v<MT> )
3289 ?( max( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), jj ) )
3290 :( jj ) );
3291 const size_t jend ( ( IsLower_v<MT> )
3292 ?( min( ( IsStrictlyLower_v<MT> ? i : i+1UL ), n_, jj+block ) )
3293 :( min( n_, jj+block ) ) );
3294 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3295
3296 for( size_t j=jbegin; j<jend; ++j ) {
3297 v_[i*nn_+j] -= (*rhs)(i,j);
3298 }
3299 }
3300 }
3301 }
3302}
3303//*************************************************************************************************
3304
3305
3306//*************************************************************************************************
3317template< typename Type // Data type of the matrix
3318 , bool SO // Storage order
3319 , typename Alloc // Type of the allocator
3320 , typename Tag > // Type tag
3321template< typename MT > // Type of the right-hand side sparse matrix
3323{
3324 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3325 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3326
3327 for( size_t i=0UL; i<m_; ++i )
3328 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
3329 v_[i*nn_+element->index()] -= element->value();
3330}
3331//*************************************************************************************************
3332
3333
3334//*************************************************************************************************
3345template< typename Type // Data type of the matrix
3346 , bool SO // Storage order
3347 , typename Alloc // Type of the allocator
3348 , typename Tag > // Type tag
3349template< typename MT > // Type of the right-hand side sparse matrix
3351{
3353
3354 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3355 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3356
3357 for( size_t j=0UL; j<n_; ++j )
3358 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
3359 v_[element->index()*nn_+j] -= element->value();
3360}
3361//*************************************************************************************************
3362
3363
3364//*************************************************************************************************
3375template< typename Type // Data type of the matrix
3376 , bool SO // Storage order
3377 , typename Alloc // Type of the allocator
3378 , typename Tag > // Type tag
3379template< typename MT > // Type of the right-hand side dense matrix
3382{
3383 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3384 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3385
3386 const size_t jpos( prevMultiple( n_, 2UL ) );
3387 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
3388
3389 for( size_t i=0UL; i<m_; ++i ) {
3390 for( size_t j=0UL; j<jpos; j+=2UL ) {
3391 v_[i*nn_+j ] *= (*rhs)(i,j );
3392 v_[i*nn_+j+1UL] *= (*rhs)(i,j+1UL);
3393 }
3394 if( jpos < n_ ) {
3395 v_[i*nn_+jpos] *= (*rhs)(i,jpos);
3396 }
3397 }
3398}
3399//*************************************************************************************************
3400
3401
3402//*************************************************************************************************
3413template< typename Type // Data type of the matrix
3414 , bool SO // Storage order
3415 , typename Alloc // Type of the allocator
3416 , typename Tag > // Type tag
3417template< typename MT > // Type of the right-hand side dense matrix
3420{
3422
3423 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3424 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3425
3426 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
3427
3428 for( size_t i=0UL; i<m_; ++i )
3429 {
3430 const size_t jpos( remainder ? prevMultiple( n_, SIMDSIZE ) : n_ );
3431 BLAZE_INTERNAL_ASSERT( jpos <= n_, "Invalid end calculation" );
3432
3433 size_t j( 0UL );
3434 Iterator left( begin(i) );
3435 ConstIterator_t<MT> right( (*rhs).begin(i) );
3436
3437 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3438 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3439 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3440 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3441 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3442 }
3443 for( ; j<jpos; j+=SIMDSIZE ) {
3444 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3445 }
3446 for( ; remainder && j<n_; ++j ) {
3447 *left *= *right; ++left; ++right;
3448 }
3449 }
3450}
3451//*************************************************************************************************
3452
3453
3454//*************************************************************************************************
3465template< typename Type // Data type of the matrix
3466 , bool SO // Storage order
3467 , typename Alloc // Type of the allocator
3468 , typename Tag > // Type tag
3469template< typename MT > // Type of the right-hand side dense matrix
3471{
3473
3474 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3475 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3476
3477 constexpr size_t block( BLOCK_SIZE );
3478
3479 for( size_t ii=0UL; ii<m_; ii+=block ) {
3480 const size_t iend( min( m_, ii+block ) );
3481 for( size_t jj=0UL; jj<n_; jj+=block ) {
3482 const size_t jend( min( n_, jj+block ) );
3483 for( size_t i=ii; i<iend; ++i ) {
3484 for( size_t j=jj; j<jend; ++j ) {
3485 v_[i*nn_+j] *= (*rhs)(i,j);
3486 }
3487 }
3488 }
3489 }
3490}
3491//*************************************************************************************************
3492
3493
3494//*************************************************************************************************
3505template< typename Type // Data type of the matrix
3506 , bool SO // Storage order
3507 , typename Alloc // Type of the allocator
3508 , typename Tag > // Type tag
3509template< typename MT > // Type of the right-hand side sparse matrix
3511{
3512 using blaze::reset;
3513
3514 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3515 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3516
3517 for( size_t i=0UL; i<m_; ++i )
3518 {
3519 size_t j( 0UL );
3520
3521 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
3522 for( ; j<element->index(); ++j )
3523 reset( v_[i*nn_+j] );
3524 v_[i*nn_+j] *= element->value();
3525 ++j;
3526 }
3527
3528 for( ; j<n_; ++j ) {
3529 reset( v_[i*nn_+j] );
3530 }
3531 }
3532}
3533//*************************************************************************************************
3534
3535
3536//*************************************************************************************************
3547template< typename Type // Data type of the matrix
3548 , bool SO // Storage order
3549 , typename Alloc // Type of the allocator
3550 , typename Tag > // Type tag
3551template< typename MT > // Type of the right-hand side sparse matrix
3553{
3554 using blaze::reset;
3555
3557
3558 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
3559 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
3560
3561 for( size_t j=0UL; j<n_; ++j )
3562 {
3563 size_t i( 0UL );
3564
3565 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
3566 for( ; i<element->index(); ++i )
3567 reset( v_[i*nn_+j] );
3568 v_[i*nn_+j] *= element->value();
3569 ++i;
3570 }
3571
3572 for( ; i<m_; ++i ) {
3573 reset( v_[i*nn_+j] );
3574 }
3575 }
3576}
3577//*************************************************************************************************
3578
3579
3580
3581
3582
3583
3584
3585
3586//=================================================================================================
3587//
3588// CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3589//
3590//=================================================================================================
3591
3592//*************************************************************************************************
3600template< typename Type // Data type of the matrix
3601 , typename Alloc // Type of the allocator
3602 , typename Tag > // Type tag
3603class DynamicMatrix<Type,true,Alloc,Tag>
3604 : public DenseMatrix< DynamicMatrix<Type,true,Alloc,Tag>, true >
3605{
3606 private:
3607 //**********************************************************************************************
3609 static constexpr AlignmentFlag align = ( usePadding ? aligned : unaligned );
3610 //**********************************************************************************************
3611
3612 public:
3613 //**Type definitions****************************************************************************
3616 using ResultType = This;
3617
3620
3623
3624 using ElementType = Type;
3627 using TagType = Tag;
3628 using ReturnType = const Type&;
3629 using CompositeType = const This&;
3630
3631 using Reference = Type&;
3632 using ConstReference = const Type&;
3633 using Pointer = Type*;
3634 using ConstPointer = const Type*;
3635
3638 //**********************************************************************************************
3639
3640 //**Rebind struct definition********************************************************************
3643 template< typename NewType > // Data type of the other matrix
3644 struct Rebind
3645 {
3647 using NewAlloc = typename std::allocator_traits<Alloc>::template rebind_alloc<NewType>;
3648
3651 };
3652 //**********************************************************************************************
3653
3654 //**Resize struct definition********************************************************************
3657 template< size_t NewM // Number of rows of the other matrix
3658 , size_t NewN > // Number of columns of the other matrix
3659 struct Resize
3660 {
3661 using Other = DynamicMatrix<Type,true,Alloc,Tag>;
3662 };
3663 //**********************************************************************************************
3664
3665 //**Compilation flags***************************************************************************
3667
3671 static constexpr bool simdEnabled = IsVectorizable_v<Type>;
3672
3674
3677 static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3678 //**********************************************************************************************
3679
3680 //**Constructors********************************************************************************
3683 inline DynamicMatrix( const Alloc& alloc = Alloc{} ) noexcept;
3684 inline DynamicMatrix( size_t m, size_t n, const Alloc& alloc = Alloc{} );
3685 inline DynamicMatrix( size_t m, size_t n, const Type& init, const Alloc& alloc = Alloc{} );
3686 inline DynamicMatrix( initializer_list< initializer_list<Type> > list, const Alloc& alloc = Alloc{} );
3687
3688 template< typename Other >
3689 inline DynamicMatrix( size_t m, size_t n, const Other* array, const Alloc& alloc = Alloc{} );
3690
3691 template< typename Other, size_t Rows, size_t Cols >
3692 inline DynamicMatrix( const Other (&array)[Rows][Cols], const Alloc& alloc = Alloc{} );
3693
3694 template< typename Other, size_t Rows, size_t Cols >
3695 inline DynamicMatrix( const std::array<std::array<Other,Cols>,Rows>& array, const Alloc& alloc = Alloc{} );
3696
3697 inline DynamicMatrix( const DynamicMatrix& m );
3698 inline DynamicMatrix( DynamicMatrix&& m );
3699
3700 template< typename MT, bool SO >
3701 inline DynamicMatrix( const Matrix<MT,SO>& m );
3703 //**********************************************************************************************
3704
3705 //**Destructor**********************************************************************************
3708 inline ~DynamicMatrix();
3710 //**********************************************************************************************
3711
3712 //**Data access functions***********************************************************************
3715 inline Reference operator()( size_t i, size_t j ) noexcept;
3716 inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3717 inline Reference at( size_t i, size_t j );
3718 inline ConstReference at( size_t i, size_t j ) const;
3719 inline Pointer data () noexcept;
3720 inline ConstPointer data () const noexcept;
3721 inline Pointer data ( size_t j ) noexcept;
3722 inline ConstPointer data ( size_t j ) const noexcept;
3723 inline Iterator begin ( size_t j ) noexcept;
3724 inline ConstIterator begin ( size_t j ) const noexcept;
3725 inline ConstIterator cbegin( size_t j ) const noexcept;
3726 inline Iterator end ( size_t j ) noexcept;
3727 inline ConstIterator end ( size_t j ) const noexcept;
3728 inline ConstIterator cend ( size_t j ) const noexcept;
3730 //**********************************************************************************************
3731
3732 //**Assignment operators************************************************************************
3735 inline DynamicMatrix& operator=( const Type& rhs ) &;
3736 inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list ) &;
3737
3738 template< typename Other, size_t Rows, size_t Cols >
3739 inline DynamicMatrix& operator=( const Other (&array)[Rows][Cols] ) &;
3740
3741 template< typename Other, size_t Rows, size_t Cols >
3742 inline DynamicMatrix& operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &;
3743
3744 inline DynamicMatrix& operator=( const DynamicMatrix& rhs ) &;
3745 inline DynamicMatrix& operator=( DynamicMatrix&& rhs ) &;
3746
3747 template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs ) &;
3748 template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs ) &;
3749 template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs ) &;
3750 template< typename MT, bool SO > inline DynamicMatrix& operator%=( const Matrix<MT,SO>& rhs ) &;
3752 //**********************************************************************************************
3753
3754 //**Utility functions***************************************************************************
3757 inline size_t rows() const noexcept;
3758 inline size_t columns() const noexcept;
3759 inline size_t spacing() const noexcept;
3760 inline size_t capacity() const noexcept;
3761 inline size_t capacity( size_t j ) const noexcept;
3762 inline size_t nonZeros() const;
3763 inline size_t nonZeros( size_t j ) const;
3764 inline void reset();
3765 inline void reset( size_t j );
3766 inline void clear();
3767 void resize ( size_t m, size_t n, bool preserve=true );
3768 inline void extend ( size_t m, size_t n, bool preserve=true );
3769 inline void reserve( size_t elements );
3770 inline void shrinkToFit();
3771 inline void swap( DynamicMatrix& m ) noexcept;
3773 //**********************************************************************************************
3774
3775 //**Numeric functions***************************************************************************
3778 inline DynamicMatrix& transpose();
3779 inline DynamicMatrix& ctranspose();
3780
3781 template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
3783 //**********************************************************************************************
3784
3785 private:
3786 //**********************************************************************************************
3788 template< typename MT >
3789 static constexpr bool VectorizedAssign_v =
3790 ( useOptimizedKernels &&
3791 simdEnabled && MT::simdEnabled &&
3792 IsSIMDCombinable_v< Type, ElementType_t<MT> > );
3793 //**********************************************************************************************
3794
3795 //**********************************************************************************************
3797 template< typename MT >
3798 static constexpr bool VectorizedAddAssign_v =
3799 ( VectorizedAssign_v<MT> &&
3800 HasSIMDAdd_v< Type, ElementType_t<MT> > &&
3801 !IsDiagonal_v<MT> );
3802 //**********************************************************************************************
3803
3804 //**********************************************************************************************
3806 template< typename MT >
3807 static constexpr bool VectorizedSubAssign_v =
3808 ( VectorizedAssign_v<MT> &&
3809 HasSIMDSub_v< Type, ElementType_t<MT> > &&
3810 !IsDiagonal_v<MT> );
3811 //**********************************************************************************************
3812
3813 //**********************************************************************************************
3815 template< typename MT >
3816 static constexpr bool VectorizedSchurAssign_v =
3817 ( VectorizedAssign_v<MT> &&
3818 HasSIMDMult_v< Type, ElementType_t<MT> > );
3819 //**********************************************************************************************
3820
3821 //**********************************************************************************************
3823 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
3824 //**********************************************************************************************
3825
3826 public:
3827 //**Debugging functions*************************************************************************
3830 inline bool isIntact() const noexcept;
3832 //**********************************************************************************************
3833
3834 //**Expression template evaluation functions****************************************************
3837 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3838 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3839
3840 inline bool isAligned () const noexcept;
3841 inline bool canSMPAssign() const noexcept;
3842
3843 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3844 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3845 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3846
3847 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3848 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3849 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3850 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3851
3852 template< typename MT >
3853 inline auto assign( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
3854
3855 template< typename MT >
3856 inline auto assign( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
3857
3858 template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3859 template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3860 template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3861
3862 template< typename MT >
3863 inline auto addAssign( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
3864
3865 template< typename MT >
3866 inline auto addAssign( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
3867
3868 template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3869 template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3870 template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3871
3872 template< typename MT >
3873 inline auto subAssign ( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
3874
3875 template< typename MT >
3876 inline auto subAssign ( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
3877
3878 template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3879 template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3880 template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3881
3882 template< typename MT >
3883 inline auto schurAssign ( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
3884
3885 template< typename MT >
3886 inline auto schurAssign ( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
3887
3888 template< typename MT > inline void schurAssign( const DenseMatrix<MT,false>& rhs );
3889 template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3890 template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3892 //**********************************************************************************************
3893
3894 private:
3895 //**Uninitialized struct definition*************************************************************
3898 struct Uninitialized {};
3899 //**********************************************************************************************
3900
3901 //**Constructors********************************************************************************
3904 inline DynamicMatrix( size_t m, size_t mm, size_t n, const Alloc& alloc, Uninitialized );
3905 inline DynamicMatrix( size_t m, size_t mm, size_t n, size_t capa, const Alloc& alloc, Uninitialized );
3907 //**********************************************************************************************
3908
3909 //**Utility functions***************************************************************************
3912 inline size_t addPadding( size_t minRows ) const noexcept;
3914 //**********************************************************************************************
3915
3916 //**Member variables****************************************************************************
3919 size_t m_;
3920 size_t mm_;
3921 size_t n_;
3922 size_t capacity_;
3923
3924 Type* BLAZE_RESTRICT v_;
3928 BLAZE_NO_UNIQUE_ADDRESS Alloc alloc_;
3930 //**********************************************************************************************
3931
3932 //**Compile time checks*************************************************************************
3937 //**********************************************************************************************
3938};
3940//*************************************************************************************************
3941
3942
3943
3944
3945//=================================================================================================
3946//
3947// CONSTRUCTORS
3948//
3949//=================================================================================================
3950
3951//*************************************************************************************************
3957template< typename Type // Data type of the matrix
3958 , typename Alloc // Type of the allocator
3959 , typename Tag > // Type tag
3960inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( const Alloc& alloc ) noexcept
3961 : m_ ( 0UL ) // The current number of rows of the matrix
3962 , mm_ ( 0UL ) // The alignment adjusted number of rows
3963 , n_ ( 0UL ) // The current number of columns of the matrix
3964 , capacity_( 0UL ) // The maximum capacity of the matrix
3965 , v_ ( nullptr ) // The matrix elements
3966 , alloc_ ( alloc ) // The allocator of the matrix
3967{}
3969//*************************************************************************************************
3970
3971
3972//*************************************************************************************************
3981template< typename Type // Data type of the matrix
3982 , typename Alloc // Type of the allocator
3983 , typename Tag > // Type tag
3984inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( size_t m, size_t mm, size_t n, const Alloc& alloc, Uninitialized )
3985 : DynamicMatrix( m, mm, n, mm*n, alloc, Uninitialized{} )
3986{}
3987//*************************************************************************************************
3988
3989
3990//*************************************************************************************************
4000template< typename Type // Data type of the matrix
4001 , typename Alloc // Type of the allocator
4002 , typename Tag > // Type tag
4003inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( size_t m, size_t mm, size_t n, size_t capa, const Alloc& alloc, Uninitialized )
4004 : m_ ( m ) // The current number of rows of the matrix
4005 , mm_ ( mm ) // The alignment adjusted number of rows
4006 , n_ ( n ) // The current number of columns of the matrix
4007 , capacity_( capa ) // The maximum capacity of the matrix
4008 , v_ ( nullptr ) // The matrix elements
4009 , alloc_ ( alloc ) // The allocator of the matrix
4010{
4011 v_ = alloc_.allocate( capacity_ );
4012
4013 if( !checkAlignment( v_ ) ) {
4014 alloc_.deallocate( v_, capacity_ );
4016 }
4017}
4018//*************************************************************************************************
4019
4020
4021//*************************************************************************************************
4033template< typename Type // Data type of the matrix
4034 , typename Alloc // Type of the allocator
4035 , typename Tag > // Type tag
4036inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, const Alloc& alloc )
4037 : DynamicMatrix( m, addPadding(m), n, alloc, Uninitialized{} )
4038{
4039 using blaze::clear;
4040
4042
4043 if( IsVectorizable_v<Type> && IsBuiltin_v<Type> ) {
4044 for( size_t j=0UL; j<n_; ++j ) {
4045 for( size_t i=m_; i<mm_; ++i ) {
4046 clear( v_[i+j*mm_] );
4047 }
4048 }
4049 }
4050
4051 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4052}
4054//*************************************************************************************************
4055
4056
4057//*************************************************************************************************
4068template< typename Type // Data type of the matrix
4069 , typename Alloc // Type of the allocator
4070 , typename Tag > // Type tag
4071inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, const Type& init, const Alloc& alloc )
4072 : DynamicMatrix( m, n, alloc )
4073{
4074 for( size_t j=0UL; j<n_; ++j ) {
4075 for( size_t i=0UL; i<m_; ++i ) {
4076 v_[i+j*mm_] = init;
4077 }
4078 }
4079
4080 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4081}
4083//*************************************************************************************************
4084
4085
4086//*************************************************************************************************
4108template< typename Type // Data type of the matrix
4109 , typename Alloc // Type of the allocator
4110 , typename Tag > // Type tag
4112 : DynamicMatrix( list.size(), determineColumns( list ), alloc )
4113{
4114 using blaze::clear;
4115
4116 size_t i( 0UL );
4117
4118 for( const auto& rowList : list ) {
4119 size_t j( 0UL );
4120 for( const auto& element : rowList ) {
4121 v_[i+j*mm_] = element;
4122 ++j;
4123 }
4124 for( ; j<n_; ++j ) {
4125 clear( v_[i+j*mm_] );
4126 }
4127 ++i;
4128 }
4129
4130 BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
4131 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4132}
4134//*************************************************************************************************
4135
4136
4137//*************************************************************************************************
4162template< typename Type // Data type of the matrix
4163 , typename Alloc // Type of the allocator
4164 , typename Tag > // Type tag
4165template< typename Other > // Data type of the initialization array
4166inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( size_t m, size_t n, const Other* array, const Alloc& alloc )
4167 : DynamicMatrix( m, n, alloc )
4168{
4169 for( size_t j=0UL; j<n; ++j ) {
4170 for( size_t i=0UL; i<m; ++i ) {
4171 v_[i+j*mm_] = array[i+j*m];
4172 }
4173 }
4174
4175 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4176}
4178//*************************************************************************************************
4179
4180
4181//*************************************************************************************************
4204template< typename Type // Data type of the matrix
4205 , typename Alloc // Type of the allocator
4206 , typename Tag > // Type tag
4207template< typename Other // Data type of the static array
4208 , size_t Rows // Number of rows of the static array
4209 , size_t Cols > // Number of columns of the static array
4210inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( const Other (&array)[Rows][Cols], const Alloc& alloc )
4211 : DynamicMatrix( Rows, Cols, alloc )
4212{
4213 for( size_t j=0UL; j<Cols; ++j ) {
4214 for( size_t i=0UL; i<Rows; ++i ) {
4215 v_[i+j*mm_] = array[i][j];
4216 }
4217 }
4218
4219 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4220}
4222//*************************************************************************************************
4223
4224
4225//*************************************************************************************************
4248template< typename Type // Data type of the matrix
4249 , typename Alloc // Type of the allocator
4250 , typename Tag > // Type tag
4251template< typename Other // Data type of the std::array
4252 , size_t Rows // Number of rows of the std::array
4253 , size_t Cols > // Number of columns of the std::array
4254inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( const std::array<std::array<Other,Cols>,Rows>& array, const Alloc& alloc )
4255 : DynamicMatrix( Rows, Cols, alloc )
4256{
4257 for( size_t j=0UL; j<Cols; ++j ) {
4258 for( size_t i=0UL; i<Rows; ++i ) {
4259 v_[i+j*mm_] = array[i][j];
4260 }
4261 }
4262
4263 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4264}
4266//*************************************************************************************************
4267
4268
4269//*************************************************************************************************
4278template< typename Type // Data type of the matrix
4279 , typename Alloc // Type of the allocator
4280 , typename Tag > // Type tag
4281inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( const DynamicMatrix& m )
4282 : DynamicMatrix( m.m_, m.n_ )
4283{
4284 BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
4285
4286 smpAssign( *this, m );
4287
4288 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4289}
4291//*************************************************************************************************
4292
4293
4294//*************************************************************************************************
4300template< typename Type // Data type of the matrix
4301 , typename Alloc // Type of the allocator
4302 , typename Tag > // Type tag
4303inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( DynamicMatrix&& m )
4304 : m_ ( m.m_ ) // The current number of rows of the matrix
4305 , mm_ ( m.mm_ ) // The alignment adjusted number of rows
4306 , n_ ( m.n_ ) // The current number of columns of the matrix
4307 , capacity_( m.capacity_ ) // The maximum capacity of the matrix
4308 , v_ ( m.v_ ) // The matrix elements
4309{
4310 m.m_ = 0UL;
4311 m.mm_ = 0UL;
4312 m.n_ = 0UL;
4313 m.capacity_ = 0UL;
4314 m.v_ = nullptr;
4315}
4317//*************************************************************************************************
4318
4319
4320//*************************************************************************************************
4326template< typename Type // Data type of the matrix
4327 , typename Alloc // Type of the allocator
4328 , typename Tag > // Type tag
4329template< typename MT // Type of the foreign matrix
4330 , bool SO > // Storage order of the foreign matrix
4331inline DynamicMatrix<Type,true,Alloc,Tag>::DynamicMatrix( const Matrix<MT,SO>& m )
4332 : DynamicMatrix( (*m).rows(), (*m).columns() )
4333{
4334 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4335
4336 if( IsSparseMatrix_v<MT> && IsBuiltin_v<Type> ) {
4337 reset();
4338 }
4339
4340 smpAssign( *this, *m );
4341
4342 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4343}
4345//*************************************************************************************************
4346
4347
4348
4349
4350//=================================================================================================
4351//
4352// DESTRUCTOR
4353//
4354//=================================================================================================
4355
4356//*************************************************************************************************
4360template< typename Type // Data type of the matrix
4361 , typename Alloc // Type of the allocator
4362 , typename Tag > // Type tag
4364{
4365 blaze::destroy_n( v_, capacity_ );
4366 alloc_.deallocate( v_, capacity_ );
4367}
4369//*************************************************************************************************
4370
4371
4372
4373
4374//=================================================================================================
4375//
4376// DATA ACCESS FUNCTIONS
4377//
4378//=================================================================================================
4379
4380//*************************************************************************************************
4391template< typename Type // Data type of the matrix
4392 , typename Alloc // Type of the allocator
4393 , typename Tag > // Type tag
4395 DynamicMatrix<Type,true,Alloc,Tag>::operator()( size_t i, size_t j ) noexcept
4396{
4397 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
4398 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
4399 return v_[i+j*mm_];
4400}
4402//*************************************************************************************************
4403
4404
4405//*************************************************************************************************
4416template< typename Type // Data type of the matrix
4417 , typename Alloc // Type of the allocator
4418 , typename Tag > // Type tag
4420 DynamicMatrix<Type,true,Alloc,Tag>::operator()( size_t i, size_t j ) const noexcept
4421{
4422 BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
4423 BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
4424 return v_[i+j*mm_];
4425}
4427//*************************************************************************************************
4428
4429
4430//*************************************************************************************************
4442template< typename Type // Data type of the matrix
4443 , typename Alloc // Type of the allocator
4444 , typename Tag > // Type tag
4446 DynamicMatrix<Type,true,Alloc,Tag>::at( size_t i, size_t j )
4447{
4448 if( i >= m_ ) {
4449 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4450 }
4451 if( j >= n_ ) {
4452 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4453 }
4454 return (*this)(i,j);
4455}
4457//*************************************************************************************************
4458
4459
4460//*************************************************************************************************
4472template< typename Type // Data type of the matrix
4473 , typename Alloc // Type of the allocator
4474 , typename Tag > // Type tag
4476 DynamicMatrix<Type,true,Alloc,Tag>::at( size_t i, size_t j ) const
4477{
4478 if( i >= m_ ) {
4479 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4480 }
4481 if( j >= n_ ) {
4482 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4483 }
4484 return (*this)(i,j);
4485}
4487//*************************************************************************************************
4488
4489
4490//*************************************************************************************************
4502template< typename Type // Data type of the matrix
4503 , typename Alloc // Type of the allocator
4504 , typename Tag > // Type tag
4507{
4508 return v_;
4509}
4511//*************************************************************************************************
4512
4513
4514//*************************************************************************************************
4526template< typename Type // Data type of the matrix
4527 , typename Alloc // Type of the allocator
4528 , typename Tag > // Type tag
4531{
4532 return v_;
4533}
4535//*************************************************************************************************
4536
4537
4538//*************************************************************************************************
4547template< typename Type // Data type of the matrix
4548 , typename Alloc // Type of the allocator
4549 , typename Tag > // Type tag
4551 DynamicMatrix<Type,true,Alloc,Tag>::data( size_t j ) noexcept
4552{
4553 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4554 return v_ + j*mm_;
4555}
4557//*************************************************************************************************
4558
4559
4560//*************************************************************************************************
4569template< typename Type // Data type of the matrix
4570 , typename Alloc // Type of the allocator
4571 , typename Tag > // Type tag
4573 DynamicMatrix<Type,true,Alloc,Tag>::data( size_t j ) const noexcept
4574{
4575 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4576 return v_ + j*mm_;
4577}
4579//*************************************************************************************************
4580
4581
4582//*************************************************************************************************
4589template< typename Type // Data type of the matrix
4590 , typename Alloc // Type of the allocator
4591 , typename Tag > // Type tag
4594{
4595 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4596 return Iterator( v_ + j*mm_ );
4597}
4599//*************************************************************************************************
4600
4601
4602//*************************************************************************************************
4609template< typename Type // Data type of the matrix
4610 , typename Alloc // Type of the allocator
4611 , typename Tag > // Type tag
4613 DynamicMatrix<Type,true,Alloc,Tag>::begin( size_t j ) const noexcept
4614{
4615 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4616 return ConstIterator( v_ + j*mm_ );
4617}
4619//*************************************************************************************************
4620
4621
4622//*************************************************************************************************
4629template< typename Type // Data type of the matrix
4630 , typename Alloc // Type of the allocator
4631 , typename Tag > // Type tag
4633 DynamicMatrix<Type,true,Alloc,Tag>::cbegin( size_t j ) const noexcept
4634{
4635 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4636 return ConstIterator( v_ + j*mm_ );
4637}
4639//*************************************************************************************************
4640
4641
4642//*************************************************************************************************
4649template< typename Type // Data type of the matrix
4650 , typename Alloc // Type of the allocator
4651 , typename Tag > // Type tag
4653 DynamicMatrix<Type,true,Alloc,Tag>::end( size_t j ) noexcept
4654{
4655 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4656 return Iterator( v_ + j*mm_ + m_ );
4657}
4659//*************************************************************************************************
4660
4661
4662//*************************************************************************************************
4669template< typename Type // Data type of the matrix
4670 , typename Alloc // Type of the allocator
4671 , typename Tag > // Type tag
4673 DynamicMatrix<Type,true,Alloc,Tag>::end( size_t j ) const noexcept
4674{
4675 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4676 return ConstIterator( v_ + j*mm_ + m_ );
4677}
4679//*************************************************************************************************
4680
4681
4682//*************************************************************************************************
4689template< typename Type // Data type of the matrix
4690 , typename Alloc // Type of the allocator
4691 , typename Tag > // Type tag
4693 DynamicMatrix<Type,true,Alloc,Tag>::cend( size_t j ) const noexcept
4694{
4695 BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4696 return ConstIterator( v_ + j*mm_ + m_ );
4697}
4699//*************************************************************************************************
4700
4701
4702
4703
4704//=================================================================================================
4705//
4706// ASSIGNMENT OPERATORS
4707//
4708//=================================================================================================
4709
4710//*************************************************************************************************
4717template< typename Type // Data type of the matrix
4718 , typename Alloc // Type of the allocator
4719 , typename Tag > // Type tag
4720inline DynamicMatrix<Type,true,Alloc,Tag>&
4722{
4723 for( size_t j=0UL; j<n_; ++j )
4724 for( size_t i=0UL; i<m_; ++i )
4725 v_[i+j*mm_] = rhs;
4726
4727 return *this;
4728}
4730//*************************************************************************************************
4731
4732
4733//*************************************************************************************************
4755template< typename Type // Data type of the matrix
4756 , typename Alloc // Type of the allocator
4757 , typename Tag > // Type tag
4758inline DynamicMatrix<Type,true,Alloc,Tag>&
4760{
4761 using blaze::clear;
4762
4763 resize( list.size(), determineColumns( list ), false );
4764
4765 size_t i( 0UL );
4766
4767 for( const auto& rowList : list ) {
4768 size_t j( 0UL );
4769 for( const auto& element : rowList ) {
4770 v_[i+j*mm_] = element;
4771 ++j;
4772 }
4773 for( ; j<n_; ++j ) {
4774 clear( v_[i+j*mm_] );
4775 }
4776 ++i;
4777 }
4778
4779 return *this;
4780}
4782//*************************************************************************************************
4783
4784
4785//*************************************************************************************************
4808template< typename Type // Data type of the matrix
4809 , typename Alloc // Type of the allocator
4810 , typename Tag > // Type tag
4811template< typename Other // Data type of the static array
4812 , size_t Rows // Number of rows of the static array
4813 , size_t Cols > // Number of columns of the static array
4814inline DynamicMatrix<Type,true,Alloc,Tag>&
4815 DynamicMatrix<Type,true,Alloc,Tag>::operator=( const Other (&array)[Rows][Cols] ) &
4816{
4817 resize( Rows, Cols, false );
4818
4819 for( size_t j=0UL; j<Cols; ++j )
4820 for( size_t i=0UL; i<Rows; ++i )
4821 v_[i+j*mm_] = array[i][j];
4822
4823 return *this;
4824}
4826//*************************************************************************************************
4827
4828
4829//*************************************************************************************************
4852template< typename Type // Data type of the matrix
4853 , typename Alloc // Type of the allocator
4854 , typename Tag > // Type tag
4855template< typename Other // Data type of the std::array
4856 , size_t Rows // Number of rows of the std::array
4857 , size_t Cols > // Number of columns of the std::array
4858inline DynamicMatrix<Type,true,Alloc,Tag>&
4859 DynamicMatrix<Type,true,Alloc,Tag>::operator=( const std::array<std::array<Other,Cols>,Rows>& array ) &
4860{
4861 resize( Rows, Cols, false );
4862
4863 for( size_t j=0UL; j<Cols; ++j )
4864 for( size_t i=0UL; i<Rows; ++i )
4865 v_[i+j*mm_] = array[i][j];
4866
4867 return *this;
4868}
4870//*************************************************************************************************
4871
4872
4873//*************************************************************************************************
4883template< typename Type // Data type of the matrix
4884 , typename Alloc // Type of the allocator
4885 , typename Tag > // Type tag
4886inline DynamicMatrix<Type,true,Alloc,Tag>&
4887 DynamicMatrix<Type,true,Alloc,Tag>::operator=( const DynamicMatrix& rhs ) &
4888{
4889 if( &rhs == this ) return *this;
4890
4891 resize( rhs.m_, rhs.n_, false );
4892 smpAssign( *this, *rhs );
4893
4894 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4895
4896 return *this;
4897}
4899//*************************************************************************************************
4900
4901
4902//*************************************************************************************************
4909template< typename Type // Data type of the matrix
4910 , typename Alloc // Type of the allocator
4911 , typename Tag > // Type tag
4912inline DynamicMatrix<Type,true,Alloc,Tag>&
4913 DynamicMatrix<Type,true,Alloc,Tag>::operator=( DynamicMatrix&& rhs ) &
4914{
4915 blaze::destroy_n( v_, capacity_ );
4916 alloc_.deallocate( v_, capacity_ );
4917
4918 m_ = rhs.m_;
4919 mm_ = rhs.mm_;
4920 n_ = rhs.n_;
4921 capacity_ = rhs.capacity_;
4922 v_ = rhs.v_;
4923
4924 rhs.m_ = 0UL;
4925 rhs.mm_ = 0UL;
4926 rhs.n_ = 0UL;
4927 rhs.capacity_ = 0UL;
4928 rhs.v_ = nullptr;
4929
4930 return *this;
4931}
4933//*************************************************************************************************
4934
4935
4936//*************************************************************************************************
4946template< typename Type // Data type of the matrix
4947 , typename Alloc // Type of the allocator
4948 , typename Tag > // Type tag
4949template< typename MT // Type of the right-hand side matrix
4950 , bool SO > // Storage order of the right-hand side matrix
4951inline DynamicMatrix<Type,true,Alloc,Tag>&
4952 DynamicMatrix<Type,true,Alloc,Tag>::operator=( const Matrix<MT,SO>& rhs ) &
4953{
4954 using TT = decltype( trans( *this ) );
4955 using CT = decltype( ctrans( *this ) );
4956 using IT = decltype( inv( *this ) );
4957
4958 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
4959
4960 if( IsSame_v<MT,TT> && (*rhs).isAliased( this ) ) {
4961 transpose();
4962 }
4963 else if( IsSame_v<MT,CT> && (*rhs).isAliased( this ) ) {
4964 ctranspose();
4965 }
4966 else if( !IsSame_v<MT,IT> && (*rhs).canAlias( this ) ) {
4967 DynamicMatrix tmp( *rhs );
4968 swap( tmp );
4969 }
4970 else {
4971 resize( (*rhs).rows(), (*rhs).columns(), false );
4972 if( IsSparseMatrix_v<MT> )
4973 reset();
4974 smpAssign( *this, *rhs );
4975 }
4976
4977 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4978
4979 return *this;
4980}
4982//*************************************************************************************************
4983
4984
4985//*************************************************************************************************
4996template< typename Type // Data type of the matrix
4997 , typename Alloc // Type of the allocator
4998 , typename Tag > // Type tag
4999template< typename MT // Type of the right-hand side matrix
5000 , bool SO > // Storage order of the right-hand side matrix
5001inline DynamicMatrix<Type,true,Alloc,Tag>&
5002 DynamicMatrix<Type,true,Alloc,Tag>::operator+=( const Matrix<MT,SO>& rhs ) &
5003{
5004 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5005
5006 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
5007 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
5008 }
5009
5010 if( (*rhs).canAlias( this ) ) {
5011 const ResultType_t<MT> tmp( *rhs );
5012 smpAddAssign( *this, tmp );
5013 }
5014 else {
5015 smpAddAssign( *this, *rhs );
5016 }
5017
5018 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5019
5020 return *this;
5021}
5023//*************************************************************************************************
5024
5025
5026//*************************************************************************************************
5037template< typename Type // Data type of the matrix
5038 , typename Alloc // Type of the allocator
5039 , typename Tag > // Type tag
5040template< typename MT // Type of the right-hand side matrix
5041 , bool SO > // Storage order of the right-hand side matrix
5042inline DynamicMatrix<Type,true,Alloc,Tag>&
5043 DynamicMatrix<Type,true,Alloc,Tag>::operator-=( const Matrix<MT,SO>& rhs ) &
5044{
5045 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5046
5047 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
5048 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
5049 }
5050
5051 if( (*rhs).canAlias( this ) ) {
5052 const ResultType_t<MT> tmp( *rhs );
5053 smpSubAssign( *this, tmp );
5054 }
5055 else {
5056 smpSubAssign( *this, *rhs );
5057 }
5058
5059 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5060
5061 return *this;
5062}
5064//*************************************************************************************************
5065
5066
5067//*************************************************************************************************
5078template< typename Type // Data type of the matrix
5079 , typename Alloc // Type of the allocator
5080 , typename Tag > // Type tag
5081template< typename MT // Type of the right-hand side matrix
5082 , bool SO > // Storage order of the right-hand side matrix
5083inline DynamicMatrix<Type,true,Alloc,Tag>&
5084 DynamicMatrix<Type,true,Alloc,Tag>::operator%=( const Matrix<MT,SO>& rhs ) &
5085{
5086 BLAZE_CONSTRAINT_MUST_BE_SAME_TAG( Tag, TagType_t<MT> );
5087
5088 if( (*rhs).rows() != m_ || (*rhs).columns() != n_ ) {
5089 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
5090 }
5091
5092 if( (*rhs).canAlias( this ) ) {
5093 const ResultType_t<MT> tmp( *rhs );
5094 smpSchurAssign( *this, tmp );
5095 }
5096 else {
5097 smpSchurAssign( *this, *rhs );
5098 }
5099
5100 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5101
5102 return *this;
5103}
5105//*************************************************************************************************
5106
5107
5108
5109
5110//=================================================================================================
5111//
5112// UTILITY FUNCTIONS
5113//
5114//=================================================================================================
5115
5116//*************************************************************************************************
5122template< typename Type // Data type of the matrix
5123 , typename Alloc // Type of the allocator
5124 , typename Tag > // Type tag
5125inline size_t DynamicMatrix<Type,true,Alloc,Tag>::rows() const noexcept
5126{
5127 return m_;
5128}
5130//*************************************************************************************************
5131
5132
5133//*************************************************************************************************
5139template< typename Type // Data type of the matrix
5140 , typename Alloc // Type of the allocator
5141 , typename Tag > // Type tag
5142inline size_t DynamicMatrix<Type,true,Alloc,Tag>::columns() const noexcept
5143{
5144 return n_;
5145}
5147//*************************************************************************************************
5148
5149
5150//*************************************************************************************************
5159template< typename Type // Data type of the matrix
5160 , typename Alloc // Type of the allocator
5161 , typename Tag > // Type tag
5162inline size_t DynamicMatrix<Type,true,Alloc,Tag>::spacing() const noexcept
5163{
5164 return mm_;
5165}
5167//*************************************************************************************************
5168
5169
5170//*************************************************************************************************
5176template< typename Type // Data type of the matrix
5177 , typename Alloc // Type of the allocator
5178 , typename Tag > // Type tag
5179inline size_t DynamicMatrix<Type,true,Alloc,Tag>::capacity() const noexcept
5180{
5181 return capacity_;
5182}
5184//*************************************************************************************************
5185
5186
5187//*************************************************************************************************
5194template< typename Type // Data type of the matrix
5195 , typename Alloc // Type of the allocator
5196 , typename Tag > // Type tag
5197inline size_t DynamicMatrix<Type,true,Alloc,Tag>::capacity( size_t j ) const noexcept
5198{
5199 MAYBE_UNUSED( j );
5200 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5201 return mm_;
5202}
5204//*************************************************************************************************
5205
5206
5207//*************************************************************************************************
5217template< typename Type // Data type of the matrix
5218 , typename Alloc // Type of the allocator
5219 , typename Tag > // Type tag
5221{
5222 size_t nonzeros( 0UL );
5223
5224 for( size_t j=0UL; j<n_; ++j )
5225 for( size_t i=0UL; i<m_; ++i )
5226 if( !isDefault<strict>( v_[i+j*mm_] ) )
5227 ++nonzeros;
5228
5229 return nonzeros;
5230}
5232//*************************************************************************************************
5233
5234
5235//*************************************************************************************************
5245template< typename Type // Data type of the matrix
5246 , typename Alloc // Type of the allocator
5247 , typename Tag > // Type tag
5248inline size_t DynamicMatrix<Type,true,Alloc,Tag>::nonZeros( size_t j ) const
5249{
5250 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5251
5252 const size_t iend( j*mm_ + m_ );
5253 size_t nonzeros( 0UL );
5254
5255 for( size_t i=j*mm_; i<iend; ++i )
5256 if( !isDefault<strict>( v_[i] ) )
5257 ++nonzeros;
5258
5259 return nonzeros;
5260}
5262//*************************************************************************************************
5263
5264
5265//*************************************************************************************************
5271template< typename Type // Data type of the matrix
5272 , typename Alloc // Type of the allocator
5273 , typename Tag > // Type tag
5275{
5276 using blaze::clear;
5277
5278 for( size_t j=0UL; j<n_; ++j )
5279 for( size_t i=0UL; i<m_; ++i )
5280 clear( v_[i+j*mm_] );
5281}
5283//*************************************************************************************************
5284
5285
5286//*************************************************************************************************
5296template< typename Type // Data type of the matrix
5297 , typename Alloc // Type of the allocator
5298 , typename Tag > // Type tag
5299inline void DynamicMatrix<Type,true,Alloc,Tag>::reset( size_t j )
5300{
5301 using blaze::clear;
5302
5303 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5304 for( size_t i=0UL; i<m_; ++i )
5305 clear( v_[i+j*mm_] );
5306}
5308//*************************************************************************************************
5309
5310
5311//*************************************************************************************************
5319template< typename Type // Data type of the matrix
5320 , typename Alloc // Type of the allocator
5321 , typename Tag > // Type tag
5323{
5324 resize( 0UL, 0UL, false );
5325}
5327//*************************************************************************************************
5328
5329
5330//*************************************************************************************************
5366template< typename Type // Data type of the matrix
5367 , typename Alloc // Type of the allocator
5368 , typename Tag > // Type tag
5369void DynamicMatrix<Type,true,Alloc,Tag>::resize( size_t m, size_t n, bool preserve )
5370{
5371 using blaze::clear;
5372 using blaze::min;
5373
5374 if( m == m_ && n == n_ ) return;
5375
5376 const size_t mm( addPadding( m ) );
5377
5378 if( preserve )
5379 {
5380 const size_t min_m( min( m, m_ ) );
5381 const size_t min_n( min( n, n_ ) );
5382
5383 DynamicMatrix tmp( m, mm, n, Alloc{}, Uninitialized{} );
5384
5385 for( size_t j=0UL; j<min_n; ++j ) {
5386 blaze::uninitialized_transfer( v_+j*mm_, v_+j*mm_+min_m, tmp.v_+j*mm );
5387 blaze::uninitialized_default_construct( tmp.v_+j*mm+min_m, tmp.v_+j*mm+mm );
5388 }
5389 blaze::uninitialized_default_construct( tmp.v_+min_n*mm, tmp.v_+mm*n );
5390
5391 std::swap( capacity_, tmp.capacity_ );
5392 std::swap( v_, tmp.v_ );
5393 }
5394 else if( mm*n > capacity_ )
5395 {
5396 DynamicMatrix tmp( m, mm, n, Alloc{}, Uninitialized{} );
5397
5398 blaze::uninitialized_default_construct( tmp.v_, tmp.v_+tmp.capacity_ );
5399
5400 std::swap( capacity_, tmp.capacity_ );
5401 std::swap( v_, tmp.v_ );
5402 }
5403
5404 if( IsVectorizable_v<Type> ) {
5405 for( size_t j=0UL; j<n; ++j )
5406 for( size_t i=m; i<mm; ++i )
5407 clear( v_[i+j*mm] );
5408 }
5409
5410 m_ = m;
5411 mm_ = mm;
5412 n_ = n;
5413
5414 BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5415}
5417//*************************************************************************************************
5418
5419
5420//*************************************************************************************************
5435template< typename Type // Data type of the matrix
5436 , typename Alloc // Type of the allocator
5437 , typename Tag > // Type tag
5438inline void DynamicMatrix<Type,true,Alloc,Tag>::extend( size_t m, size_t n, bool preserve )
5439{
5440 resize( m_+m, n_+n, preserve );
5441}
5443//*************************************************************************************************
5444
5445
5446//*************************************************************************************************
5456template< typename Type // Data type of the matrix
5457 , typename Alloc // Type of the allocator
5458 , typename Tag > // Type tag
5460{
5461 using blaze::clear;
5462
5463 if( elements > capacity_ )
5464 {
5465 DynamicMatrix tmp( m_, mm_, n_, elements, Alloc{}, Uninitialized{} );
5466
5467 blaze::uninitialized_transfer( v_, v_+capacity_, tmp.v_ );
5468 blaze::uninitialized_value_construct( tmp.v_+capacity_, tmp.v_+elements );
5469
5470 std::swap( capacity_, tmp.capacity_ );
5471 std::swap( v_, tmp.v_ );
5472 }
5473}
5475//*************************************************************************************************
5476
5477
5478//*************************************************************************************************
5489template< typename Type // Data type of the matrix
5490 , typename Alloc // Type of the allocator
5491 , typename Tag > // Type tag
5493{
5494 if( ( mm_ * n_ ) < capacity_ ) {
5495 DynamicMatrix( *this ).swap( *this );
5496 }
5497}
5499//*************************************************************************************************
5500
5501
5502//*************************************************************************************************
5509template< typename Type // Data type of the matrix
5510 , typename Alloc // Type of the allocator
5511 , typename Tag > // Type tag
5512inline void DynamicMatrix<Type,true,Alloc,Tag>::swap( DynamicMatrix& m ) noexcept
5513{
5514 using std::swap;
5515
5516 swap( m_ , m.m_ );
5517 swap( mm_, m.mm_ );
5518 swap( n_ , m.n_ );
5519 swap( capacity_, m.capacity_ );
5520 swap( v_ , m.v_ );
5521}
5523//*************************************************************************************************
5524
5525
5526//*************************************************************************************************
5536template< typename Type // Data type of the matrix
5537 , typename Alloc // Type of the allocator
5538 , typename Tag > // Type tag
5539inline size_t DynamicMatrix<Type,true,Alloc,Tag>::addPadding( size_t values ) const noexcept
5540{
5541 if( usePadding && IsVectorizable_v<Type> )
5542 return nextMultiple<size_t>( values, SIMDSIZE );
5543 else return values;
5544}
5546//*************************************************************************************************
5547
5548
5549
5550
5551//=================================================================================================
5552//
5553// NUMERIC FUNCTIONS
5554//
5555//=================================================================================================
5556
5557//*************************************************************************************************
5563template< typename Type // Data type of the matrix
5564 , typename Alloc // Type of the allocator
5565 , typename Tag > // Type tag
5566inline DynamicMatrix<Type,true,Alloc,Tag>& DynamicMatrix<Type,true,Alloc,Tag>::transpose()
5567{
5568 using std::swap;
5569
5570 constexpr size_t block( BLOCK_SIZE );
5571
5572 if( m_ == n_ )
5573 {
5574 for( size_t jj=0UL; jj<n_; jj+=block ) {
5575 const size_t jend( min( jj+block, n_ ) );
5576 for( size_t ii=0UL; ii<=jj; ii+=block ) {
5577 for( size_t j=jj; j<jend; ++j ) {
5578 const size_t iend( min( ii+block, m_, j ) );
5579 for( size_t i=ii; i<iend; ++i ) {
5580 swap( v_[i+j*mm_], v_[j+i*mm_] );
5581 }
5582 }
5583 }
5584 }
5585 }
5586 else
5587 {
5588 DynamicMatrix tmp( trans(*this) );
5589 this->swap( tmp );
5590 }
5591
5592 return *this;
5593}
5595//*************************************************************************************************
5596
5597
5598//*************************************************************************************************
5604template< typename Type // Data type of the matrix
5605 , typename Alloc // Type of the allocator
5606 , typename Tag > // Type tag
5607inline DynamicMatrix<Type,true,Alloc,Tag>& DynamicMatrix<Type,true,Alloc,Tag>::ctranspose()
5608{
5609 constexpr size_t block( BLOCK_SIZE );
5610
5611 if( m_ == n_ )
5612 {
5613 for( size_t jj=0UL; jj<n_; jj+=block ) {
5614 const size_t jend( min( jj+block, n_ ) );
5615 for( size_t ii=0UL; ii<jj; ii+=block ) {
5616 const size_t iend( min( ii+block, m_ ) );
5617 for( size_t j=jj; j<jend; ++j ) {
5618 for( size_t i=ii; i<iend; ++i ) {
5619 cswap( v_[i+j*mm_], v_[j+i*mm_] );
5620 }
5621 }
5622 }
5623 for( size_t j=jj; j<jend; ++j ) {
5624 for( size_t i=jj; i<j; ++i ) {
5625 cswap( v_[i+j*mm_], v_[j+i*mm_] );
5626 }
5627 conjugate( v_[j+j*mm_] );
5628 }
5629 }
5630 }
5631 else
5632 {
5633 DynamicMatrix tmp( ctrans(*this) );
5634 this->swap( tmp );
5635 }
5636
5637 return *this;
5638}
5640//*************************************************************************************************
5641
5642
5643//*************************************************************************************************
5661template< typename Type // Data type of the matrix
5662 , typename Alloc // Type of the allocator
5663 , typename Tag > // Type tag
5664template< typename Other > // Data type of the scalar value
5665inline DynamicMatrix<Type,true,Alloc,Tag>& DynamicMatrix<Type,true,Alloc,Tag>::scale( const Other& scalar )
5666{
5667 for( size_t j=0UL; j<n_; ++j )
5668 for( size_t i=0UL; i<m_; ++i )
5669 v_[i+j*mm_] *= scalar;
5670
5671 return *this;
5672}
5674//*************************************************************************************************
5675
5676
5677
5678
5679//=================================================================================================
5680//
5681// DEBUGGING FUNCTIONS
5682//
5683//=================================================================================================
5684
5685//*************************************************************************************************
5695template< typename Type // Data type of the matrix
5696 , typename Alloc // Type of the allocator
5697 , typename Tag > // Type tag
5698inline bool DynamicMatrix<Type,true,Alloc,Tag>::isIntact() const noexcept
5699{
5700 if( m_ > mm_ || mm_ * n_ > capacity_ )
5701 return false;
5702
5703 if( IsVectorizable_v<Type> ) {
5704 for( size_t j=0UL; j<n_; ++j ) {
5705 for( size_t i=m_; i<mm_; ++i ) {
5706 if( !isDefault<strict>( v_[i+j*mm_] ) )
5707 return false;
5708 }
5709 }
5710 }
5711
5712 return true;
5713}
5715//*************************************************************************************************
5716
5717
5718
5719
5720//=================================================================================================
5721//
5722// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5723//
5724//=================================================================================================
5725
5726//*************************************************************************************************
5737template< typename Type // Data type of the matrix
5738 , typename Alloc // Type of the allocator
5739 , typename Tag > // Type tag
5740template< typename Other > // Data type of the foreign expression
5741inline bool DynamicMatrix<Type,true,Alloc,Tag>::canAlias( const Other* alias ) const noexcept
5742{
5743 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5744}
5746//*************************************************************************************************
5747
5748
5749//*************************************************************************************************
5760template< typename Type // Data type of the matrix
5761 , typename Alloc // Type of the allocator
5762 , typename Tag > // Type tag
5763template< typename Other > // Data type of the foreign expression
5764inline bool DynamicMatrix<Type,true,Alloc,Tag>::isAliased( const Other* alias ) const noexcept
5765{
5766 return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5767}
5769//*************************************************************************************************
5770
5771
5772//*************************************************************************************************
5782template< typename Type // Data type of the matrix
5783 , typename Alloc // Type of the allocator
5784 , typename Tag > // Type tag
5785inline bool DynamicMatrix<Type,true,Alloc,Tag>::isAligned() const noexcept
5786{
5787 return ( usePadding || rows() % SIMDSIZE == 0UL );
5788}
5790//*************************************************************************************************
5791
5792
5793//*************************************************************************************************
5804template< typename Type // Data type of the matrix
5805 , typename Alloc // Type of the allocator
5806 , typename Tag > // Type tag
5807inline bool DynamicMatrix<Type,true,Alloc,Tag>::canSMPAssign() const noexcept
5808{
5809 return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5810}
5812//*************************************************************************************************
5813
5814
5815//*************************************************************************************************
5830template< typename Type // Data type of the matrix
5831 , typename Alloc // Type of the allocator
5832 , typename Tag > // Type tag
5834 DynamicMatrix<Type,true,Alloc,Tag>::load( size_t i, size_t j ) const noexcept
5835{
5836 if( usePadding )
5837 return loada( i, j );
5838 else
5839 return loadu( i, j );
5840}
5842//*************************************************************************************************
5843
5844
5845//*************************************************************************************************
5860template< typename Type // Data type of the matrix
5861 , typename Alloc // Type of the allocator
5862 , typename Tag > // Type tag
5864 DynamicMatrix<Type,true,Alloc,Tag>::loada( size_t i, size_t j ) const noexcept
5865{
5866 using blaze::loada;
5867
5869
5870 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5871 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5872 BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5873 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5874 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5875
5876 return loada( v_+i+j*mm_ );
5877}
5879//*************************************************************************************************
5880
5881
5882//*************************************************************************************************
5897template< typename Type // Data type of the matrix
5898 , typename Alloc // Type of the allocator
5899 , typename Tag > // Type tag
5901 DynamicMatrix<Type,true,Alloc,Tag>::loadu( size_t i, size_t j ) const noexcept
5902{
5903 using blaze::loadu;
5904
5906
5907 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5908 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5909 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5910
5911 return loadu( v_+i+j*mm_ );
5912}
5914//*************************************************************************************************
5915
5916
5917//*************************************************************************************************
5933template< typename Type // Data type of the matrix
5934 , typename Alloc // Type of the allocator
5935 , typename Tag > // Type tag
5937 DynamicMatrix<Type,true,Alloc,Tag>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5938{
5939 if( usePadding )
5940 storea( i, j, value );
5941 else
5942 storeu( i, j, value );
5943}
5945//*************************************************************************************************
5946
5947
5948//*************************************************************************************************
5964template< typename Type // Data type of the matrix
5965 , typename Alloc // Type of the allocator
5966 , typename Tag > // Type tag
5968 DynamicMatrix<Type,true,Alloc,Tag>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5969{
5970 using blaze::storea;
5971
5973
5974 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5975 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5976 BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5977 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5978 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5979
5980 storea( v_+i+j*mm_, value );
5981}
5983//*************************************************************************************************
5984
5985
5986//*************************************************************************************************
6002template< typename Type // Data type of the matrix
6003 , typename Alloc // Type of the allocator
6004 , typename Tag > // Type tag
6006 DynamicMatrix<Type,true,Alloc,Tag>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
6007{
6008 using blaze::storeu;
6009
6011
6012 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6013 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
6014 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6015
6016 storeu( v_+i+j*mm_, value );
6017}
6019//*************************************************************************************************
6020
6021
6022//*************************************************************************************************
6039template< typename Type // Data type of the matrix
6040 , typename Alloc // Type of the allocator
6041 , typename Tag > // Type tag
6043 DynamicMatrix<Type,true,Alloc,Tag>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
6044{
6045 using blaze::stream;
6046
6048
6049 BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
6050 BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
6051 BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
6052 BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
6053 BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
6054
6055 stream( v_+i+j*mm_, value );
6056}
6058//*************************************************************************************************
6059
6060
6061//*************************************************************************************************
6073template< typename Type // Data type of the matrix
6074 , typename Alloc // Type of the allocator
6075 , typename Tag > // Type tag
6076template< typename MT > // Type of the right-hand side dense matrix
6077inline auto DynamicMatrix<Type,true,Alloc,Tag>::assign( const DenseMatrix<MT,true>& rhs )
6078 -> DisableIf_t< VectorizedAssign_v<MT> >
6079{
6080 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6081 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6082
6083 const size_t ipos( prevMultiple( m_, 2UL ) );
6084 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6085
6086 for( size_t j=0UL; j<n_; ++j ) {
6087 for( size_t i=0UL; i<ipos; i+=2UL ) {
6088 v_[i +j*mm_] = (*rhs)(i ,j);
6089 v_[i+1UL+j*mm_] = (*rhs)(i+1UL,j);
6090 }
6091 if( ipos < m_ ) {
6092 v_[ipos+j*mm_] = (*rhs)(ipos,j);
6093 }
6094 }
6095}
6097//*************************************************************************************************
6098
6099
6100//*************************************************************************************************
6112template< typename Type // Data type of the matrix
6113 , typename Alloc // Type of the allocator
6114 , typename Tag > // Type tag
6115template< typename MT > // Type of the right-hand side dense matrix
6116inline auto DynamicMatrix<Type,true,Alloc,Tag>::assign( const DenseMatrix<MT,true>& rhs )
6117 -> EnableIf_t< VectorizedAssign_v<MT> >
6118{
6120
6121 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6122 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6123
6124 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
6125
6126 const size_t ipos( remainder ? prevMultiple( m_, SIMDSIZE ) : m_ );
6127 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6128
6129 if( usePadding && useStreaming &&
6130 ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) &&
6131 !(*rhs).isAliased( this ) )
6132 {
6133 for( size_t j=0UL; j<n_; ++j )
6134 {
6135 size_t i( 0UL );
6136 Iterator left( begin(j) );
6137 ConstIterator_t<MT> right( (*rhs).begin(j) );
6138
6139 for( ; i<ipos; i+=SIMDSIZE ) {
6140 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6141 }
6142 for( ; remainder && i<m_; ++i ) {
6143 *left = *right; ++left; ++right;
6144 }
6145 }
6146 }
6147 else
6148 {
6149 for( size_t j=0UL; j<n_; ++j )
6150 {
6151 size_t i( 0UL );
6152 Iterator left( begin(j) );
6153 ConstIterator_t<MT> right( (*rhs).begin(j) );
6154
6155 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6156 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6157 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6158 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6159 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6160 }
6161 for( ; i<ipos; i+=SIMDSIZE ) {
6162 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6163 }
6164 for( ; remainder && i<m_; ++i ) {
6165 *left = *right; ++left; ++right;
6166 }
6167 }
6168 }
6169}
6171//*************************************************************************************************
6172
6173
6174//*************************************************************************************************
6186template< typename Type // Data type of the matrix
6187 , typename Alloc // Type of the allocator
6188 , typename Tag > // Type tag
6189template< typename MT > // Type of the right-hand side dense matrix
6190inline void DynamicMatrix<Type,true,Alloc,Tag>::assign( const DenseMatrix<MT,false>& rhs )
6191{
6193
6194 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6195 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6196
6197 constexpr size_t block( BLOCK_SIZE );
6198
6199 for( size_t jj=0UL; jj<n_; jj+=block ) {
6200 const size_t jend( min( n_, jj+block ) );
6201 for( size_t ii=0UL; ii<m_; ii+=block ) {
6202 const size_t iend( min( m_, ii+block ) );
6203 for( size_t j=jj; j<jend; ++j ) {
6204 for( size_t i=ii; i<iend; ++i ) {
6205 v_[i+j*mm_] = (*rhs)(i,j);
6206 }
6207 }
6208 }
6209 }
6210}
6212//*************************************************************************************************
6213
6214
6215//*************************************************************************************************
6227template< typename Type // Data type of the matrix
6228 , typename Alloc // Type of the allocator
6229 , typename Tag > // Type tag
6230template< typename MT > // Type of the right-hand side sparse matrix
6231inline void DynamicMatrix<Type,true,Alloc,Tag>::assign( const SparseMatrix<MT,true>& rhs )
6232{
6233 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6234 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6235
6236 for( size_t j=0UL; j<(*rhs).columns(); ++j )
6237 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6238 v_[element->index()+j*mm_] = element->value();
6239}
6241//*************************************************************************************************
6242
6243
6244//*************************************************************************************************
6256template< typename Type // Data type of the matrix
6257 , typename Alloc // Type of the allocator
6258 , typename Tag > // Type tag
6259template< typename MT > // Type of the right-hand side sparse matrix
6260inline void DynamicMatrix<Type,true,Alloc,Tag>::assign( const SparseMatrix<MT,false>& rhs )
6261{
6263
6264 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6265 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6266
6267 for( size_t i=0UL; i<(*rhs).rows(); ++i )
6268 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6269 v_[i+element->index()*mm_] = element->value();
6270}
6272//*************************************************************************************************
6273
6274
6275//*************************************************************************************************
6287template< typename Type // Data type of the matrix
6288 , typename Alloc // Type of the allocator
6289 , typename Tag > // Type tag
6290template< typename MT > // Type of the right-hand side dense matrix
6291inline auto DynamicMatrix<Type,true,Alloc,Tag>::addAssign( const DenseMatrix<MT,true>& rhs )
6292 -> DisableIf_t< VectorizedAddAssign_v<MT> >
6293{
6294 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6295 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6296
6297 for( size_t j=0UL; j<n_; ++j )
6298 {
6299 if( IsDiagonal_v<MT> )
6300 {
6301 v_[j+j*mm_] += (*rhs)(j,j);
6302 }
6303 else
6304 {
6305 const size_t ibegin( ( IsLower_v<MT> )
6306 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
6307 :( 0UL ) );
6308 const size_t iend ( ( IsUpper_v<MT> )
6309 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6310 :( m_ ) );
6311 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6312
6313 size_t i( ibegin );
6314
6315 for( ; (i+2UL) <= iend; i+=2UL ) {
6316 v_[i +j*mm_] += (*rhs)(i ,j);
6317 v_[i+1UL+j*mm_] += (*rhs)(i+1UL,j);
6318 }
6319 if( i < iend ) {
6320 v_[i+j*mm_] += (*rhs)(i,j);
6321 }
6322 }
6323 }
6324}
6326//*************************************************************************************************
6327
6328
6329//*************************************************************************************************
6341template< typename Type // Data type of the matrix
6342 , typename Alloc // Type of the allocator
6343 , typename Tag > // Type tag
6344template< typename MT > // Type of the right-hand side dense matrix
6345inline auto DynamicMatrix<Type,true,Alloc,Tag>::addAssign( const DenseMatrix<MT,true>& rhs )
6346 -> EnableIf_t< VectorizedAddAssign_v<MT> >
6347{
6350
6351 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6352 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6353
6354 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
6355
6356 for( size_t j=0UL; j<n_; ++j )
6357 {
6358 const size_t ibegin( ( IsLower_v<MT> )
6359 ?( prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6360 :( 0UL ) );
6361 const size_t iend ( ( IsUpper_v<MT> )
6362 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6363 :( m_ ) );
6364 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6365
6366 const size_t ipos( remainder ? prevMultiple( iend, SIMDSIZE ) : iend );
6367 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
6368
6369 size_t i( ibegin );
6370 Iterator left( begin(j) + ibegin );
6371 ConstIterator_t<MT> right( (*rhs).begin(j) + ibegin );
6372
6373 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6374 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6375 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6376 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6377 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6378 }
6379 for( ; i<ipos; i+=SIMDSIZE ) {
6380 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6381 }
6382 for( ; remainder && i<iend; ++i ) {
6383 *left += *right; ++left; ++right;
6384 }
6385 }
6386}
6388//*************************************************************************************************
6389
6390
6391//*************************************************************************************************
6403template< typename Type // Data type of the matrix
6404 , typename Alloc // Type of the allocator
6405 , typename Tag > // Type tag
6406template< typename MT > // Type of the right-hand side dense matrix
6407inline void DynamicMatrix<Type,true,Alloc,Tag>::addAssign( const DenseMatrix<MT,false>& rhs )
6408{
6410
6411 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6412 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6413
6414 constexpr size_t block( BLOCK_SIZE );
6415
6416 for( size_t jj=0UL; jj<n_; jj+=block ) {
6417 const size_t jend( min( n_, jj+block ) );
6418 for( size_t ii=0UL; ii<m_; ii+=block )
6419 {
6420 if( IsLower_v<MT> && ii < jj ) continue;
6421 if( IsUpper_v<MT> && ii > jj ) break;
6422
6423 for( size_t j=jj; j<jend; ++j )
6424 {
6425 const size_t ibegin( ( IsLower_v<MT> )
6426 ?( max( ( IsStrictlyLower_v<MT> ? j+1UL : j ), ii ) )
6427 :( ii ) );
6428 const size_t iend ( ( IsUpper_v<MT> )
6429 ?( min( ( IsStrictlyUpper_v<MT> ? j : j+1UL ), m_, ii+block ) )
6430 :( min( m_, ii+block ) ) );
6431 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6432
6433 for( size_t i=ibegin; i<iend; ++i ) {
6434 v_[i+j*mm_] += (*rhs)(i,j);
6435 }
6436 }
6437 }
6438 }
6439}
6441//*************************************************************************************************
6442
6443
6444//*************************************************************************************************
6456template< typename Type // Data type of the matrix
6457 , typename Alloc // Type of the allocator
6458 , typename Tag > // Type tag
6459template< typename MT > // Type of the right-hand side sparse matrix
6460inline void DynamicMatrix<Type,true,Alloc,Tag>::addAssign( const SparseMatrix<MT,true>& rhs )
6461{
6462 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6463 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6464
6465 for( size_t j=0UL; j<(*rhs).columns(); ++j )
6466 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6467 v_[element->index()+j*mm_] += element->value();
6468}
6470//*************************************************************************************************
6471
6472
6473//*************************************************************************************************
6485template< typename Type // Data type of the matrix
6486 , typename Alloc // Type of the allocator
6487 , typename Tag > // Type tag
6488template< typename MT > // Type of the right-hand side sparse matrix
6489inline void DynamicMatrix<Type,true,Alloc,Tag>::addAssign( const SparseMatrix<MT,false>& rhs )
6490{
6492
6493 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6494 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6495
6496 for( size_t i=0UL; i<(*rhs).rows(); ++i )
6497 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6498 v_[i+element->index()*mm_] += element->value();
6499}
6501//*************************************************************************************************
6502
6503
6504//*************************************************************************************************
6516template< typename Type // Data type of the matrix
6517 , typename Alloc // Type of the allocator
6518 , typename Tag > // Type tag
6519template< typename MT > // Type of the right-hand side dense matrix
6520inline auto DynamicMatrix<Type,true,Alloc,Tag>::subAssign( const DenseMatrix<MT,true>& rhs )
6521 -> DisableIf_t< VectorizedSubAssign_v<MT> >
6522{
6523 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6524 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6525
6526 for( size_t j=0UL; j<n_; ++j )
6527 {
6528 if( IsDiagonal_v<MT> )
6529 {
6530 v_[j+j*mm_] -= (*rhs)(j,j);
6531 }
6532 else
6533 {
6534 const size_t ibegin( ( IsLower_v<MT> )
6535 ?( IsStrictlyLower_v<MT> ? j+1UL : j )
6536 :( 0UL ) );
6537 const size_t iend ( ( IsUpper_v<MT> )
6538 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6539 :( m_ ) );
6540 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6541
6542 size_t i( ibegin );
6543
6544 for( ; (i+2UL) <= iend; i+=2UL ) {
6545 v_[i +j*mm_] -= (*rhs)(i ,j);
6546 v_[i+1+j*mm_] -= (*rhs)(i+1,j);
6547 }
6548 if( i < iend ) {
6549 v_[i+j*mm_] -= (*rhs)(i,j);
6550 }
6551 }
6552 }
6553}
6555//*************************************************************************************************
6556
6557
6558//*************************************************************************************************
6570template< typename Type // Data type of the matrix
6571 , typename Alloc // Type of the allocator
6572 , typename Tag > // Type tag
6573template< typename MT > // Type of the right-hand side dense matrix
6574inline auto DynamicMatrix<Type,true,Alloc,Tag>::subAssign( const DenseMatrix<MT,true>& rhs )
6575 -> EnableIf_t< VectorizedSubAssign_v<MT> >
6576{
6579
6580 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6581 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6582
6583 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
6584
6585 for( size_t j=0UL; j<n_; ++j )
6586 {
6587 const size_t ibegin( ( IsLower_v<MT> )
6588 ?( prevMultiple( ( IsStrictlyLower_v<MT> ? j+1UL : j ), SIMDSIZE ) )
6589 :( 0UL ) );
6590 const size_t iend ( ( IsUpper_v<MT> )
6591 ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
6592 :( m_ ) );
6593 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6594
6595 const size_t ipos( remainder ? prevMultiple( iend, SIMDSIZE ) : iend );
6596 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
6597
6598 size_t i( ibegin );
6599 Iterator left( begin(j) + ibegin );
6600 ConstIterator_t<MT> right( (*rhs).begin(j) + ibegin );
6601
6602 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6603 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6604 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6605 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6606 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6607 }
6608 for( ; i<ipos; i+=SIMDSIZE ) {
6609 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6610 }
6611 for( ; remainder && i<iend; ++i ) {
6612 *left -= *right; ++left; ++right;
6613 }
6614 }
6615}
6617//*************************************************************************************************
6618
6619
6620//*************************************************************************************************
6632template< typename Type // Data type of the matrix
6633 , typename Alloc // Type of the allocator
6634 , typename Tag > // Type tag
6635template< typename MT > // Type of the right-hand side dense matrix
6636inline void DynamicMatrix<Type,true,Alloc,Tag>::subAssign( const DenseMatrix<MT,false>& rhs )
6637{
6639
6640 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6641 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6642
6643 constexpr size_t block( BLOCK_SIZE );
6644
6645 for( size_t jj=0UL; jj<n_; jj+=block ) {
6646 const size_t jend( min( n_, jj+block ) );
6647 for( size_t ii=0UL; ii<m_; ii+=block )
6648 {
6649 if( IsLower_v<MT> && ii < jj ) continue;
6650 if( IsUpper_v<MT> && ii > jj ) break;
6651
6652 for( size_t j=jj; j<jend; ++j )
6653 {
6654 const size_t ibegin( ( IsLower_v<MT> )
6655 ?( max( ( IsStrictlyLower_v<MT> ? j+1UL : j ), ii ) )
6656 :( ii ) );
6657 const size_t iend ( ( IsUpper_v<MT> )
6658 ?( min( ( IsStrictlyUpper_v<MT> ? j : j+1UL ), m_, ii+block ) )
6659 :( min( m_, ii+block ) ) );
6660 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6661
6662 for( size_t i=ibegin; i<iend; ++i ) {
6663 v_[i+j*mm_] -= (*rhs)(i,j);
6664 }
6665 }
6666 }
6667 }
6668}
6670//*************************************************************************************************
6671
6672
6673//*************************************************************************************************
6685template< typename Type // Data type of the matrix
6686 , typename Alloc // Type of the allocator
6687 , typename Tag > // Type tag
6688template< typename MT > // Type of the right-hand side sparse matrix
6689inline void DynamicMatrix<Type,true,Alloc,Tag>::subAssign( const SparseMatrix<MT,true>& rhs )
6690{
6691 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6692 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6693
6694 for( size_t j=0UL; j<(*rhs).columns(); ++j )
6695 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
6696 v_[element->index()+j*mm_] -= element->value();
6697}
6699//*************************************************************************************************
6700
6701
6702//*************************************************************************************************
6714template< typename Type // Data type of the matrix
6715 , typename Alloc // Type of the allocator
6716 , typename Tag > // Type tag
6717template< typename MT > // Type of the right-hand side sparse matrix
6718inline void DynamicMatrix<Type,true,Alloc,Tag>::subAssign( const SparseMatrix<MT,false>& rhs )
6719{
6721
6722 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6723 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6724
6725 for( size_t i=0UL; i<(*rhs).rows(); ++i )
6726 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
6727 v_[i+element->index()*mm_] -= element->value();
6728}
6730//*************************************************************************************************
6731
6732
6733//*************************************************************************************************
6745template< typename Type // Data type of the matrix
6746 , typename Alloc // Type of the allocator
6747 , typename Tag > // Type tag
6748template< typename MT > // Type of the right-hand side dense matrix
6749inline auto DynamicMatrix<Type,true,Alloc,Tag>::schurAssign( const DenseMatrix<MT,true>& rhs )
6750 -> DisableIf_t< VectorizedSchurAssign_v<MT> >
6751{
6752 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6753 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6754
6755 const size_t ipos( prevMultiple( m_, 2UL ) );
6756 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6757
6758 for( size_t j=0UL; j<n_; ++j ) {
6759 for( size_t i=0UL; (i+2UL) <= ipos; i+=2UL ) {
6760 v_[i +j*mm_] *= (*rhs)(i ,j);
6761 v_[i+1+j*mm_] *= (*rhs)(i+1,j);
6762 }
6763 if( ipos < m_ ) {
6764 v_[ipos+j*mm_] *= (*rhs)(ipos,j);
6765 }
6766 }
6767}
6769//*************************************************************************************************
6770
6771
6772//*************************************************************************************************
6784template< typename Type // Data type of the matrix
6785 , typename Alloc // Type of the allocator
6786 , typename Tag > // Type tag
6787template< typename MT > // Type of the right-hand side dense matrix
6788inline auto DynamicMatrix<Type,true,Alloc,Tag>::schurAssign( const DenseMatrix<MT,true>& rhs )
6789 -> EnableIf_t< VectorizedSchurAssign_v<MT> >
6790{
6792
6793 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6794 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6795
6796 constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
6797
6798 for( size_t j=0UL; j<n_; ++j )
6799 {
6800 const size_t ipos( remainder ? prevMultiple( m_, SIMDSIZE ) : m_ );
6801 BLAZE_INTERNAL_ASSERT( ipos <= m_, "Invalid end calculation" );
6802
6803 size_t i( 0UL );
6804 Iterator left( begin(j) );
6805 ConstIterator_t<MT> right( (*rhs).begin(j) );
6806
6807 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6808 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6809 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6810 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6811 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6812 }
6813 for( ; i<ipos; i+=SIMDSIZE ) {
6814 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6815 }
6816 for( ; remainder && i<m_; ++i ) {
6817 *left *= *right; ++left; ++right;
6818 }
6819 }
6820}
6822//*************************************************************************************************
6823
6824
6825//*************************************************************************************************
6837template< typename Type // Data type of the matrix
6838 , typename Alloc // Type of the allocator
6839 , typename Tag > // Type tag
6840template< typename MT > // Type of the right-hand side dense matrix
6841inline void DynamicMatrix<Type,true,Alloc,Tag>::schurAssign( const DenseMatrix<MT,false>& rhs )
6842{
6844
6845 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6846 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6847
6848 constexpr size_t block( BLOCK_SIZE );
6849
6850 for( size_t jj=0UL; jj<n_; jj+=block ) {
6851 const size_t jend( min( n_, jj+block ) );
6852 for( size_t ii=0UL; ii<m_; ii+=block ) {
6853 const size_t iend( min( m_, ii+block ) );
6854 for( size_t j=jj; j<jend; ++j ) {
6855 for( size_t i=ii; i<iend; ++i ) {
6856 v_[i+j*mm_] *= (*rhs)(i,j);
6857 }
6858 }
6859 }
6860 }
6861}
6863//*************************************************************************************************
6864
6865
6866//*************************************************************************************************
6878template< typename Type // Data type of the matrix
6879 , typename Alloc // Type of the allocator
6880 , typename Tag > // Type tag
6881template< typename MT > // Type of the right-hand side sparse matrix
6882inline void DynamicMatrix<Type,true,Alloc,Tag>::schurAssign( const SparseMatrix<MT,true>& rhs )
6883{
6884 using blaze::reset;
6885
6886 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6887 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6888
6889 for( size_t j=0UL; j<n_; ++j )
6890 {
6891 size_t i( 0UL );
6892
6893 for( auto element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
6894 for( ; i<element->index(); ++i )
6895 reset( v_[i+j*mm_] );
6896 v_[i+j*mm_] *= element->value();
6897 ++i;
6898 }
6899
6900 for( ; i<m_; ++i ) {
6901 reset( v_[i+j*mm_] );
6902 }
6903 }
6904}
6906//*************************************************************************************************
6907
6908
6909//*************************************************************************************************
6921template< typename Type // Data type of the matrix
6922 , typename Alloc // Type of the allocator
6923 , typename Tag > // Type tag
6924template< typename MT > // Type of the right-hand side sparse matrix
6925inline void DynamicMatrix<Type,true,Alloc,Tag>::schurAssign( const SparseMatrix<MT,false>& rhs )
6926{
6927 using blaze::reset;
6928
6930
6931 BLAZE_INTERNAL_ASSERT( m_ == (*rhs).rows() , "Invalid number of rows" );
6932 BLAZE_INTERNAL_ASSERT( n_ == (*rhs).columns(), "Invalid number of columns" );
6933
6934 for( size_t i=0UL; i<m_; ++i )
6935 {
6936 size_t j( 0UL );
6937
6938 for( auto element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
6939 for( ; j<element->index(); ++j )
6940 reset( v_[i+j*mm_] );
6941 v_[i+j*mm_] *= element->value();
6942 ++j;
6943 }
6944
6945 for( ; j<n_; ++j ) {
6946 reset( v_[i+j*mm_] );
6947 }
6948 }
6949}
6951//*************************************************************************************************
6952
6953
6954
6955
6956
6957
6958
6959
6960//=================================================================================================
6961//
6962// DYNAMICMATRIX OPERATORS
6963//
6964//=================================================================================================
6965
6966//*************************************************************************************************
6969template< RelaxationFlag RF, typename Type, bool SO, typename Alloc, typename Tag >
6970bool isDefault( const DynamicMatrix<Type,SO,Alloc,Tag>& m );
6971
6972template< typename Type, bool SO, typename Alloc, typename Tag >
6973bool isIntact( const DynamicMatrix<Type,SO,Alloc,Tag>& m ) noexcept;
6974
6975template< typename Type, bool SO, typename Alloc, typename Tag >
6976void swap( DynamicMatrix<Type,SO,Alloc,Tag>& a, DynamicMatrix<Type,SO,Alloc,Tag>& b ) noexcept;
6978//*************************************************************************************************
6979
6980
6981//*************************************************************************************************
7006template< RelaxationFlag RF // Relaxation flag
7007 , typename Type // Data type of the matrix
7008 , bool SO // Storage order
7009 , typename Alloc // Type of the allocator
7010 , typename Tag > // Type tag
7012{
7013 return ( m.rows() == 0UL && m.columns() == 0UL );
7014}
7015//*************************************************************************************************
7016
7017
7018//*************************************************************************************************
7036template< typename Type // Data type of the matrix
7037 , bool SO // Storage order
7038 , typename Alloc // Type of the allocator
7039 , typename Tag > // Type tag
7040inline bool isIntact( const DynamicMatrix<Type,SO,Alloc,Tag>& m ) noexcept
7041{
7042 return m.isIntact();
7043}
7044//*************************************************************************************************
7045
7046
7047//*************************************************************************************************
7055template< typename Type // Data type of the matrix
7056 , bool SO // Storage order
7057 , typename Alloc // Type of the allocator
7058 , typename Tag > // Type tag
7060{
7061 a.swap( b );
7062}
7063//*************************************************************************************************
7064
7065
7066
7067
7068//=================================================================================================
7069//
7070// HASCONSTDATAACCESS SPECIALIZATIONS
7071//
7072//=================================================================================================
7073
7074//*************************************************************************************************
7076template< typename T, bool SO, typename Alloc, typename Tag >
7077struct HasConstDataAccess< DynamicMatrix<T,SO,Alloc,Tag> >
7078 : public TrueType
7079{};
7081//*************************************************************************************************
7082
7083
7084
7085
7086//=================================================================================================
7087//
7088// HASMUTABLEDATAACCESS SPECIALIZATIONS
7089//
7090//=================================================================================================
7091
7092//*************************************************************************************************
7094template< typename T, bool SO, typename Alloc, typename Tag >
7095struct HasMutableDataAccess< DynamicMatrix<T,SO,Alloc,Tag> >
7096 : public TrueType
7097{};
7099//*************************************************************************************************
7100
7101
7102
7103
7104//=================================================================================================
7105//
7106// ISALIGNED SPECIALIZATIONS
7107//
7108//=================================================================================================
7109
7110//*************************************************************************************************
7112template< typename T, bool SO, typename Alloc, typename Tag >
7113struct IsAligned< DynamicMatrix<T,SO,Alloc,Tag> >
7114 : public BoolConstant<usePadding>
7115{};
7117//*************************************************************************************************
7118
7119
7120
7121
7122//=================================================================================================
7123//
7124// ISCONTIGUOUS SPECIALIZATIONS
7125//
7126//=================================================================================================
7127
7128//*************************************************************************************************
7130template< typename T, bool SO, typename Alloc, typename Tag >
7131struct IsContiguous< DynamicMatrix<T,SO,Alloc,Tag> >
7132 : public TrueType
7133{};
7135//*************************************************************************************************
7136
7137
7138
7139
7140//=================================================================================================
7141//
7142// ISPADDED SPECIALIZATIONS
7143//
7144//=================================================================================================
7145
7146//*************************************************************************************************
7148template< typename T, bool SO, typename Alloc, typename Tag >
7149struct IsPadded< DynamicMatrix<T,SO,Alloc,Tag> >
7150 : public BoolConstant<usePadding>
7151{};
7153//*************************************************************************************************
7154
7155
7156
7157
7158//=================================================================================================
7159//
7160// ADDTRAIT SPECIALIZATIONS
7161//
7162//=================================================================================================
7163
7164//*************************************************************************************************
7166template< typename T1, typename T2 >
7167struct AddTraitEval2< T1, T2
7168 , EnableIf_t< IsMatrix_v<T1> &&
7169 IsMatrix_v<T2> &&
7170 ( IsDenseMatrix_v<T1> || IsDenseMatrix_v<T2> ) &&
7171 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7172 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7173 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7174 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7175 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7176 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
7177 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
7178 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
7179{
7180 using ET = AddTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7181
7182 static constexpr bool SO1 = StorageOrder_v<T1>;
7183 static constexpr bool SO2 = StorageOrder_v<T2>;
7184
7185 static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
7186 ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7187 ? ( IsSymmetric_v<T1>
7188 ? SO2
7189 : SO1 )
7190 : SO1 && SO2 )
7191 : ( IsDenseMatrix_v<T1>
7192 ? SO1
7193 : SO2 ) );
7194
7195 using Type = DynamicMatrix< ET
7196 , SO
7197 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7198 , AddTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7199};
7201//*************************************************************************************************
7202
7203
7204
7205
7206//=================================================================================================
7207//
7208// SUBTRAIT SPECIALIZATIONS
7209//
7210//=================================================================================================
7211
7212//*************************************************************************************************
7214template< typename T1, typename T2 >
7215struct SubTraitEval2< T1, T2
7216 , EnableIf_t< IsMatrix_v<T1> &&
7217 IsMatrix_v<T2> &&
7218 ( IsDenseMatrix_v<T1> || IsDenseMatrix_v<T2> ) &&
7219 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7220 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7221 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7222 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7223 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7224 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
7225 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
7226 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
7227{
7228 using ET = SubTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7229
7230 static constexpr bool SO1 = StorageOrder_v<T1>;
7231 static constexpr bool SO2 = StorageOrder_v<T2>;
7232
7233 static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
7234 ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7235 ? ( IsSymmetric_v<T1>
7236 ? SO2
7237 : SO1 )
7238 : SO1 && SO2 )
7239 : ( IsDenseMatrix_v<T1>
7240 ? SO1
7241 : SO2 ) );
7242
7243 using Type = DynamicMatrix< ET
7244 , SO
7245 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7246 , SubTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7247};
7249//*************************************************************************************************
7250
7251
7252
7253
7254//=================================================================================================
7255//
7256// SCHURTRAIT SPECIALIZATIONS
7257//
7258//=================================================================================================
7259
7260//*************************************************************************************************
7262template< typename T1, typename T2 >
7263struct SchurTraitEval2< T1, T2
7264 , EnableIf_t< IsDenseMatrix_v<T1> &&
7265 IsDenseMatrix_v<T2> &&
7266 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7267 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7268 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7269 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7270 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7271 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
7272 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
7273 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
7274{
7275 using ET = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7276
7277 static constexpr bool SO1 = StorageOrder_v<T1>;
7278 static constexpr bool SO2 = StorageOrder_v<T2>;
7279
7280 static constexpr bool SO = ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7281 ? ( IsSymmetric_v<T1>
7282 ? SO2
7283 : SO1 )
7284 : SO1 && SO2 );
7285
7286 using Type = DynamicMatrix< ET
7287 , SO
7288 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7289 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7290};
7292//*************************************************************************************************
7293
7294
7295
7296
7297//=================================================================================================
7298//
7299// MULTTRAIT SPECIALIZATIONS
7300//
7301//=================================================================================================
7302
7303//*************************************************************************************************
7305template< typename T1, typename T2 >
7306struct MultTraitEval2< T1, T2
7307 , EnableIf_t< IsDenseMatrix_v<T1> &&
7308 IsScalar_v<T2> &&
7309 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7310 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7311 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7312 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) > >
7313{
7314 using ET = MultTrait_t< ElementType_t<T1>, T2 >;
7315
7316 using Type = DynamicMatrix< ET
7317 , StorageOrder_v<T1>
7318 , DynamicAllocator_t< ET, GetAllocator_t<T1> >
7319 , MultTrait_t< TagType_t<T1>, T2 > >;
7320};
7321
7322template< typename T1, typename T2 >
7323struct MultTraitEval2< T1, T2
7324 , EnableIf_t< IsScalar_v<T1> &&
7325 IsDenseMatrix_v<T2> &&
7326 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7327 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7328 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
7329 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
7330{
7331 using ET = MultTrait_t< T1, ElementType_t<T2> >;
7332
7333 using Type = DynamicMatrix< ET
7334 , StorageOrder_v<T2>
7335 , DynamicAllocator_t< ET, GetAllocator_t<T2> >
7336 , MultTrait_t< T1, TagType_t<T2> > >;
7337};
7338
7339template< typename T1, typename T2 >
7340struct MultTraitEval2< T1, T2
7341 , EnableIf_t< IsDenseVector_v<T1> &&
7342 IsDenseVector_v<T2> &&
7343 IsColumnVector_v<T1> &&
7344 IsRowVector_v<T2> &&
7345 ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
7346 ( Size_v<T2,0UL> == DefaultSize_v ) ) &&
7347 ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) ||
7348 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ) > >
7349{
7350 using ET = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7351
7352 using Type = DynamicMatrix< ET
7353 , false
7354 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7355 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7356};
7357
7358template< typename T1, typename T2 >
7359struct MultTraitEval2< T1, T2
7360 , EnableIf_t< IsMatrix_v<T1> &&
7361 IsMatrix_v<T2> &&
7362 ( IsDenseMatrix_v<T1> || IsDenseMatrix_v<T2> ) &&
7363 ( ( Size_v<T1,0UL> == DefaultSize_v &&
7364 ( !IsSquare_v<T1> || Size_v<T2,0UL> == DefaultSize_v ) ) ||
7365 ( Size_v<T2,1UL> == DefaultSize_v &&
7366 ( !IsSquare_v<T2> || Size_v<T1,1UL> == DefaultSize_v ) ) ) &&
7367 ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v &&
7368 ( !IsSquare_v<T1> || MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ) ||
7369 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v &&
7370 ( !IsSquare_v<T2> || MaxSize_v<T1,1UL> == DefaultMaxSize_v ) ) ) > >
7371{
7372 using M1 = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7373 using M2 = MultTrait_t< TagType_t<T1>, TagType_t<T2> >;
7374 using ET = AddTrait_t<M1,M1>;
7375
7376 using Type = DynamicMatrix< ET
7377 , ( IsSparseMatrix_v<T1> ? StorageOrder_v<T2> : StorageOrder_v<T1> )
7378 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7379 , AddTrait_t<M2,M2> >;
7380};
7382//*************************************************************************************************
7383
7384
7385
7386
7387//=================================================================================================
7388//
7389// KRONTRAIT SPECIALIZATIONS
7390//
7391//=================================================================================================
7392
7393//*************************************************************************************************
7395template< typename T1, typename T2 >
7396struct KronTraitEval2< T1, T2
7397 , EnableIf_t< IsDenseMatrix_v<T1> &&
7398 IsDenseMatrix_v<T2> &&
7399 ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
7400 ( Size_v<T2,0UL> == DefaultSize_v ) ||
7401 ( Size_v<T1,1UL> == DefaultSize_v ) ||
7402 ( Size_v<T2,1UL> == DefaultSize_v ) ) &&
7403 ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) ||
7404 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ||
7405 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) ||
7406 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) ) > >
7407{
7408 using ET = MultTrait_t< ElementType_t<T1>, ElementType_t<T2> >;
7409
7410 using Type = DynamicMatrix< ET
7411 , StorageOrder_v<T2>
7412 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7413 , MultTrait_t< TagType_t<T1>, TagType_t<T2> > >;
7414};
7416//*************************************************************************************************
7417
7418
7419
7420
7421//=================================================================================================
7422//
7423// DIVTRAIT SPECIALIZATIONS
7424//
7425//=================================================================================================
7426
7427//*************************************************************************************************
7429template< typename T1, typename T2 >
7430struct DivTraitEval2< T1, T2
7431 , EnableIf_t< IsDenseMatrix_v<T1> &&
7432 IsScalar_v<T2> &&
7433 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7434 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7435 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7436 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) > >
7437{
7438 using ET = DivTrait_t< ElementType_t<T1>, T2 >;
7439
7440 using Type = DynamicMatrix< ET
7441 , StorageOrder_v<T1>
7442 , DynamicAllocator_t< ET, GetAllocator_t<T1> >
7443 , DivTrait_t< TagType_t<T1>, T2 > >;
7444};
7446//*************************************************************************************************
7447
7448
7449
7450
7451//=================================================================================================
7452//
7453// MAPTRAIT SPECIALIZATIONS
7454//
7455//=================================================================================================
7456
7457//*************************************************************************************************
7459template< typename T, typename OP >
7460struct UnaryMapTraitEval2< T, OP
7462 ( Size_v<T,0UL> == DefaultSize_v ||
7463 Size_v<T,1UL> == DefaultSize_v ) &&
7464 ( MaxSize_v<T,0UL> == DefaultMaxSize_v ||
7465 MaxSize_v<T,1UL> == DefaultMaxSize_v ) > >
7466{
7467 using ET =
7468 EvaluateTrait_t< decltype( std::declval<OP>()( std::declval< ElementType_t<T> >() ) ) >;
7469
7470 using Type = DynamicMatrix< ET
7471 , StorageOrder_v<T>
7472 , DynamicAllocator_t< ET, GetAllocator_t<T> >
7473 , MapTrait_t< TagType_t<T>, OP > >;
7474};
7476//*************************************************************************************************
7477
7478
7479//*************************************************************************************************
7481template< typename T1, typename T2, typename OP >
7482struct BinaryMapTraitEval2< T1, T2, OP
7484 IsRowVector_v<T2> &&
7485 ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
7486 ( Size_v<T2,0UL> == DefaultSize_v ) ) &&
7487 ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) ||
7488 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ) > >
7489{
7490 using ET =
7491 EvaluateTrait_t< decltype( std::declval<OP>()( std::declval< ElementType_t<T1> >()
7492 , std::declval< ElementType_t<T2> >() ) ) >;
7493
7494 using Type = DynamicMatrix< ET
7495 , false
7496 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7497 , MapTrait_t< TagType_t<T1>, TagType_t<T2>, OP > >;
7498};
7499
7500template< typename T1, typename T2, typename OP >
7501struct BinaryMapTraitEval2< T1, T2, OP
7502 , EnableIf_t< IsMatrix_v<T1> &&
7503 IsMatrix_v<T2> &&
7504 ( Size_v<T1,0UL> == DefaultSize_v ) &&
7505 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7506 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7507 ( Size_v<T2,1UL> == DefaultSize_v ) &&
7508 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7509 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
7510 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
7511 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
7512{
7513 using ET =
7514 EvaluateTrait_t< decltype( std::declval<OP>()( std::declval< ElementType_t<T1> >()
7515 , std::declval< ElementType_t<T2> >() ) ) >;
7516
7517 static constexpr bool SO1 = StorageOrder_v<T1>;
7518 static constexpr bool SO2 = StorageOrder_v<T2>;
7519
7520 static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
7521 ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
7522 ? ( IsSymmetric_v<T1>
7523 ? SO2
7524 : SO1 )
7525 : SO1 && SO2 )
7526 : ( IsDenseMatrix_v<T1>
7527 ? SO1
7528 : SO2 ) );
7529
7530 using Type = DynamicMatrix< ET
7531 , SO
7532 , DynamicAllocator_t< ET, GetAllocator_t<T1>, GetAllocator_t<T2> >
7533 , MapTrait_t< TagType_t<T1>, TagType_t<T2>, OP > >;
7534};
7536//*************************************************************************************************
7537
7538
7539
7540
7541//=================================================================================================
7542//
7543// EXPANDTRAIT SPECIALIZATIONS
7544//
7545//=================================================================================================
7546
7547//*************************************************************************************************
7549template< typename T, size_t E >
7550struct ExpandTraitEval2< T, E
7552 ( ( E == inf ) ||
7553 ( ( Size_v<T,0UL> == DefaultSize_v ) &&
7554 ( MaxSize_v<T,0UL> == DefaultMaxSize_v ) ) ) > >
7555{
7556 using Type = DynamicMatrix< ElementType_t<T>
7557 , ( IsColumnVector_v<T> ? columnMajor : rowMajor )
7558 , DynamicAllocator_t< ElementType_t<T>, GetAllocator_t<T> >
7559 , TagType_t<T> >;
7560};
7562//*************************************************************************************************
7563
7564
7565
7566
7567//=================================================================================================
7568//
7569// REPEATTRAIT SPECIALIZATIONS
7570//
7571//=================================================================================================
7572
7573//*************************************************************************************************
7575template< typename T, size_t R0, size_t R1 >
7576struct RepeatTraitEval2< T, R0, R1, inf
7578 ( ( R0 == inf && R1 == inf ) ||
7579 ( ( Size_v<T,0UL> == DefaultSize_v ) &&
7580 ( MaxSize_v<T,0UL> == DefaultMaxSize_v ) ) ||
7581 ( ( Size_v<T,1UL> == DefaultSize_v ) &&
7582 ( MaxSize_v<T,1UL> == DefaultMaxSize_v ) ) ) > >
7583{
7584 using Type = DynamicMatrix< ElementType_t<T>
7585 , StorageOrder_v<T>
7586 , DynamicAllocator_t< ElementType_t<T>, GetAllocator_t<T> >
7587 , TagType_t<T> >;
7588};
7590//*************************************************************************************************
7591
7592
7593
7594
7595//=================================================================================================
7596//
7597// SOLVETRAIT SPECIALIZATIONS
7598//
7599//=================================================================================================
7600
7601//*************************************************************************************************
7603template< typename T1, typename T2 >
7604struct SolveTraitEval2< T1, T2
7605 , EnableIf_t< IsDenseMatrix_v<T1> &&
7606 IsDenseMatrix_v<T2> &&
7607 ( ( ( Size_v<T1,0UL> == DefaultSize_v ) &&
7608 ( Size_v<T2,0UL> == DefaultSize_v ) &&
7609 ( Size_v<T1,1UL> == DefaultSize_v ) &&
7610 ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
7611 ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
7612 ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) ) ||
7613 ( ( Size_v<T2,1UL> == DefaultSize_v ) &&
7614 ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) ) ) > >
7615{
7616 using Type = DynamicMatrix< ElementType_t<T2>
7617 , StorageOrder_v<T2>
7618 , DynamicAllocator_t< ElementType_t<T2>, GetAllocator_t<T2> >
7619 , TagType_t<T2> >;
7620};
7622//*************************************************************************************************
7623
7624
7625
7626
7627//=================================================================================================
7628//
7629// HIGHTYPE SPECIALIZATIONS
7630//
7631//=================================================================================================
7632
7633//*************************************************************************************************
7635template< typename T1, bool SO, typename Alloc, typename Tag, typename T2 >
7636struct HighType< DynamicMatrix<T1,SO,Alloc,Tag>, DynamicMatrix<T2,SO,Alloc,Tag> >
7637{
7638 using Type = DynamicMatrix< typename HighType<T1,T2>::Type, SO, Alloc, Tag >;
7639};
7641//*************************************************************************************************
7642
7643
7644
7645
7646//=================================================================================================
7647//
7648// LOWTYPE SPECIALIZATIONS
7649//
7650//=================================================================================================
7651
7652//*************************************************************************************************
7654template< typename T1, bool SO, typename Alloc, typename Tag, typename T2 >
7655struct LowType< DynamicMatrix<T1,SO,Alloc,Tag>, DynamicMatrix<T2,SO,Alloc,Tag> >
7656{
7657 using Type = DynamicMatrix< typename LowType<T1,T2>::Type, SO, Alloc, Tag >;
7658};
7660//*************************************************************************************************
7661
7662
7663
7664
7665//=================================================================================================
7666//
7667// SUBMATRIXTRAIT SPECIALIZATIONS
7668//
7669//=================================================================================================
7670
7671//*************************************************************************************************
7673template< typename MT >
7674struct SubmatrixTraitEval2< MT, inf, inf, inf, inf
7675 , EnableIf_t< IsDenseMatrix_v<MT> &&
7676 ( Size_v<MT,0UL> == DefaultSize_v ||
7677 Size_v<MT,1UL> == DefaultSize_v ) &&
7678 ( MaxSize_v<MT,0UL> == DefaultMaxSize_v ||
7679 MaxSize_v<MT,1UL> == DefaultMaxSize_v ) > >
7680{
7681 using ET = RemoveConst_t< ElementType_t<MT> >;
7682
7683 using Type = DynamicMatrix< ET
7684 , StorageOrder_v<MT>
7685 , DynamicAllocator_t< ET, GetAllocator_t<MT> >
7686 , TagType_t<MT> >;
7687};
7689//*************************************************************************************************
7690
7691
7692
7693
7694//=================================================================================================
7695//
7696// ROWSTRAIT SPECIALIZATIONS
7697//
7698//=================================================================================================
7699
7700//*************************************************************************************************
7702template< typename MT, size_t M >
7703struct RowsTraitEval2< MT, M
7704 , EnableIf_t< IsDenseMatrix_v<MT> &&
7705 ( M == 0UL || Size_v<MT,1UL> == DefaultSize_v ) &&
7706 ( M == 0UL || MaxSize_v<MT,1UL> == DefaultMaxSize_v ) > >
7707{
7708 using ET = RemoveConst_t< ElementType_t<MT> >;
7709
7710 using Type = DynamicMatrix< ET
7711 , false
7712 , DynamicAllocator_t< ET, GetAllocator_t<MT> >
7713 , TagType_t<MT> >;
7714};
7716//*************************************************************************************************
7717
7718
7719
7720
7721//=================================================================================================
7722//
7723// COLUMNSTRAIT SPECIALIZATIONS
7724//
7725//=================================================================================================
7726
7727//*************************************************************************************************
7729template< typename MT, size_t N >
7730struct ColumnsTraitEval2< MT, N
7731 , EnableIf_t< IsDenseMatrix_v<MT> &&
7732 ( N == 0UL || Size_v<MT,0UL> == DefaultSize_v ) &&
7733 ( N == 0UL || MaxSize_v<MT,0UL> == DefaultMaxSize_v ) > >
7734{
7735 using ET = RemoveConst_t< ElementType_t<MT> >;
7736
7737 using Type = DynamicMatrix< ET
7738 , true
7739 , DynamicAllocator_t< ET, GetAllocator_t<MT> >
7740 , TagType_t<MT> >;
7741};
7743//*************************************************************************************************
7744
7745} // namespace blaze
7746
7747#endif
Header file for the addition trait.
Header file for generic algorithms.
Header file for auxiliary alias declarations.
typename ResultType_t< T >::TagType TagType_t
Alias declaration for nested TagType type definitions.
Definition: Aliases.h:530
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.
Definition: Aliases.h:130
Header file for the AlignedAllocator implementation.
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.
Header file for the columns trait.
Header file for the conjugate shim.
Constraint on the data type.
Header file for the DenseIterator class template.
Constraint on the data type.
Header file for the division trait.
Header file for the DynamicAllocator type trait.
Header file for the EnableIf class template.
Header file for the EvaluateTrait class template.
Header file for the expand trait.
Header file for the GetAllocator type trait.
Header file for the HasConstDataAccess type trait.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Header file for the HighType type trait.
Header file for the IntegralConstant class template.
Header file for the IsAligned type trait.
Header file for the IsBuiltin type trait.
Header file for the IsColumnVector type trait.
Header file for the IsContiguous type trait.
Header file for the isDefault shim.
Header file for the IsDenseMatrix type trait.
Header file for the IsDenseVector type trait.
Header file for the IsDiagonal type trait.
Header file for the IsLower type trait.
Header file for the IsMatrix type trait.
Header file for the IsPadded type trait.
Header file for the IsRowVector 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 IsScalar type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsSquare type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsUpper type trait.
Header file for the IsVectorizable type trait.
Header file for the Kron product trait.
Header file for the LowType type trait.
Header file for the map trait.
Header file for the MaxSize type trait.
Header file for the MAYBE_UNUSED function template.
Header file for memory allocation and deallocation functionality.
Header file for the multiplication trait.
Header file for the nextMultiple shim.
System settings for the [[no_unique_address]] attribute.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Header file for the relaxation flag enumeration.
Header file for the RemoveCV type trait.
Header file for the RemoveConst type trait.
Header file for the repeat trait.
Header file for the rows trait.
Header file for all SIMD functionality.
Data type constraint.
Header file for the Schur product trait.
Header file for the Solver trait.
Header file for the subtraction trait.
Header file for the submatrix trait.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Allocator for type-specific aligned memory.
Definition: AlignedAllocator.h:72
Implementation of a generic iterator for dense vectors and matrices.
Definition: DenseIterator.h:60
Base class for dense matrices.
Definition: DenseMatrix.h:82
Efficient implementation of a dynamic matrix.
Definition: DynamicMatrix.h:242
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: DynamicMatrix.h:2690
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: DynamicMatrix.h:2413
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2584
const Type & ReturnType
Return type for expression template evaluations.
Definition: DynamicMatrix.h:265
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: DynamicMatrix.h:2932
void reset()
Reset to the default initial values.
Definition: DynamicMatrix.h:1934
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DynamicMatrix.h:1798
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: DynamicMatrix.h:3380
AlignedAllocator< Type > AllocatorType
Allocator type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:263
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: DynamicMatrix.h:271
Type *BLAZE_RESTRICT v_
The dynamically allocated matrix elements.
Definition: DynamicMatrix.h:569
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DynamicMatrix.h:1819
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: DynamicMatrix.h:2615
DynamicMatrix & transpose()
In-place transpose of the matrix.
Definition: DynamicMatrix.h:2219
void reserve(size_t elements)
Setting the minimum capacity of the matrix.
Definition: DynamicMatrix.h:2116
Tag TagType
Tag type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:264
size_t capacity_
The maximum capacity of the matrix.
Definition: DynamicMatrix.h:567
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: DynamicMatrix.h:1053
~DynamicMatrix()
The destructor for DynamicMatrix.
Definition: DynamicMatrix.h:1022
void swap(DynamicMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:2167
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DynamicMatrix.h:1782
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2511
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: DynamicMatrix.h:2433
DynamicMatrix< Type,!SO, Alloc, Tag > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DynamicMatrix.h:256
Type ElementType
Type of the matrix elements.
Definition: DynamicMatrix.h:261
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: DynamicMatrix.h:314
DenseMatrix< This, SO > BaseType
Base type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:252
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: DynamicMatrix.h:3156
size_t nn_
The alignment adjusted number of columns.
Definition: DynamicMatrix.h:566
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: DynamicMatrix.h:2028
bool isIntact() const noexcept
Returns whether the invariants of the dynamic matrix are intact.
Definition: DynamicMatrix.h:2349
DynamicMatrix & operator=(const Type &rhs) &
Homogenous assignment to all matrix elements.
Definition: DynamicMatrix.h:1397
DynamicMatrix< Type, SO, Alloc, Tag > This
Type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:251
size_t m_
The current number of rows of the matrix.
Definition: DynamicMatrix.h:564
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1370
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: DynamicMatrix.h:2653
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: DynamicMatrix.h:2391
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: DynamicMatrix.h:308
auto assign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedAssign_v< MT > >
Default implementation of the assignment of a row-major dense matrix.
Definition: DynamicMatrix.h:2723
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: DynamicMatrix.h:468
DynamicMatrix< Type,!SO, Alloc, Tag > TransposeType
Transpose type for expression template evaluations.
Definition: DynamicMatrix.h:259
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: DynamicMatrix.h:2148
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: DynamicMatrix.h:1879
DenseIterator< Type, align > Iterator
Iterator over non-constant elements.
Definition: DynamicMatrix.h:273
DenseIterator< const Type, align > ConstIterator
Iterator over constant elements.
Definition: DynamicMatrix.h:274
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: DynamicMatrix.h:1835
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2481
void clear()
Clearing the matrix.
Definition: DynamicMatrix.h:1982
This ResultType
Result type for expression template evaluations.
Definition: DynamicMatrix.h:253
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: DynamicMatrix.h:1161
Type & Reference
Reference to a non-constant matrix value.
Definition: DynamicMatrix.h:268
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: DynamicMatrix.h:2454
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2548
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: DynamicMatrix.h:1102
const Type & ConstReference
Reference to a constant matrix value.
Definition: DynamicMatrix.h:269
size_t addPadding(size_t value) const noexcept
Add the necessary amount of padding to the given value.
Definition: DynamicMatrix.h:2193
DynamicMatrix(const Alloc &alloc=Alloc{}) noexcept
The (default) constructor for DynamicMatrix.
Definition: DynamicMatrix.h:637
BLAZE_NO_UNIQUE_ADDRESS Alloc alloc_
The allocator of the matrix.
Definition: DynamicMatrix.h:580
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1250
SIMDTrait_t< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: DynamicMatrix.h:262
DynamicMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: DynamicMatrix.h:2259
void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: DynamicMatrix.h:2096
static constexpr AlignmentFlag align
Compilation switch for the choice of alignment.
Definition: DynamicMatrix.h:246
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1298
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1322
const This & CompositeType
Data type for composite expression templates.
Definition: DynamicMatrix.h:266
Type * Pointer
Pointer to a non-constant matrix value.
Definition: DynamicMatrix.h:270
size_t n_
The current number of columns of the matrix.
Definition: DynamicMatrix.h:565
Base class for matrices.
Definition: Matrix.h:85
SIMD characteristics of data types.
Definition: SIMDTrait.h:297
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Initializer list type of the Blaze library.
Header file for the DenseMatrix base class.
Header file for the SparseMatrix base class.
void uninitialized_value_construct(ForwardIt first, ForwardIt last)
Value constructs elements in the given range.
Definition: UninitializedValueConstruct.h:69
void uninitialized_default_construct_n(ForwardIt first, size_t n)
Default constructs elements in the given range.
Definition: UninitializedDefaultConstruct.h:100
void uninitialized_default_construct(ForwardIt first, ForwardIt last)
Default constructs elements in the given range.
Definition: UninitializedDefaultConstruct.h:69
void destroy_n(ForwardIt first, size_t n)
Destroys the given range of objects .
Definition: Destroy.h:87
ForwardIt uninitialized_transfer(InputIt first, InputIt last, ForwardIt dest)
Transfers the elements from the given source range to the uninitialized destination range.
Definition: UninitializedTransfer.h:73
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.
Definition: Const.h:79
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TAG(A, B)
Data type constraint.
Definition: SameTag.h:68
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1339
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1501
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) inv(const DenseMatrix< MT, SO > &dm)
Calculation of the inverse of the given dense matrix.
Definition: DMatInvExpr.h:405
void swap(DynamicMatrix< Type, SO, Alloc, Tag > &a, DynamicMatrix< Type, SO, Alloc, Tag > &b) noexcept
Swapping the contents of two dynamic matrices.
Definition: DynamicMatrix.h:7059
bool isDefault(const DynamicMatrix< Type, SO, Alloc, Tag > &m)
Returns whether the given dynamic matrix is in default state.
Definition: DynamicMatrix.h:7011
bool isIntact(const DynamicMatrix< Type, SO, Alloc, Tag > &m) noexcept
Returns whether the invariants of the given dynamic matrix are intact.
Definition: DynamicMatrix.h:7040
decltype(auto) elements(Vector< VT, TF > &vector, REAs... args)
Creating a view on a selection of elements of the given vector.
Definition: Elements.h:143
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Diagonal.h:79
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric_v< T >)
Swapping two conjugated values/objects.
Definition: Conjugate.h:193
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:118
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr ptrdiff_t DefaultMaxSize_v
Default size of the MaxSize type trait.
Definition: MaxSize.h:72
constexpr bool IsScalar_v
Auxiliary variable template for the IsScalar type trait.
Definition: IsScalar.h:104
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr ptrdiff_t DefaultSize_v
Default size of the Size type trait.
Definition: Size.h:72
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.
Definition: IsDiagonal.h:148
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.
Definition: IsMatrix.h:124
constexpr bool IsColumnVector_v
Auxiliary variable template for the IsColumnVector type trait.
Definition: IsColumnVector.h:126
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
constexpr bool IsDenseMatrix_v
Auxiliary variable template for the IsDenseMatrix type trait.
Definition: IsDenseMatrix.h:124
constexpr bool IsDenseVector_v
Auxiliary variable template for the IsDenseVector type trait.
Definition: IsDenseVector.h:124
typename DynamicAllocator< As... >::template Type< T > DynamicAllocator_t
Auxiliary alias declaration for the DynamicAllocator type trait.
Definition: DynamicAllocator.h:211
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
constexpr Infinity inf
Global Infinity instance.
Definition: Infinity.h:1080
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:107
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.
Definition: AlignmentFlag.h:63
@ unaligned
Flag for unaligned vectors and matrices.
Definition: AlignmentFlag.h:64
@ aligned
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
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
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_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
#define BLAZE_RESTRICT
Compiler dependent setup of the [[no_unique_address]] attribute.
Definition: Restrict.h:81
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
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.
Definition: IntegralConstant.h:110
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
#define BLAZE_THROW_BAD_ALLOC
Macro for the emission of a std::bad_alloc exception.
Definition: Exception.h:139
Header file for the exception macros of the math module.
Header file for all forward declarations of the math module.
Header file for the extended initializer_list functionality.
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Header file for all forward declarations for dense vectors and matrices.
Header file for the Size type trait.
Header file for the StorageOrder type trait.
Header file for the clear shim.
Header file for the reset shim.
Rebind mechanism to obtain a DynamicMatrix with different data/element type.
Definition: DynamicMatrix.h:282
DynamicMatrix< NewType, SO, NewAlloc, Tag > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:287
typename std::allocator_traits< Alloc >::template rebind_alloc< NewType > NewAlloc
The new type of allocator.
Definition: DynamicMatrix.h:284
Resize mechanism to obtain a DynamicMatrix with different fixed dimensions.
Definition: DynamicMatrix.h:297
DynamicMatrix< Type, SO, Alloc, Tag > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:298
Definition of the nested auxiliary struct Uninitialized.
Definition: DynamicMatrix.h:543
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
System settings for the restrict keyword.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for basic type definitions.