DMatTDMatAddExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTDMATADDEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATTDMATADDEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
72 #include <blaze/system/Blocking.h>
74 #include <blaze/util/Assert.h>
75 #include <blaze/util/DisableIf.h>
76 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/mpl/And.h>
79 #include <blaze/util/mpl/If.h>
80 #include <blaze/util/mpl/Maximum.h>
81 #include <blaze/util/mpl/Not.h>
82 #include <blaze/util/mpl/Or.h>
83 #include <blaze/util/Types.h>
84 
85 
86 namespace blaze {
87 
88 //=================================================================================================
89 //
90 // CLASS DMATTDMATADDEXPR
91 //
92 //=================================================================================================
93 
94 //*************************************************************************************************
101 template< typename MT1 // Type of the left-hand side dense matrix
102  , typename MT2 > // Type of the right-hand side dense matrix
104  : public MatMatAddExpr< DenseMatrix< DMatTDMatAddExpr<MT1,MT2>, false > >
105  , private Computation
106 {
107  private:
108  //**Type definitions****************************************************************************
115  //**********************************************************************************************
116 
117  //**Return type evaluation**********************************************************************
119 
124  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
125 
128  //**********************************************************************************************
129 
130  //**Serial evaluation strategy******************************************************************
132 
138  enum : bool { useAssign = RequiresEvaluation<MT1>::value || RequiresEvaluation<MT2>::value || !returnExpr };
139 
141  template< typename MT >
143  struct UseAssign {
144  enum : bool { value = useAssign };
145  };
147  //**********************************************************************************************
148 
149  //**Parallel evaluation strategy****************************************************************
151 
157  template< typename MT >
158  struct UseSMPAssign {
159  enum : bool { value = ( !MT1::smpAssignable || !MT2::smpAssignable ) && useAssign };
160  };
162  //**********************************************************************************************
163 
164  public:
165  //**Type definitions****************************************************************************
171 
174 
176  using CompositeType = const ResultType;
177 
179  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
180 
182  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
183  //**********************************************************************************************
184 
185  //**Compilation flags***************************************************************************
187  enum : bool { simdEnabled = false };
188 
190  enum : bool { smpAssignable = MT1::smpAssignable && MT2::smpAssignable };
191  //**********************************************************************************************
192 
193  //**Constructor*********************************************************************************
199  explicit inline DMatTDMatAddExpr( const MT1& lhs, const MT2& rhs ) noexcept
200  : lhs_( lhs ) // Left-hand side dense matrix of the addition expression
201  , rhs_( rhs ) // Right-hand side dense matrix of the addition expression
202  {
203  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
204  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
205  }
206  //**********************************************************************************************
207 
208  //**Access operator*****************************************************************************
215  inline ReturnType operator()( size_t i, size_t j ) const {
216  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
217  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
218  return lhs_(i,j) + rhs_(i,j);
219  }
220  //**********************************************************************************************
221 
222  //**At function*********************************************************************************
230  inline ReturnType at( size_t i, size_t j ) const {
231  if( i >= lhs_.rows() ) {
232  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
233  }
234  if( j >= lhs_.columns() ) {
235  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
236  }
237  return (*this)(i,j);
238  }
239  //**********************************************************************************************
240 
241  //**Rows function*******************************************************************************
246  inline size_t rows() const noexcept {
247  return lhs_.rows();
248  }
249  //**********************************************************************************************
250 
251  //**Columns function****************************************************************************
256  inline size_t columns() const noexcept {
257  return lhs_.columns();
258  }
259  //**********************************************************************************************
260 
261  //**Left operand access*************************************************************************
266  inline LeftOperand leftOperand() const noexcept {
267  return lhs_;
268  }
269  //**********************************************************************************************
270 
271  //**Right operand access************************************************************************
276  inline RightOperand rightOperand() const noexcept {
277  return rhs_;
278  }
279  //**********************************************************************************************
280 
281  //**********************************************************************************************
287  template< typename T >
288  inline bool canAlias( const T* alias ) const noexcept {
289  return ( IsExpression<MT1>::value && ( RequiresEvaluation<MT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
290  ( IsExpression<MT2>::value && ( RequiresEvaluation<MT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
291  }
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
300  template< typename T >
301  inline bool isAliased( const T* alias ) const noexcept {
302  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
303  }
304  //**********************************************************************************************
305 
306  //**********************************************************************************************
311  inline bool isAligned() const noexcept {
312  return lhs_.isAligned() && rhs_.isAligned();
313  }
314  //**********************************************************************************************
315 
316  //**********************************************************************************************
321  inline bool canSMPAssign() const noexcept {
322  return lhs_.canSMPAssign() || rhs_.canSMPAssign() ||
323  ( rows() * columns() >= SMP_DMATTDMATADD_THRESHOLD );
324  }
325  //**********************************************************************************************
326 
327  private:
328  //**Member variables****************************************************************************
331  //**********************************************************************************************
332 
333  //**Assignment to dense matrices****************************************************************
347  template< typename MT // Type of the target dense matrix
348  , bool SO > // Storage order of the target dense matrix
349  friend inline DisableIf_< UseAssign<MT> >
350  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
351  {
353 
354  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
356 
357  constexpr size_t block( BLOCK_SIZE );
358 
359  const size_t m( rhs.rows() );
360  const size_t n( rhs.columns() );
361 
362  for( size_t ii=0UL; ii<m; ii+=block ) {
363  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
364  for( size_t jj=0UL; jj<n; jj+=block ) {
365  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
366  for( size_t i=ii; i<iend; ++i ) {
367  for( size_t j=jj; j<jend; ++j ) {
368  (~lhs)(i,j) = rhs.lhs_(i,j) + rhs.rhs_(i,j);
369  }
370  }
371  }
372  }
373  }
375  //**********************************************************************************************
376 
377  //**Assignment to dense matrices****************************************************************
391  template< typename MT // Type of the target dense matrix
392  , bool SO > // Storage order of the target dense matrix
393  friend inline EnableIf_< UseAssign<MT> >
394  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
395  {
397 
398  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
399  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
400 
401  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
402  addAssign( ~lhs, rhs.rhs_ );
403  }
404  else if( !IsOperation<MT2>::value && isSame( ~lhs, rhs.rhs_ ) ) {
405  addAssign( ~lhs, rhs.lhs_ );
406  }
407  else {
408  assign ( ~lhs, rhs.lhs_ );
409  addAssign( ~lhs, rhs.rhs_ );
410  }
411  }
413  //**********************************************************************************************
414 
415  //**Assignment to sparse matrices***************************************************************
427  template< typename MT // Type of the target sparse matrix
428  , bool SO > // Storage order of the target sparse matrix
429  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
430  {
432 
434 
441 
442  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
443  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
444 
445  const TmpType tmp( serial( rhs ) );
446  assign( ~lhs, tmp );
447  }
449  //**********************************************************************************************
450 
451  //**Addition assignment to dense matrices*******************************************************
465  template< typename MT // Type of the target dense matrix
466  , bool SO > // Storage order of the target dense matrix
467  friend inline DisableIf_< UseAssign<MT> >
468  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
469  {
471 
472  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
473  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
474 
475  constexpr size_t block( BLOCK_SIZE );
476 
477  const size_t m( rhs.rows() );
478  const size_t n( rhs.columns() );
479 
480  for( size_t ii=0UL; ii<m; ii+=block ) {
481  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
482  for( size_t jj=0UL; jj<n; jj+=block ) {
483  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
484  for( size_t i=ii; i<iend; ++i ) {
485  for( size_t j=jj; j<jend; ++j ) {
486  (~lhs)(i,j) += rhs.lhs_(i,j) + rhs.rhs_(i,j);
487  }
488  }
489  }
490  }
491  }
493  //**********************************************************************************************
494 
495  //**Addition assignment to dense matrices*******************************************************
509  template< typename MT // Type of the target dense matrix
510  , bool SO > // Storage order of the target dense matrix
511  friend inline EnableIf_< UseAssign<MT> >
512  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
513  {
515 
516  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
517  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
518 
519  addAssign( ~lhs, rhs.lhs_ );
520  addAssign( ~lhs, rhs.rhs_ );
521  }
523  //**********************************************************************************************
524 
525  //**Addition assignment to sparse matrices******************************************************
526  // No special implementation for the addition assignment to sparse matrices.
527  //**********************************************************************************************
528 
529  //**Subtraction assignment to dense matrices****************************************************
543  template< typename MT // Type of the target dense matrix
544  , bool SO > // Storage order of the target dense matrix
545  friend inline DisableIf_< UseAssign<MT> >
546  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
547  {
549 
550  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
551  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
552 
553  constexpr size_t block( BLOCK_SIZE );
554 
555  const size_t m( rhs.rows() );
556  const size_t n( rhs.columns() );
557 
558  for( size_t ii=0UL; ii<m; ii+=block ) {
559  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
560  for( size_t jj=0UL; jj<n; jj+=block ) {
561  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
562  for( size_t i=ii; i<iend; ++i ) {
563  for( size_t j=jj; j<jend; ++j ) {
564  (~lhs)(i,j) -= rhs.lhs_(i,j) + rhs.rhs_(i,j);
565  }
566  }
567  }
568  }
569  }
571  //**********************************************************************************************
572 
573  //**Subtraction assignment to dense matrices****************************************************
587  template< typename MT // Type of the target dense matrix
588  , bool SO > // Storage order of the target dense matrix
589  friend inline EnableIf_< UseAssign<MT> >
590  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
591  {
593 
594  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
595  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
596 
597  subAssign( ~lhs, rhs.lhs_ );
598  subAssign( ~lhs, rhs.rhs_ );
599  }
601  //**********************************************************************************************
602 
603  //**Subtraction assignment to sparse matrices***************************************************
604  // No special implementation for the subtraction assignment to sparse matrices.
605  //**********************************************************************************************
606 
607  //**Schur product assignment to dense matrices**************************************************
622  template< typename MT // Type of the target dense matrix
623  , bool SO > // Storage order of the target dense matrix
624  friend inline DisableIf_< UseAssign<MT> >
625  schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
626  {
628 
632 
633  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
634  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
635 
636  const ResultType tmp( serial( rhs ) );
637  schurAssign( ~lhs, tmp );
638  }
640  //**********************************************************************************************
641 
642  //**Schur product assignment to sparse matrices*************************************************
643  // No special implementation for the Schur product assignment to sparse matrices.
644  //**********************************************************************************************
645 
646  //**Multiplication assignment to dense matrices*************************************************
647  // No special implementation for the multiplication assignment to dense matrices.
648  //**********************************************************************************************
649 
650  //**Multiplication assignment to sparse matrices************************************************
651  // No special implementation for the multiplication assignment to sparse matrices.
652  //**********************************************************************************************
653 
654  //**SMP assignment to dense matrices************************************************************
668  template< typename MT // Type of the target dense matrix
669  , bool SO > // Storage order of the target dense matrix
670  friend inline EnableIf_< UseSMPAssign<MT> >
671  smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
672  {
674 
675  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
676  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
677 
678  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
679  smpAddAssign( ~lhs, rhs.rhs_ );
680  }
681  else if( !IsOperation<MT2>::value && isSame( ~lhs, rhs.rhs_ ) ) {
682  smpAddAssign( ~lhs, rhs.lhs_ );
683  }
684  else {
685  smpAssign ( ~lhs, rhs.lhs_ );
686  smpAddAssign( ~lhs, rhs.rhs_ );
687  }
688  }
690  //**********************************************************************************************
691 
692  //**SMP assignment to sparse matrices***********************************************************
706  template< typename MT // Type of the target sparse matrix
707  , bool SO > // Storage order of the target sparse matrix
708  friend inline EnableIf_< UseSMPAssign<MT> >
710  {
712 
714 
721 
722  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
723  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
724 
725  const TmpType tmp( rhs );
726  smpAssign( ~lhs, tmp );
727  }
729  //**********************************************************************************************
730 
731  //**SMP addition assignment to dense matrices***************************************************
746  template< typename MT // Type of the target dense matrix
747  , bool SO > // Storage order of the target dense matrix
748  friend inline EnableIf_< UseSMPAssign<MT> >
750  {
752 
753  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
754  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
755 
756  smpAddAssign( ~lhs, rhs.lhs_ );
757  smpAddAssign( ~lhs, rhs.rhs_ );
758  }
760  //**********************************************************************************************
761 
762  //**SMP addition assignment to sparse matrices**************************************************
763  // No special implementation for the SMP addition assignment to sparse matrices.
764  //**********************************************************************************************
765 
766  //**SMP subtraction assignment to dense matrices************************************************
781  template< typename MT // Type of the target dense matrix
782  , bool SO > // Storage order of the target dense matrix
783  friend inline EnableIf_< UseSMPAssign<MT> >
785  {
787 
788  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
789  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
790 
791  smpSubAssign( ~lhs, rhs.lhs_ );
792  smpSubAssign( ~lhs, rhs.rhs_ );
793  }
795  //**********************************************************************************************
796 
797  //**SMP subtraction assignment to sparse matrices***********************************************
798  // No special implementation for the SMP subtraction assignment to sparse matrices.
799  //**********************************************************************************************
800 
801  //**SMP Schur product assignment to dense matrices**********************************************
816  template< typename MT // Type of the target dense matrix
817  , bool SO > // Storage order of the target dense matrix
818  friend inline EnableIf_< UseSMPAssign<MT> >
820  {
822 
826 
827  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
828  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
829 
830  const ResultType tmp( rhs );
831  smpSchurAssign( ~lhs, tmp );
832  }
834  //**********************************************************************************************
835 
836  //**SMP Schur product assignment to sparse matrices*********************************************
837  // No special implementation for the SMP Schur product assignment to sparse matrices.
838  //**********************************************************************************************
839 
840  //**SMP multiplication assignment to dense matrices*********************************************
841  // No special implementation for the SMP multiplication assignment to dense matrices.
842  //**********************************************************************************************
843 
844  //**SMP multiplication assignment to sparse matrices********************************************
845  // No special implementation for the SMP multiplication assignment to sparse matrices.
846  //**********************************************************************************************
847 
848  //**Compile time checks*************************************************************************
856  //**********************************************************************************************
857 };
858 //*************************************************************************************************
859 
860 
861 
862 
863 //=================================================================================================
864 //
865 // GLOBAL BINARY ARITHMETIC OPERATORS
866 //
867 //=================================================================================================
868 
869 //*************************************************************************************************
882 template< typename MT1 // Type of the left-hand side dense matrix
883  , typename MT2 > // Type of the right-hand side dense matrix
884 inline const DMatTDMatAddExpr<MT1,MT2>
885  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
886  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
887 {
889 
890  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
891  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
892 
893  return DMatTDMatAddExpr<MT1,MT2>( ~lhs, ~rhs );
894 }
896 //*************************************************************************************************
897 
898 
899 //*************************************************************************************************
912 template< typename MT1 // Type of the left-hand side dense matrix
913  , typename MT2 > // Type of the right-hand side dense matrix
914 inline decltype(auto)
915  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
916  EnableIf_< And< IsSymmetric<MT1>, Not< IsSymmetric<MT2> > > >* = nullptr )
917 {
919 
920  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
921  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
922 
923  return trans( ~lhs ) + ~rhs;
924 }
926 //*************************************************************************************************
927 
928 
929 //*************************************************************************************************
942 template< typename MT1 // Type of the left-hand side dense matrix
943  , typename MT2 > // Type of the right-hand side dense matrix
944 inline decltype(auto)
945  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
946  EnableIf_< IsSymmetric<MT2> >* = nullptr )
947 {
949 
950  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
951  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
952 
953  return (~lhs) + trans( ~rhs );
954 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
988 template< typename MT1 // Type of the left-hand side dense matrix
989  , typename MT2 > // Type of the right-hand side dense matrix
990 inline decltype(auto)
991  operator+( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
992 {
994 
995  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
996  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
997  }
998 
999  return dmattdmatadd( ~lhs, ~rhs );
1000 }
1001 //*************************************************************************************************
1002 
1003 
1004 //*************************************************************************************************
1017 template< typename MT1 // Type of the left-hand side dense matrix
1018  , typename MT2 > // Type of the right-hand side dense matrix
1019 inline const DMatTDMatAddExpr<MT2,MT1>
1020  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1021  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
1022 {
1024 
1025  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1026  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1027 
1028  return DMatTDMatAddExpr<MT2,MT1>( ~rhs, ~lhs );
1029 }
1031 //*************************************************************************************************
1032 
1033 
1034 //*************************************************************************************************
1047 template< typename MT1 // Type of the left-hand side dense matrix
1048  , typename MT2 > // Type of the right-hand side dense matrix
1049 inline decltype(auto)
1050  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1051  EnableIf_< And< Not< IsSymmetric<MT1> >, IsSymmetric<MT2> > >* = nullptr )
1052 {
1054 
1055  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1056  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1057 
1058  return trans( ~rhs ) + (~lhs);
1059 }
1061 //*************************************************************************************************
1062 
1063 
1064 //*************************************************************************************************
1077 template< typename MT1 // Type of the left-hand side dense matrix
1078  , typename MT2 > // Type of the right-hand side dense matrix >
1079 inline decltype(auto)
1080  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1081  EnableIf_< IsSymmetric<MT1> >* = nullptr )
1082 {
1084 
1085  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1086  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1087 
1088  return (~rhs) + trans( ~lhs );
1089 }
1091 //*************************************************************************************************
1092 
1093 
1094 //*************************************************************************************************
1123 template< typename MT1 // Type of the left-hand side dense matrix
1124  , typename MT2 > // Type of the right-hand side dense matrix
1125 inline decltype(auto)
1126  operator+( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1127 {
1129 
1130  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1131  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1132  }
1133 
1134  return tdmatdmatadd( ~lhs, ~rhs );
1135 }
1136 //*************************************************************************************************
1137 
1138 
1139 
1140 
1141 //=================================================================================================
1142 //
1143 // SIZE SPECIALIZATIONS
1144 //
1145 //=================================================================================================
1146 
1147 //*************************************************************************************************
1149 template< typename MT1, typename MT2 >
1150 struct Size< DMatTDMatAddExpr<MT1,MT2>, 0UL >
1151  : public Maximum< Size<MT1,0UL>, Size<MT2,0UL> >
1152 {};
1153 
1154 template< typename MT1, typename MT2 >
1155 struct Size< DMatTDMatAddExpr<MT1,MT2>, 1UL >
1156  : public Maximum< Size<MT1,1UL>, Size<MT2,1UL> >
1157 {};
1159 //*************************************************************************************************
1160 
1161 
1162 
1163 
1164 //=================================================================================================
1165 //
1166 // ISALIGNED SPECIALIZATIONS
1167 //
1168 //=================================================================================================
1169 
1170 //*************************************************************************************************
1172 template< typename MT1, typename MT2 >
1173 struct IsAligned< DMatTDMatAddExpr<MT1,MT2> >
1174  : public And< IsAligned<MT1>, IsAligned<MT2> >
1175 {};
1177 //*************************************************************************************************
1178 
1179 
1180 
1181 
1182 //=================================================================================================
1183 //
1184 // ISSYMMETRIC SPECIALIZATIONS
1185 //
1186 //=================================================================================================
1187 
1188 //*************************************************************************************************
1190 template< typename MT1, typename MT2 >
1191 struct IsSymmetric< DMatTDMatAddExpr<MT1,MT2> >
1192  : public And< IsSymmetric<MT1>, IsSymmetric<MT2> >
1193 {};
1195 //*************************************************************************************************
1196 
1197 
1198 
1199 
1200 //=================================================================================================
1201 //
1202 // ISHERMITIAN SPECIALIZATIONS
1203 //
1204 //=================================================================================================
1205 
1206 //*************************************************************************************************
1208 template< typename MT1, typename MT2 >
1209 struct IsHermitian< DMatTDMatAddExpr<MT1,MT2> >
1210  : public And< IsHermitian<MT1>, IsHermitian<MT2> >
1211 {};
1213 //*************************************************************************************************
1214 
1215 
1216 
1217 
1218 //=================================================================================================
1219 //
1220 // ISLOWER SPECIALIZATIONS
1221 //
1222 //=================================================================================================
1223 
1224 //*************************************************************************************************
1226 template< typename MT1, typename MT2 >
1227 struct IsLower< DMatTDMatAddExpr<MT1,MT2> >
1228  : public And< IsLower<MT1>, IsLower<MT2> >
1229 {};
1231 //*************************************************************************************************
1232 
1233 
1234 
1235 
1236 //=================================================================================================
1237 //
1238 // ISUNILOWER SPECIALIZATIONS
1239 //
1240 //=================================================================================================
1241 
1242 //*************************************************************************************************
1244 template< typename MT1, typename MT2 >
1245 struct IsUniLower< DMatTDMatAddExpr<MT1,MT2> >
1246  : public Or< And< IsUniLower<MT1>, IsStrictlyLower<MT2> >
1247  , And< IsUniLower<MT2>, IsStrictlyLower<MT1> > >
1248 {};
1250 //*************************************************************************************************
1251 
1252 
1253 
1254 
1255 //=================================================================================================
1256 //
1257 // ISSTRICTLYLOWER SPECIALIZATIONS
1258 //
1259 //=================================================================================================
1260 
1261 //*************************************************************************************************
1263 template< typename MT1, typename MT2 >
1264 struct IsStrictlyLower< DMatTDMatAddExpr<MT1,MT2> >
1265  : public And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >
1266 {};
1268 //*************************************************************************************************
1269 
1270 
1271 
1272 
1273 //=================================================================================================
1274 //
1275 // ISUPPER SPECIALIZATIONS
1276 //
1277 //=================================================================================================
1278 
1279 //*************************************************************************************************
1281 template< typename MT1, typename MT2 >
1282 struct IsUpper< DMatTDMatAddExpr<MT1,MT2> >
1283  : public And< IsUpper<MT1>, IsUpper<MT2> >
1284 {};
1286 //*************************************************************************************************
1287 
1288 
1289 
1290 
1291 //=================================================================================================
1292 //
1293 // ISUNIUPPER SPECIALIZATIONS
1294 //
1295 //=================================================================================================
1296 
1297 //*************************************************************************************************
1299 template< typename MT1, typename MT2 >
1300 struct IsUniUpper< DMatTDMatAddExpr<MT1,MT2> >
1301  : public Or< And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >
1302  , And< IsUniUpper<MT2>, IsStrictlyUpper<MT1> > >
1303 {};
1305 //*************************************************************************************************
1306 
1307 
1308 
1309 
1310 //=================================================================================================
1311 //
1312 // ISSTRICTLYUPPER SPECIALIZATIONS
1313 //
1314 //=================================================================================================
1315 
1316 //*************************************************************************************************
1318 template< typename MT1, typename MT2 >
1319 struct IsStrictlyUpper< DMatTDMatAddExpr<MT1,MT2> >
1320  : public And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >
1321 {};
1323 //*************************************************************************************************
1324 
1325 } // namespace blaze
1326 
1327 #endif
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTDMatAddExpr.h:256
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:179
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Header file for kernel specific block sizes.
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
DMatTDMatAddExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTDMatAddExpr class.
Definition: DMatTDMatAddExpr.h:199
Header file for the IsUniUpper type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:949
Header file for basic type definitions.
Compile time check whether the given type is an operational expression template.This type trait class...
Definition: IsOperation.h:70
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
#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
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: DMatTDMatAddExpr.h:276
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatTDMatAddExpr.h:230
Header file for the And class template.
Compile time value evaluation.The Maximum alias declaration selects the larger of the two given templ...
Definition: Maximum.h:73
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
Header file for the AddExprTrait class template.
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:173
Header file for the Computation base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatAddExpr.h:321
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
CompositeType_< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:114
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatAddExpr.h:170
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
CompositeType_< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:113
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
Constraint on the data type.
Header file for the Maximum class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:71
ReturnType_< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:112
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTDMatAddExpr.h:266
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
typename AddExprTrait< T1, T2 >::Type AddExprTrait_
Auxiliary alias declaration for the AddExprTrait class template.The AddExprTrait_ alias declaration p...
Definition: AddExprTrait.h:112
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#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
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatTDMatAddExpr.h:301
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Header file for the Or class template.
#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
Header file for the DenseMatrix base class.
Header file for the Not class template.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
AddTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:167
Base class for all matrix/matrix addition expression templates.The MatMatAddExpr class serves as a ta...
Definition: MatMatAddExpr.h:66
Header file for the IsOperation type trait class.
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
Constraints on the storage order of matrix types.
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTDMatAddExpr.h:215
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTDMatAddExpr.h:288
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATADDEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatAddExpr.h:107
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTDMatAddExpr.h:168
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTDMatAddExpr.h:176
ResultType_< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:109
#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
LeftOperand lhs_
Left-hand side dense matrix of the addition expression.
Definition: DMatTDMatAddExpr.h:329
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:182
Header file for run time assertion macros.
Header file for the addition trait.
RightOperand rhs_
Right-hand side dense matrix of the addition expression.
Definition: DMatTDMatAddExpr.h:330
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
Constraint on the data type.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Compile time type negation.The Not alias declaration negates the given compile time condition...
Definition: Not.h:70
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the MatMatAddExpr base class.
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
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTDMatAddExpr.h:246
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
ResultType_< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:110
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
Compile time logical &#39;or&#39; evaluation.The Or alias declaration performs at compile time a logical &#39;or&#39;...
Definition: Or.h:76
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTDMatAddExpr.h:311
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:169
Compile time logical &#39;and&#39; evaluation.The And alias declaration performs at compile time a logical &#39;a...
Definition: And.h:76
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
Header file for the IsUpper type trait.
ReturnType_< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:111
AddExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DMatTDMatAddExpr.h:127
Header file for the IsHermitian type trait.
Header file for the Size type trait.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
typename AddTrait< T1, T2 >::Type AddTrait_
Auxiliary alias declaration for the AddTrait class template.The AddTrait_ alias declaration provides ...
Definition: AddTrait.h:291
#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
Compile time check whether the given type is an expression template.This type trait class tests wheth...
Definition: IsExpression.h:95
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
Expression object for dense matrix-transpose dense matrix additions.The DMatTDMatAddExpr class repres...
Definition: DMatTDMatAddExpr.h:103