DMatTransposer.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTRANSPOSER_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATTRANSPOSER_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
50 #include <blaze/math/shims/Reset.h>
56 #include <blaze/system/Blocking.h>
57 #include <blaze/system/Inline.h>
58 #include <blaze/util/Assert.h>
59 #include <blaze/util/EnableIf.h>
61 #include <blaze/util/Types.h>
63 
64 
65 namespace blaze {
66 
67 //=================================================================================================
68 //
69 // CLASS DMATTRANSPOSER
70 //
71 //=================================================================================================
72 
73 //*************************************************************************************************
79 template< typename MT // Type of the dense matrix
80  , bool SO > // Storage order
82  : public DenseMatrix< DMatTransposer<MT,SO>, SO >
83 {
84  public:
85  //**Type definitions****************************************************************************
93  using CompositeType = const This&;
100  //**********************************************************************************************
101 
102  //**Compilation flags***************************************************************************
104 
107  enum : bool { simdEnabled = MT::simdEnabled };
108 
110 
113  enum : bool { smpAssignable = MT::smpAssignable };
114  //**********************************************************************************************
115 
116  //**Constructor*********************************************************************************
121  explicit inline DMatTransposer( MT& dm ) noexcept
122  : dm_( dm ) // The dense matrix operand
123  {}
124  //**********************************************************************************************
125 
126  //**Access operator*****************************************************************************
133  inline Reference operator()( size_t i, size_t j ) {
134  BLAZE_INTERNAL_ASSERT( i < dm_.columns(), "Invalid row access index" );
135  BLAZE_INTERNAL_ASSERT( j < dm_.rows() , "Invalid column access index" );
136  return dm_(j,i);
137  }
138  //**********************************************************************************************
139 
140  //**Access operator*****************************************************************************
147  inline ConstReference operator()( size_t i, size_t j ) const {
148  BLAZE_INTERNAL_ASSERT( i < dm_.columns(), "Invalid row access index" );
149  BLAZE_INTERNAL_ASSERT( j < dm_.rows() , "Invalid column access index" );
150  return dm_(j,i);
151  }
152  //**********************************************************************************************
153 
154  //**At function*********************************************************************************
162  inline Reference at( size_t i, size_t j ) {
163  if( i >= dm_.columns() ) {
164  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
165  }
166  if( j >= dm_.rows() ) {
167  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
168  }
169  return (*this)(i,j);
170  }
171  //**********************************************************************************************
172 
173  //**At function*********************************************************************************
181  inline ConstReference at( size_t i, size_t j ) const {
182  if( i >= dm_.columns() ) {
183  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
184  }
185  if( j >= dm_.rows() ) {
186  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
187  }
188  return (*this)(i,j);
189  }
190  //**********************************************************************************************
191 
192  //**Low-level data access***********************************************************************
197  inline Pointer data() noexcept {
198  return dm_.data();
199  }
200  //**********************************************************************************************
201 
202  //**Low-level data access***********************************************************************
207  inline ConstPointer data() const noexcept {
208  return dm_.data();
209  }
210  //**********************************************************************************************
211 
212  //**Begin function******************************************************************************
223  inline Iterator begin( size_t i ) {
224  return dm_.begin( i );
225  }
226  //**********************************************************************************************
227 
228  //**Begin function******************************************************************************
239  inline ConstIterator begin( size_t i ) const {
240  return dm_.cbegin( i );
241  }
242  //**********************************************************************************************
243 
244  //**Cbegin function*****************************************************************************
255  inline ConstIterator cbegin( size_t i ) const {
256  return dm_.cbegin( i );
257  }
258  //**********************************************************************************************
259 
260  //**End function********************************************************************************
271  inline Iterator end( size_t i ) {
272  return dm_.end( i );
273  }
274  //**********************************************************************************************
275 
276  //**End function********************************************************************************
287  inline ConstIterator end( size_t i ) const {
288  return dm_.cend( i );
289  }
290  //**********************************************************************************************
291 
292  //**Cend function*******************************************************************************
303  inline ConstIterator cend( size_t i ) const {
304  return dm_.cend( i );
305  }
306  //**********************************************************************************************
307 
308  //**Multiplication assignment operator**********************************************************
315  template< typename Other > // Data type of the right-hand side scalar
317  {
318  (~dm_) *= rhs;
319  return *this;
320  }
321  //**********************************************************************************************
322 
323  //**Division assignment operator****************************************************************
332  template< typename Other > // Data type of the right-hand side scalar
334  {
335  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
336 
337  (~dm_) /= rhs;
338  return *this;
339  }
340  //**********************************************************************************************
341 
342  //**Rows function*******************************************************************************
347  inline size_t rows() const noexcept {
348  return dm_.columns();
349  }
350  //**********************************************************************************************
351 
352  //**Columns function****************************************************************************
357  inline size_t columns() const noexcept {
358  return dm_.rows();
359  }
360  //**********************************************************************************************
361 
362  //**Spacing function****************************************************************************
367  inline size_t spacing() const noexcept {
368  return dm_.spacing();
369  }
370  //**********************************************************************************************
371 
372  //**Reset function******************************************************************************
377  inline void reset() {
378  return dm_.reset();
379  }
380  //**********************************************************************************************
381 
382  //**IsIntact function***************************************************************************
387  inline bool isIntact() const noexcept {
388  using blaze::isIntact;
389  return isIntact( dm_ );
390  }
391  //**********************************************************************************************
392 
393  //**CanAliased function*************************************************************************
399  template< typename Other > // Data type of the foreign expression
400  inline bool canAlias( const Other* alias ) const noexcept
401  {
402  return dm_.canAlias( alias );
403  }
404  //**********************************************************************************************
405 
406  //**IsAliased function**************************************************************************
412  template< typename Other > // Data type of the foreign expression
413  inline bool isAliased( const Other* alias ) const noexcept
414  {
415  return dm_.isAliased( alias );
416  }
417  //**********************************************************************************************
418 
419  //**IsAligned function**************************************************************************
424  inline bool isAligned() const noexcept
425  {
426  return dm_.isAligned();
427  }
428  //**********************************************************************************************
429 
430  //**CanSMPAssign function***********************************************************************
435  inline bool canSMPAssign() const noexcept
436  {
437  return dm_.canSMPAssign();
438  }
439  //**********************************************************************************************
440 
441  //**Load function*******************************************************************************
452  BLAZE_ALWAYS_INLINE SIMDType load( size_t i, size_t j ) const noexcept
453  {
454  return dm_.load( j, i );
455  }
456  //**********************************************************************************************
457 
458  //**Loada function******************************************************************************
469  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept
470  {
471  return dm_.loada( j, i );
472  }
473  //**********************************************************************************************
474 
475  //**Loadu function******************************************************************************
486  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept
487  {
488  return dm_.loadu( j, i );
489  }
490  //**********************************************************************************************
491 
492  //**Store function******************************************************************************
504  BLAZE_ALWAYS_INLINE void store( size_t i, size_t j, const SIMDType& value ) noexcept
505  {
506  dm_.store( j, i, value );
507  }
508  //**********************************************************************************************
509 
510  //**Storea function******************************************************************************
522  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept
523  {
524  dm_.storea( j, i, value );
525  }
526  //**********************************************************************************************
527 
528  //**Storeu function*****************************************************************************
540  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept
541  {
542  dm_.storeu( j, i, value );
543  }
544  //**********************************************************************************************
545 
546  //**Stream function*****************************************************************************
558  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept
559  {
560  dm_.stream( j, i, value );
561  }
562  //**********************************************************************************************
563 
564  //**Transpose assignment of row-major dense matrices********************************************
575  template< typename MT2 > // Type of the right-hand side dense matrix
576  inline void assign( const DenseMatrix<MT2,SO>& rhs )
577  {
579 
580  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
581  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
582 
583  const size_t m( rows() );
584  const size_t n( columns() );
585 
586  const size_t jpos( n & size_t(-2) );
587  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jpos, "Invalid end calculation" );
588 
589  for( size_t i=0UL; i<m; ++i ) {
590  for( size_t j=0UL; j<jpos; j+=2UL ) {
591  dm_(j ,i) = (~rhs)(i,j );
592  dm_(j+1UL,i) = (~rhs)(i,j+1UL);
593  }
594  if( jpos < n ) {
595  dm_(jpos,i) = (~rhs)(i,jpos);
596  }
597  }
598  }
599  //**********************************************************************************************
600 
601  //**Transpose assignment of column-major dense matrices*****************************************
612  template< typename MT2 > // Type of the right-hand side dense matrix
613  inline void assign( const DenseMatrix<MT2,!SO>& rhs )
614  {
616 
617  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
618  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
619 
620  constexpr size_t block( BLOCK_SIZE );
621 
622  const size_t m( rows() );
623  const size_t n( columns() );
624 
625  for( size_t ii=0UL; ii<m; ii+=block ) {
626  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
627  for( size_t jj=0UL; jj<n; jj+=block ) {
628  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
629  for( size_t i=ii; i<iend; ++i ) {
630  for( size_t j=jj; j<jend; ++j ) {
631  dm_(j,i) = (~rhs)(i,j);
632  }
633  }
634  }
635  }
636  }
637  //**********************************************************************************************
638 
639  //**Transpose assignment of row-major sparse matrices*******************************************
650  template< typename MT2 > // Type of the right-hand side sparse matrix
651  inline void assign( const SparseMatrix<MT2,SO>& rhs )
652  {
654 
655  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
656  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
657 
658  using RhsConstIterator = ConstIterator_<MT2>;
659 
660  for( size_t i=0UL; i<(~rhs).rows(); ++i )
661  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
662  dm_(element->index(),i) = element->value();
663  }
664  //**********************************************************************************************
665 
666  //**Transpose assignment of column-major sparse matrices****************************************
677  template< typename MT2 > // Type of the right-hand side sparse matrix
678  inline void assign( const SparseMatrix<MT2,!SO>& rhs )
679  {
681 
682  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
683  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
684 
685  using RhsConstIterator = ConstIterator_<MT2>;
686 
687  for( size_t j=0UL; j<(~rhs).columns(); ++j )
688  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
689  dm_(j,element->index()) = element->value();
690  }
691  //**********************************************************************************************
692 
693  //**Transpose addition assignment of row-major dense matrices***********************************
704  template< typename MT2 > // Type of the right-hand side dense matrix
705  inline void addAssign( const DenseMatrix<MT2,SO>& rhs )
706  {
708 
709  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
710  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
711 
712  const size_t m( rows() );
713  const size_t n( columns() );
714 
715  const size_t jpos( n & size_t(-2) );
716  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jpos, "Invalid end calculation" );
717 
718  for( size_t i=0UL; i<m; ++i ) {
719  for( size_t j=0UL; j<jpos; j+=2UL ) {
720  dm_(j ,i) += (~rhs)(i,j );
721  dm_(j+1UL,i) += (~rhs)(i,j+1UL);
722 
723  }
724  if( jpos < n ) {
725  dm_(jpos,i) += (~rhs)(i,jpos);
726  }
727  }
728  }
729  //**********************************************************************************************
730 
731  //**Transpose addition assignment of column-major dense matrices********************************
742  template< typename MT2 > // Type of the right-hand side dense matrix
743  inline void addAssign( const DenseMatrix<MT2,!SO>& rhs )
744  {
746 
747  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
748  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
749 
750  constexpr size_t block( BLOCK_SIZE );
751 
752  const size_t m( rows() );
753  const size_t n( columns() );
754 
755  for( size_t ii=0UL; ii<m; ii+=block ) {
756  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
757  for( size_t jj=0UL; jj<n; jj+=block ) {
758  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
759  for( size_t i=ii; i<iend; ++i ) {
760  for( size_t j=jj; j<jend; ++j ) {
761  dm_(j,i) += (~rhs)(i,j);
762  }
763  }
764  }
765  }
766  }
767  //**********************************************************************************************
768 
769  //**Transpose addition assignment of row-major sparse matrices**********************************
780  template< typename MT2 > // Type of the right-hand side sparse matrix
781  inline void addAssign( const SparseMatrix<MT2,SO>& rhs )
782  {
784 
785  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
786  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
787 
788  using RhsConstIterator = ConstIterator_<MT2>;
789 
790  for( size_t i=0UL; i<(~rhs).rows(); ++i )
791  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
792  dm_(element->index(),i) += element->value();
793  }
794  //**********************************************************************************************
795 
796  //**Transpose addition assignment of column-major sparse matrices*******************************
807  template< typename MT2 > // Type of the right-hand side sparse matrix
808  inline void addAssign( const SparseMatrix<MT2,!SO>& rhs )
809  {
811 
812  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
813  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
814 
815  using RhsConstIterator = ConstIterator_<MT2>;
816 
817  for( size_t j=0UL; j<(~rhs).columns(); ++j )
818  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
819  dm_(j,element->index()) += element->value();
820  }
821  //**********************************************************************************************
822 
823  //**Transpose subtraction assignment of row-major dense matrices********************************
834  template< typename MT2 > // Type of the right-hand side dense matrix
835  inline void subAssign( const DenseMatrix<MT2,SO>& rhs )
836  {
838 
839  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
840  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
841 
842  const size_t m( rows() );
843  const size_t n( columns() );
844 
845  const size_t jpos( n & size_t(-2) );
846  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jpos, "Invalid end calculation" );
847 
848  for( size_t i=0UL; i<m; ++i ) {
849  for( size_t j=0UL; j<jpos; j+=2UL ) {
850  dm_(j ,i) -= (~rhs)(i,j );
851  dm_(j+1UL,i) -= (~rhs)(i,j+1UL);
852 
853  }
854  if( jpos < n ) {
855  dm_(jpos,i) -= (~rhs)(i,jpos);
856  }
857  }
858  }
859  //**********************************************************************************************
860 
861  //**Transpose subtraction assignment of column-major dense matrices*****************************
872  template< typename MT2 > // Type of the right-hand side dense matrix
873  inline void subAssign( const DenseMatrix<MT2,!SO>& rhs )
874  {
876 
877  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
878  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
879 
880  constexpr size_t block( BLOCK_SIZE );
881 
882  const size_t m( rows() );
883  const size_t n( columns() );
884 
885  for( size_t ii=0UL; ii<m; ii+=block ) {
886  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
887  for( size_t jj=0UL; jj<n; jj+=block ) {
888  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
889  for( size_t i=ii; i<iend; ++i ) {
890  for( size_t j=jj; j<jend; ++j ) {
891  dm_(j,i) -= (~rhs)(i,j);
892  }
893  }
894  }
895  }
896  }
897  //**********************************************************************************************
898 
899  //**Transpose subtraction assignment of row-major sparse matrices*******************************
910  template< typename MT2 > // Type of the right-hand side sparse matrix
911  inline void subAssign( const SparseMatrix<MT2,SO>& rhs )
912  {
914 
915  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
916  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
917 
918  using RhsConstIterator = ConstIterator_<MT2>;
919 
920  for( size_t i=0UL; i<(~rhs).rows(); ++i )
921  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
922  dm_(element->index(),i) -= element->value();
923  }
924  //**********************************************************************************************
925 
926  //**Transpose subtraction assignment of column-major dense matrices*****************************
937  template< typename MT2 > // Type of the right-hand side sparse matrix
938  inline void subAssign( const SparseMatrix<MT2,!SO>& rhs )
939  {
941 
942  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
943  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
944 
945  using RhsConstIterator = ConstIterator_<MT2>;
946 
947  for( size_t j=0UL; j<(~rhs).columns(); ++j )
948  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
949  dm_(j,element->index()) -= element->value();
950  }
951  //**********************************************************************************************
952 
953  //**Transpose Schur product assignment of row-major dense matrices******************************
964  template< typename MT2 > // Type of the right-hand side dense matrix
965  inline void schurAssign( const DenseMatrix<MT2,SO>& rhs )
966  {
968 
969  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
970  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
971 
972  const size_t m( rows() );
973  const size_t n( columns() );
974 
975  const size_t jpos( n & size_t(-2) );
976  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == jpos, "Invalid end calculation" );
977 
978  for( size_t i=0UL; i<m; ++i ) {
979  for( size_t j=0UL; j<jpos; j+=2UL ) {
980  dm_(j ,i) *= (~rhs)(i,j );
981  dm_(j+1UL,i) *= (~rhs)(i,j+1UL);
982 
983  }
984  if( jpos < n ) {
985  dm_(jpos,i) *= (~rhs)(i,jpos);
986  }
987  }
988  }
989  //**********************************************************************************************
990 
991  //**Transpose Schur product assignment of column-major dense matrices***************************
1002  template< typename MT2 > // Type of the right-hand side dense matrix
1003  inline void schurAssign( const DenseMatrix<MT2,!SO>& rhs )
1004  {
1006 
1007  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1008  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1009 
1010  constexpr size_t block( BLOCK_SIZE );
1011 
1012  const size_t m( rows() );
1013  const size_t n( columns() );
1014 
1015  for( size_t ii=0UL; ii<m; ii+=block ) {
1016  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
1017  for( size_t jj=0UL; jj<n; jj+=block ) {
1018  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
1019  for( size_t i=ii; i<iend; ++i ) {
1020  for( size_t j=jj; j<jend; ++j ) {
1021  dm_(j,i) *= (~rhs)(i,j);
1022  }
1023  }
1024  }
1025  }
1026  }
1027  //**********************************************************************************************
1028 
1029  //**Transpose Schur product assignment of row-major sparse matrices*****************************
1040  template< typename MT2 > // Type of the right-hand side sparse matrix
1041  inline void schurAssign( const SparseMatrix<MT2,SO>& rhs )
1042  {
1043  using blaze::reset;
1044 
1046 
1047  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1048  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1049 
1050  using RhsConstIterator = ConstIterator_<MT2>;
1051 
1052  for( size_t i=0UL; i<(~rhs).rows(); ++i )
1053  {
1054  size_t j( 0UL );
1055 
1056  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
1057  for( ; j<element->index(); ++j )
1058  reset( dm_(j,i) );
1059  dm_(j,i) *= element->value();
1060  ++j;
1061  }
1062 
1063  for( ; j<(~rhs).columns(); ++j ) {
1064  reset( dm_(j,i) );
1065  }
1066  }
1067  }
1068  //**********************************************************************************************
1069 
1070  //**Transpose Schur product assignment of column-major sparse matrices**************************
1081  template< typename MT2 > // Type of the right-hand side sparse matrix
1082  inline void schurAssign( const SparseMatrix<MT2,!SO>& rhs )
1083  {
1084  using blaze::reset;
1085 
1087 
1088  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1089  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1090 
1091  using RhsConstIterator = ConstIterator_<MT2>;
1092 
1093  for( size_t j=0UL; j<(~rhs).columns(); ++j )
1094  {
1095  size_t i( 0UL );
1096 
1097  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
1098  for( ; i<element->index(); ++i )
1099  reset( dm_(j,i) );
1100  dm_(j,i) *= element->value();
1101  ++i;
1102  }
1103 
1104  for( ; i<(~rhs).rows(); ++i ) {
1105  reset( dm_(j,i) );
1106  }
1107  }
1108  }
1109  //**********************************************************************************************
1110 
1111  //**Transpose multiplication assignment of dense matrices***************************************
1112  // No special implementation for the transpose multiplication assignment of dense matrices.
1113  //**********************************************************************************************
1114 
1115  //**Transpose multiplication assignment of sparse matrices**************************************
1116  // No special implementation for the transpose multiplication assignment of sparse matrices.
1117  //**********************************************************************************************
1118 
1119  private:
1120  //**Member variables****************************************************************************
1121  MT& dm_;
1122  //**********************************************************************************************
1123 
1124  //**Compile time checks*************************************************************************
1130  //**********************************************************************************************
1131 };
1132 //*************************************************************************************************
1133 
1134 
1135 
1136 
1137 //=================================================================================================
1138 //
1139 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR MATRICES
1140 //
1141 //=================================================================================================
1142 
1143 //*************************************************************************************************
1151 template< typename MT > // Type of the dense matrix
1152 class DMatTransposer<MT,true>
1153  : public DenseMatrix< DMatTransposer<MT,true>, true >
1154 {
1155  public:
1156  //**Type definitions****************************************************************************
1157  using This = DMatTransposer<MT,true>;
1158  using ResultType = TransposeType_<MT>;
1160  using TransposeType = ResultType_<MT>;
1161  using ElementType = ElementType_<MT>;
1163  using ReturnType = ReturnType_<MT>;
1164  using CompositeType = const This&;
1165  using Reference = Reference_<MT>;
1167  using Pointer = Pointer_<MT>;
1169  using Iterator = Iterator_<MT>;
1171  //**********************************************************************************************
1172 
1173  //**Compilation flags***************************************************************************
1175 
1178  enum : bool { simdEnabled = MT::simdEnabled };
1179 
1181 
1184  enum : bool { smpAssignable = MT::smpAssignable };
1185  //**********************************************************************************************
1186 
1187  //**Constructor*********************************************************************************
1192  explicit inline DMatTransposer( MT& dm ) noexcept
1193  : dm_( dm ) // The dense matrix operand
1194  {}
1195  //**********************************************************************************************
1196 
1197  //**Access operator*****************************************************************************
1204  inline Reference operator()( size_t i, size_t j ) {
1205  BLAZE_INTERNAL_ASSERT( i < dm_.columns(), "Invalid row access index" );
1206  BLAZE_INTERNAL_ASSERT( j < dm_.rows() , "Invalid column access index" );
1207  return dm_(j,i);
1208  }
1209  //**********************************************************************************************
1210 
1211  //**Access operator*****************************************************************************
1218  inline ConstReference operator()( size_t i, size_t j ) const {
1219  BLAZE_INTERNAL_ASSERT( i < dm_.columns(), "Invalid row access index" );
1220  BLAZE_INTERNAL_ASSERT( j < dm_.rows() , "Invalid column access index" );
1221  return dm_(j,i);
1222  }
1223  //**********************************************************************************************
1224 
1225  //**At function*********************************************************************************
1233  inline Reference at( size_t i, size_t j ) {
1234  if( i >= dm_.columns() ) {
1235  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1236  }
1237  if( j >= dm_.rows() ) {
1238  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1239  }
1240  return (*this)(i,j);
1241  }
1242  //**********************************************************************************************
1243 
1244  //**At function*********************************************************************************
1252  inline ConstReference at( size_t i, size_t j ) const {
1253  if( i >= dm_.columns() ) {
1254  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1255  }
1256  if( j >= dm_.rows() ) {
1257  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1258  }
1259  return (*this)(i,j);
1260  }
1261  //**********************************************************************************************
1262 
1263  //**Low-level data access***********************************************************************
1268  inline Pointer data() noexcept {
1269  return dm_.data();
1270  }
1271  //**********************************************************************************************
1272 
1273  //**Low-level data access***********************************************************************
1278  inline ConstPointer data() const noexcept {
1279  return dm_.data();
1280  }
1281  //**********************************************************************************************
1282 
1283  //**Begin function******************************************************************************
1289  inline Iterator begin( size_t j ) {
1290  return dm_.begin(j);
1291  }
1292  //**********************************************************************************************
1293 
1294  //**Begin function******************************************************************************
1300  inline ConstIterator begin( size_t j ) const {
1301  return dm_.cbegin(j);
1302  }
1303  //**********************************************************************************************
1304 
1305  //**Cbegin function*****************************************************************************
1311  inline ConstIterator cbegin( size_t j ) const {
1312  return dm_.cbegin(j);
1313  }
1314  //**********************************************************************************************
1315 
1316  //**End function********************************************************************************
1322  inline Iterator end( size_t j ) {
1323  return dm_.end(j);
1324  }
1325  //**********************************************************************************************
1326 
1327  //**End function********************************************************************************
1333  inline ConstIterator end( size_t j ) const {
1334  return dm_.cend(j);
1335  }
1336  //**********************************************************************************************
1337 
1338  //**Cend function*******************************************************************************
1344  inline ConstIterator cend( size_t j ) const {
1345  return dm_.cend(j);
1346  }
1347  //**********************************************************************************************
1348 
1349  //**Multiplication assignment operator**********************************************************
1356  template< typename Other > // Data type of the right-hand side scalar
1357  inline EnableIf_< IsNumeric<Other>, DMatTransposer >& operator*=( Other rhs )
1358  {
1359  (~dm_) *= rhs;
1360  return *this;
1361  }
1362  //**********************************************************************************************
1363 
1364  //**Division assignment operator****************************************************************
1373  template< typename Other > // Data type of the right-hand side scalar
1374  inline EnableIf_< IsNumeric<Other>, DMatTransposer >& operator/=( Other rhs )
1375  {
1376  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1377 
1378  (~dm_) /= rhs;
1379  return *this;
1380  }
1381  //**********************************************************************************************
1382 
1383  //**Rows function*******************************************************************************
1388  inline size_t rows() const noexcept {
1389  return dm_.columns();
1390  }
1391  //**********************************************************************************************
1392 
1393  //**Columns function****************************************************************************
1398  inline size_t columns() const noexcept {
1399  return dm_.rows();
1400  }
1401  //**********************************************************************************************
1402 
1403  //**Spacing function****************************************************************************
1408  inline size_t spacing() const noexcept {
1409  return dm_.spacing();
1410  }
1411  //**********************************************************************************************
1412 
1413  //**Reset function******************************************************************************
1418  inline void reset() {
1419  return dm_.reset();
1420  }
1421  //**********************************************************************************************
1422 
1423  //**IsIntact function***************************************************************************
1428  inline bool isIntact() const noexcept {
1429  using blaze::isIntact;
1430  return isIntact( dm_ );
1431  }
1432  //**********************************************************************************************
1433 
1434  //**CanAliased function*************************************************************************
1440  template< typename Other > // Data type of the foreign expression
1441  inline bool canAlias( const Other* alias ) const noexcept
1442  {
1443  return dm_.canAlias( alias );
1444  }
1445  //**********************************************************************************************
1446 
1447  //**IsAliased function**************************************************************************
1453  template< typename Other > // Data type of the foreign expression
1454  inline bool isAliased( const Other* alias ) const noexcept
1455  {
1456  return dm_.isAliased( alias );
1457  }
1458  //**********************************************************************************************
1459 
1460  //**IsAligned function**************************************************************************
1465  inline bool isAligned() const noexcept
1466  {
1467  return dm_.isAligned();
1468  }
1469  //**********************************************************************************************
1470 
1471  //**CanSMPAssign function***********************************************************************
1476  inline bool canSMPAssign() const noexcept
1477  {
1478  return dm_.canSMPAssign();
1479  }
1480  //**********************************************************************************************
1481 
1482  //**Load function*******************************************************************************
1493  BLAZE_ALWAYS_INLINE SIMDType load( size_t i, size_t j ) const noexcept
1494  {
1495  return dm_.load( j, i );
1496  }
1497  //**********************************************************************************************
1498 
1499  //**Loada function*******************************************************************************
1510  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept
1511  {
1512  return dm_.loada( j, i );
1513  }
1514  //**********************************************************************************************
1515 
1516  //**Loadu function******************************************************************************
1527  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept
1528  {
1529  return dm_.loadu( j, i );
1530  }
1531  //**********************************************************************************************
1532 
1533  //**Store function******************************************************************************
1545  BLAZE_ALWAYS_INLINE void store( size_t i, size_t j, const SIMDType& value ) noexcept
1546  {
1547  dm_.store( j, i, value );
1548  }
1549  //**********************************************************************************************
1550 
1551  //**Storea function******************************************************************************
1563  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept
1564  {
1565  dm_.storea( j, i, value );
1566  }
1567  //**********************************************************************************************
1568 
1569  //**Storeu function*****************************************************************************
1581  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept
1582  {
1583  dm_.storeu( j, i, value );
1584  }
1585  //**********************************************************************************************
1586 
1587  //**Stream function*****************************************************************************
1599  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept
1600  {
1601  dm_.stream( j, i, value );
1602  }
1603  //**********************************************************************************************
1604 
1605  //**Transpose assignment of column-major dense matrices*****************************************
1616  template< typename MT2 > // Type of the right-hand side dense matrix
1617  inline void assign( const DenseMatrix<MT2,true>& rhs )
1618  {
1620 
1621  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1622  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1623 
1624  const size_t m( rows() );
1625  const size_t n( columns() );
1626 
1627  const size_t ipos( m & size_t(-2) );
1628  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ipos, "Invalid end calculation" );
1629 
1630  for( size_t j=0UL; j<n; ++j ) {
1631  for( size_t i=0UL; i<ipos; i+=2UL ) {
1632  dm_(j,i ) = (~rhs)(i ,j);
1633  dm_(j,i+1UL) = (~rhs)(i+1UL,j);
1634  }
1635  if( ipos < m ) {
1636  dm_(j,ipos) = (~rhs)(ipos,j);
1637  }
1638  }
1639  }
1640  //**********************************************************************************************
1641 
1642  //**Transpose assignment of row-major dense matrices********************************************
1653  template< typename MT2 > // Type of the right-hand side dense matrix
1654  inline void assign( const DenseMatrix<MT2,false>& rhs )
1655  {
1657 
1658  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1659  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1660 
1661  constexpr size_t block( BLOCK_SIZE );
1662 
1663  const size_t m( rows() );
1664  const size_t n( columns() );
1665 
1666  for( size_t jj=0UL; jj<n; jj+=block ) {
1667  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
1668  for( size_t ii=0UL; ii<m; ii+=block ) {
1669  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
1670  for( size_t j=jj; j<jend; ++j ) {
1671  for( size_t i=ii; i<iend; ++i ) {
1672  dm_(j,i) = (~rhs)(i,j);
1673  }
1674  }
1675  }
1676  }
1677  }
1678  //**********************************************************************************************
1679 
1680  //**Transpose assignment of column-major sparse matrices****************************************
1691  template< typename MT2 > // Type of the right-hand side sparse matrix
1692  inline void assign( const SparseMatrix<MT2,true>& rhs )
1693  {
1695 
1696  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1697  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1698 
1699  using RhsConstIterator = ConstIterator_<MT2>;
1700 
1701  for( size_t j=0UL; j<(~rhs).columns(); ++j )
1702  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1703  dm_(j,element->index()) = element->value();
1704  }
1705  //**********************************************************************************************
1706 
1707  //**Transpose assignment of row-major sparse matrices*******************************************
1718  template< typename MT2 > // Type of the right-hand side sparse matrix
1719  inline void assign( const SparseMatrix<MT2,false>& rhs )
1720  {
1722 
1723  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1724  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1725 
1726  using RhsConstIterator = ConstIterator_<MT2>;
1727 
1728  for( size_t i=0UL; i<(~rhs).rows(); ++i )
1729  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1730  dm_(element->index(),i) = element->value();
1731  }
1732  //**********************************************************************************************
1733 
1734  //**Transpose addition assignment of column-major dense matrices********************************
1745  template< typename MT2 > // Type of the right-hand side dense matrix
1746  inline void addAssign( const DenseMatrix<MT2,true>& rhs )
1747  {
1749 
1750  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1751  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1752 
1753  const size_t m( rows() );
1754  const size_t n( columns() );
1755 
1756  const size_t ipos( m & size_t(-2) );
1757  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ipos, "Invalid end calculation" );
1758 
1759  for( size_t j=0UL; j<n; ++j ) {
1760  for( size_t i=0UL; i<ipos; i+=2UL ) {
1761  dm_(j,i ) += (~rhs)(i ,j);
1762  dm_(j,i+1UL) += (~rhs)(i+1UL,j);
1763  }
1764  if( ipos < m ) {
1765  dm_(j,ipos) += (~rhs)(ipos,j);
1766  }
1767  }
1768  }
1769  //**********************************************************************************************
1770 
1771  //**Transpose addition assignment of row-major dense matrices***********************************
1782  template< typename MT2 > // Type of the right-hand side dense matrix
1783  inline void addAssign( const DenseMatrix<MT2,false>& rhs )
1784  {
1786 
1787  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1788  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1789 
1790  constexpr size_t block( BLOCK_SIZE );
1791 
1792  const size_t m( rows() );
1793  const size_t n( columns() );
1794 
1795  for( size_t jj=0UL; jj<n; jj+=block ) {
1796  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
1797  for( size_t ii=0UL; ii<m; ii+=block ) {
1798  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
1799  for( size_t j=jj; j<jend; ++j ) {
1800  for( size_t i=ii; i<iend; ++i ) {
1801  dm_(j,i) += (~rhs)(i,j);
1802  }
1803  }
1804  }
1805  }
1806  }
1807  //**********************************************************************************************
1808 
1809  //**Transpose addition assignment of column-major sparse matrices*******************************
1820  template< typename MT2 > // Type of the right-hand side sparse matrix
1821  inline void addAssign( const SparseMatrix<MT2,true>& rhs )
1822  {
1824 
1825  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1826  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1827 
1828  using RhsConstIterator = ConstIterator_<MT2>;
1829 
1830  for( size_t j=0UL; j<(~rhs).columns(); ++j )
1831  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1832  dm_(j,element->index()) += element->value();
1833  }
1834  //**********************************************************************************************
1835 
1836  //**Transpose addition assignment of row-major sparse matrices**********************************
1847  template< typename MT2 > // Type of the right-hand side sparse matrix
1848  inline void addAssign( const SparseMatrix<MT2,false>& rhs )
1849  {
1851 
1852  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1853  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1854 
1855  using RhsConstIterator = ConstIterator_<MT2>;
1856 
1857  for( size_t i=0UL; i<(~rhs).rows(); ++i )
1858  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1859  dm_(element->index(),i) += element->value();
1860  }
1861  //**********************************************************************************************
1862 
1863  //**Transpose subtraction assignment of column-major dense matrices*****************************
1874  template< typename MT2 > // Type of the right-hand side dense matrix
1875  inline void subAssign( const DenseMatrix<MT2,true>& rhs )
1876  {
1878 
1879  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1880  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1881 
1882  const size_t m( rows() );
1883  const size_t n( columns() );
1884 
1885  const size_t ipos( m & size_t(-2) );
1886  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ipos, "Invalid end calculation" );
1887 
1888  for( size_t j=0UL; j<n; ++j ) {
1889  for( size_t i=0UL; i<ipos; i+=2UL ) {
1890  dm_(j,i ) -= (~rhs)(i ,j);
1891  dm_(j,i+1UL) -= (~rhs)(i+1UL,j);
1892  }
1893  if( ipos < m ) {
1894  dm_(j,ipos) -= (~rhs)(ipos,j);
1895  }
1896  }
1897  }
1898  //**********************************************************************************************
1899 
1900  //**Transpose subtraction assignment of row-major dense matrices********************************
1911  template< typename MT2 > // Type of the right-hand side dense matrix
1912  inline void subAssign( const DenseMatrix<MT2,false>& rhs )
1913  {
1915 
1916  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1917  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1918 
1919  constexpr size_t block( BLOCK_SIZE );
1920 
1921  const size_t m( rows() );
1922  const size_t n( columns() );
1923 
1924  for( size_t jj=0UL; jj<n; jj+=block ) {
1925  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
1926  for( size_t ii=0UL; ii<m; ii+=block ) {
1927  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
1928  for( size_t j=jj; j<jend; ++j ) {
1929  for( size_t i=ii; i<iend; ++i ) {
1930  dm_(j,i) -= (~rhs)(i,j);
1931  }
1932  }
1933  }
1934  }
1935  }
1936  //**********************************************************************************************
1937 
1938  //**Transpose subtraction assignment of column-major sparse matrices****************************
1949  template< typename MT2 > // Type of the right-hand side sparse matrix
1950  inline void subAssign( const SparseMatrix<MT2,true>& rhs )
1951  {
1953 
1954  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1955  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1956 
1957  using RhsConstIterator = ConstIterator_<MT2>;
1958 
1959  for( size_t j=0UL; j<(~rhs).columns(); ++j )
1960  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1961  dm_(j,element->index()) -= element->value();
1962  }
1963  //**********************************************************************************************
1964 
1965  //**Transpose subtraction assignment of row-major dense matrices********************************
1976  template< typename MT2 > // Type of the right-hand side sparse matrix
1977  inline void subAssign( const SparseMatrix<MT2,false>& rhs )
1978  {
1980 
1981  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
1982  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
1983 
1984  using RhsConstIterator = ConstIterator_<MT2>;
1985 
1986  for( size_t i=0UL; i<(~rhs).rows(); ++i )
1987  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1988  dm_(element->index(),i) -= element->value();
1989  }
1990  //**********************************************************************************************
1991 
1992  //**Transpose Schur product assignment of column-major dense matrices***************************
2003  template< typename MT2 > // Type of the right-hand side dense matrix
2004  inline void schurAssign( const DenseMatrix<MT2,true>& rhs )
2005  {
2007 
2008  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
2009  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
2010 
2011  const size_t m( rows() );
2012  const size_t n( columns() );
2013 
2014  const size_t ipos( m & size_t(-2) );
2015  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ipos, "Invalid end calculation" );
2016 
2017  for( size_t j=0UL; j<n; ++j ) {
2018  for( size_t i=0UL; i<ipos; i+=2UL ) {
2019  dm_(j,i ) *= (~rhs)(i ,j);
2020  dm_(j,i+1UL) *= (~rhs)(i+1UL,j);
2021  }
2022  if( ipos < m ) {
2023  dm_(j,ipos) *= (~rhs)(ipos,j);
2024  }
2025  }
2026  }
2027  //**********************************************************************************************
2028 
2029  //**Transpose Schur product assignment of row-major dense matrices******************************
2040  template< typename MT2 > // Type of the right-hand side dense matrix
2041  inline void schurAssign( const DenseMatrix<MT2,false>& rhs )
2042  {
2044 
2045  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
2046  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
2047 
2048  constexpr size_t block( BLOCK_SIZE );
2049 
2050  const size_t m( rows() );
2051  const size_t n( columns() );
2052 
2053  for( size_t jj=0UL; jj<n; jj+=block ) {
2054  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
2055  for( size_t ii=0UL; ii<m; ii+=block ) {
2056  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
2057  for( size_t j=jj; j<jend; ++j ) {
2058  for( size_t i=ii; i<iend; ++i ) {
2059  dm_(j,i) *= (~rhs)(i,j);
2060  }
2061  }
2062  }
2063  }
2064  }
2065  //**********************************************************************************************
2066 
2067  //**Transpose Schur product assignment of column-major sparse matrices**************************
2078  template< typename MT2 > // Type of the right-hand side sparse matrix
2079  inline void schurAssign( const SparseMatrix<MT2,true>& rhs )
2080  {
2081  using blaze::reset;
2082 
2084 
2085  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
2086  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
2087 
2088  using RhsConstIterator = ConstIterator_<MT2>;
2089 
2090  for( size_t j=0UL; j<(~rhs).columns(); ++j )
2091  {
2092  size_t i( 0UL );
2093 
2094  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
2095  for( ; i<element->index(); ++i )
2096  reset( dm_(j,i) );
2097  dm_(j,i) *= element->value();
2098  ++i;
2099  }
2100 
2101  for( ; i<(~rhs).rows(); ++i ) {
2102  reset( dm_(j,i) );
2103  }
2104  }
2105  }
2106  //**********************************************************************************************
2107 
2108  //**Transpose Schur product assignment of row-major sparse matrices*****************************
2119  template< typename MT2 > // Type of the right-hand side sparse matrix
2120  inline void schurAssign( const SparseMatrix<MT2,false>& rhs )
2121  {
2122  using blaze::reset;
2123 
2125 
2126  BLAZE_INTERNAL_ASSERT( dm_.columns() == (~rhs).rows(), "Invalid number of rows" );
2127  BLAZE_INTERNAL_ASSERT( dm_.rows() == (~rhs).columns(), "Invalid number of columns" );
2128 
2129  using RhsConstIterator = ConstIterator_<MT2>;
2130 
2131  for( size_t i=0UL; i<(~rhs).rows(); ++i )
2132  {
2133  size_t j( 0UL );
2134 
2135  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2136  for( ; j<element->index(); ++j )
2137  reset( dm_(j,i) );
2138  dm_(j,i) *= element->value();
2139  ++j;
2140  }
2141 
2142  for( ; j<(~rhs).columns(); ++j ) {
2143  reset( dm_(j,i) );
2144  }
2145  }
2146  }
2147  //**********************************************************************************************
2148 
2149  //**Transpose multiplication assignment of dense matrices***************************************
2150  // No special implementation for the transpose multiplication assignment of dense matrices.
2151  //**********************************************************************************************
2152 
2153  //**Transpose multiplication assignment of sparse matrices**************************************
2154  // No special implementation for the transpose multiplication assignment of sparse matrices.
2155  //**********************************************************************************************
2156 
2157  private:
2158  //**Member variables****************************************************************************
2159  MT& dm_;
2160  //**********************************************************************************************
2161 
2162  //**Compile time checks*************************************************************************
2168  //**********************************************************************************************
2169 };
2171 //*************************************************************************************************
2172 
2173 
2174 
2175 
2176 //=================================================================================================
2177 //
2178 // GLOBAL OPERATORS
2179 //
2180 //=================================================================================================
2181 
2182 //*************************************************************************************************
2190 template< typename MT // Type of the dense matrix
2191  , bool SO > // Storage order
2192 inline void reset( DMatTransposer<MT,SO>& m )
2193 {
2194  m.reset();
2195 }
2197 //*************************************************************************************************
2198 
2199 
2200 //*************************************************************************************************
2208 template< typename MT // Type of the dense matrix
2209  , bool SO > // Storage order
2210 inline bool isIntact( const DMatTransposer<MT,SO>& m ) noexcept
2211 {
2212  return m.isIntact();
2213 }
2215 //*************************************************************************************************
2216 
2217 
2218 
2219 
2220 //=================================================================================================
2221 //
2222 // HASMUTABLEDATAACCESS SPECIALIZATIONS
2223 //
2224 //=================================================================================================
2225 
2226 //*************************************************************************************************
2228 template< typename MT, bool SO >
2229 struct HasMutableDataAccess< DMatTransposer<MT,SO> >
2230  : public BoolConstant< HasMutableDataAccess<MT>::value >
2231 {};
2233 //*************************************************************************************************
2234 
2235 
2236 
2237 
2238 //=================================================================================================
2239 //
2240 // ISALIGNED SPECIALIZATIONS
2241 //
2242 //=================================================================================================
2243 
2244 //*************************************************************************************************
2246 template< typename MT, bool SO >
2247 struct IsAligned< DMatTransposer<MT,SO> >
2248  : public BoolConstant< IsAligned<MT>::value >
2249 {};
2251 //*************************************************************************************************
2252 
2253 
2254 
2255 
2256 //=================================================================================================
2257 //
2258 // ISPADDED SPECIALIZATIONS
2259 //
2260 //=================================================================================================
2261 
2262 //*************************************************************************************************
2264 template< typename MT, bool SO >
2265 struct IsPadded< DMatTransposer<MT,SO> >
2266  : public BoolConstant< IsPadded<MT>::value >
2267 {};
2269 //*************************************************************************************************
2270 
2271 
2272 
2273 
2274 //=================================================================================================
2275 //
2276 // SUBMATRIXTRAIT SPECIALIZATIONS
2277 //
2278 //=================================================================================================
2279 
2280 //*************************************************************************************************
2282 template< typename MT, bool SO >
2283 struct SubmatrixTrait< DMatTransposer<MT,SO> >
2284 {
2286 };
2288 //*************************************************************************************************
2289 
2290 } // namespace blaze
2291 
2292 #endif
void schurAssign(const SparseMatrix< MT2,!SO > &rhs)
Implementation of the transpose Schur product assignment of a column-major sparse matrix...
Definition: DMatTransposer.h:1082
Constraint on the data type.
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: DMatTransposer.h:522
Header file for auxiliary alias declarations.
void addAssign(const SparseMatrix< MT2, SO > &rhs)
Implementation of the transpose addition assignment of a row-major sparse matrix. ...
Definition: DMatTransposer.h:781
Header file for kernel specific block sizes.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
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: DMatTransposer.h:540
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: DMatTransposer.h:303
Header file for basic type definitions.
DMatTransposer(MT &dm) noexcept
Constructor for the DMatTransposer class.
Definition: DMatTransposer.h:121
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:128
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
ConstPointer_< MT > ConstPointer
Pointer to a constant matrix value.
Definition: DMatTransposer.h:97
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DMatTransposer.h:239
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
void subAssign(const SparseMatrix< MT2,!SO > &rhs)
Implementation of the transpose subtraction assignment of a column-major sparse matrix.
Definition: DMatTransposer.h:938
ResultType_< MT > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTransposer.h:89
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: DMatTransposer.h:400
ReturnType_< MT > ReturnType
Return type for expression template evaluations.
Definition: DMatTransposer.h:92
Constraints on the storage order of matrix types.
void addAssign(const DenseMatrix< MT2, SO > &rhs)
Implementation of the transpose addition assignment of a row-major dense matrix.
Definition: DMatTransposer.h:705
Header file for the SIMD trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: DMatTransposer.h:197
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
ConstReference operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTransposer.h:147
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: DMatTransposer.h:287
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: DMatTransposer.h:452
Constraint on the data type.
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: DMatTransposer.h:469
typename T::Pointer Pointer_
Alias declaration for nested Pointer type definitions.The Pointer_ alias declaration provides a conve...
Definition: Aliases.h:283
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
void subAssign(const DenseMatrix< MT2, SO > &rhs)
Implementation of the transpose subtraction assignment of a row-major dense matrix.
Definition: DMatTransposer.h:835
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
ConstPointer data() const noexcept
Low-level data access to the matrix elements.
Definition: DMatTransposer.h:207
Reference operator()(size_t i, size_t j)
2D-access to the matrix elements.
Definition: DMatTransposer.h:133
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Reference_< MT > Reference
Reference to a non-constant matrix value.
Definition: DMatTransposer.h:94
Header file for the DenseMatrix base class.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: DMatTransposer.h:367
OppositeType_< MT > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTransposer.h:88
Expression object for the transposition of a dense matrix.The DMatTransposer class is a wrapper objec...
Definition: DMatTransposer.h:81
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: DMatTransposer.h:435
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTransposer.h:347
MT & dm_
The dense matrix operand.
Definition: DMatTransposer.h:1121
Header file for the IsAligned type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTransposer.h:357
Pointer_< MT > Pointer
Pointer to a non-constant matrix value.
Definition: DMatTransposer.h:96
Header file for the exception macros of the math module.
EnableIf_< IsNumeric< Other >, DMatTransposer > & operator/=(Other rhs)
Division assignment operator for the division of a matrix by a scalar value ( ).
Definition: DMatTransposer.h:333
void assign(const SparseMatrix< MT2,!SO > &rhs)
Implementation of the transpose assignment of a column-major sparse matrix.
Definition: DMatTransposer.h:678
void reset()
Resets the matrix elements.
Definition: DMatTransposer.h:377
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: DMatTransposer.h:504
typename T::Reference Reference_
Alias declaration for nested Reference type definitions.The Reference_ alias declaration provides a c...
Definition: Aliases.h:303
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: DMatTransposer.h:558
Header file for the EnableIf class template.
void assign(const DenseMatrix< MT2,!SO > &rhs)
Implementation of the transpose assignment of a column-major dense matrix.
Definition: DMatTransposer.h:613
Header file for the IsPadded type trait.
void assign(const DenseMatrix< MT2, SO > &rhs)
Implementation of the transpose assignment of a row-major dense matrix.
Definition: DMatTransposer.h:576
Header file for the IsNumeric type trait.
void subAssign(const SparseMatrix< MT2, SO > &rhs)
Implementation of the transpose subtraction assignment of a row-major sparse matrix.
Definition: DMatTransposer.h:911
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DMatTransposer.h:255
Header file for run time assertion macros.
void subAssign(const DenseMatrix< MT2,!SO > &rhs)
Implementation of the transpose subtraction assignment of a column-major dense matrix.
Definition: DMatTransposer.h:873
Header file for the submatrix trait.
void addAssign(const DenseMatrix< MT2,!SO > &rhs)
Implementation of the transpose addition assignment of a column-major dense matrix.
Definition: DMatTransposer.h:743
Header file for the reset shim.
EnableIf_< IsNumeric< Other >, DMatTransposer > & operator*=(Other rhs)
Multiplication assignment operator for the multiplication between a matrix and a scalar value ( )...
Definition: DMatTransposer.h:316
Constraints on the storage order of matrix types.
Header file for the HasMutableDataAccess type trait.
typename SubmatrixTrait< MT >::Type SubmatrixTrait_
Auxiliary alias declaration for the SubmatrixTrait type trait.The SubmatrixTrait_ alias declaration p...
Definition: SubmatrixTrait.h:163
void schurAssign(const DenseMatrix< MT2, SO > &rhs)
Implementation of the transpose Schur product assignment of a row-major dense matrix.
Definition: DMatTransposer.h:965
TransposeType_< MT > ResultType
Result type for expression template evaluations.
Definition: DMatTransposer.h:87
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
typename T::Iterator Iterator_
Alias declaration for nested Iterator type definitions.The Iterator_ alias declaration provides a con...
Definition: Aliases.h:183
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: DMatTransposer.h:413
typename T::ConstPointer ConstPointer_
Alias declaration for nested ConstPointer type definitions.The ConstPointer_ alias declaration provid...
Definition: Aliases.h:123
typename T::ConstReference ConstReference_
Alias declaration for nested ConstReference type definitions.The ConstReference_ alias declaration pr...
Definition: Aliases.h:143
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
void addAssign(const SparseMatrix< MT2,!SO > &rhs)
Implementation of the transpose addition assignment of a column-major sparse matrix.
Definition: DMatTransposer.h:808
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: DMatTransposer.h:162
void schurAssign(const SparseMatrix< MT2, SO > &rhs)
Implementation of the transpose Schur product assignment of a row-major sparse matrix.
Definition: DMatTransposer.h:1041
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: DMatTransposer.h:223
ConstReference_< MT > ConstReference
Reference to a constant matrix value.
Definition: DMatTransposer.h:95
ElementType_< MT > ElementType
Type of the matrix elements.
Definition: DMatTransposer.h:90
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: DMatTransposer.h:91
void assign(const SparseMatrix< MT2, SO > &rhs)
Implementation of the transpose assignment of a row-major sparse matrix.
Definition: DMatTransposer.h:651
Header file for the IntegralConstant class template.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
void schurAssign(const DenseMatrix< MT2,!SO > &rhs)
Implementation of the transpose Schur product assignment of a column-major dense matrix.
Definition: DMatTransposer.h:1003
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
ConstReference at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatTransposer.h:181
Iterator_< MT > Iterator
Iterator over non-constant elements.
Definition: DMatTransposer.h:98
ConstIterator_< MT > ConstIterator
Iterator over constant elements.
Definition: DMatTransposer.h:99
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: DMatTransposer.h:424
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DMatTransposer.h:271
bool isIntact() const noexcept
Returns whether the invariants of the matrix are intact.
Definition: DMatTransposer.h:387
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: DMatTransposer.h:486