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>
73 #include <blaze/system/Blocking.h>
75 #include <blaze/util/Assert.h>
76 #include <blaze/util/DisableIf.h>
77 #include <blaze/util/EnableIf.h>
80 #include <blaze/util/mpl/And.h>
81 #include <blaze/util/mpl/If.h>
82 #include <blaze/util/mpl/Maximum.h>
83 #include <blaze/util/mpl/Not.h>
84 #include <blaze/util/mpl/Or.h>
85 #include <blaze/util/Types.h>
86 
87 
88 namespace blaze {
89 
90 //=================================================================================================
91 //
92 // CLASS DMATTDMATADDEXPR
93 //
94 //=================================================================================================
95 
96 //*************************************************************************************************
103 template< typename MT1 // Type of the left-hand side dense matrix
104  , typename MT2 > // Type of the right-hand side dense matrix
106  : public MatMatAddExpr< DenseMatrix< DMatTDMatAddExpr<MT1,MT2>, false > >
107  , private Computation
108 {
109  private:
110  //**Type definitions****************************************************************************
117  //**********************************************************************************************
118 
119  //**Return type evaluation**********************************************************************
121 
126  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
127 
130  //**********************************************************************************************
131 
132  //**Serial evaluation strategy******************************************************************
134 
140  enum : bool { useAssign = RequiresEvaluation<MT1>::value || RequiresEvaluation<MT2>::value || !returnExpr };
141 
143  template< typename MT >
145  struct UseAssign {
146  enum : bool { value = useAssign };
147  };
149  //**********************************************************************************************
150 
151  //**Parallel evaluation strategy****************************************************************
153 
159  template< typename MT >
160  struct UseSMPAssign {
161  enum : bool { value = ( !MT1::smpAssignable || !MT2::smpAssignable ) && useAssign };
162  };
164  //**********************************************************************************************
165 
166  public:
167  //**Type definitions****************************************************************************
173 
176 
178  using CompositeType = const ResultType;
179 
181  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
182 
184  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
185  //**********************************************************************************************
186 
187  //**Compilation flags***************************************************************************
189  enum : bool { simdEnabled = false };
190 
192  enum : bool { smpAssignable = MT1::smpAssignable && MT2::smpAssignable };
193  //**********************************************************************************************
194 
195  //**Constructor*********************************************************************************
201  explicit inline DMatTDMatAddExpr( const MT1& lhs, const MT2& rhs ) noexcept
202  : lhs_( lhs ) // Left-hand side dense matrix of the addition expression
203  , rhs_( rhs ) // Right-hand side dense matrix of the addition expression
204  {
205  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
206  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
207  }
208  //**********************************************************************************************
209 
210  //**Access operator*****************************************************************************
217  inline ReturnType operator()( size_t i, size_t j ) const {
218  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
219  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
220  return lhs_(i,j) + rhs_(i,j);
221  }
222  //**********************************************************************************************
223 
224  //**At function*********************************************************************************
232  inline ReturnType at( size_t i, size_t j ) const {
233  if( i >= lhs_.rows() ) {
234  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
235  }
236  if( j >= lhs_.columns() ) {
237  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
238  }
239  return (*this)(i,j);
240  }
241  //**********************************************************************************************
242 
243  //**Rows function*******************************************************************************
248  inline size_t rows() const noexcept {
249  return lhs_.rows();
250  }
251  //**********************************************************************************************
252 
253  //**Columns function****************************************************************************
258  inline size_t columns() const noexcept {
259  return lhs_.columns();
260  }
261  //**********************************************************************************************
262 
263  //**Left operand access*************************************************************************
268  inline LeftOperand leftOperand() const noexcept {
269  return lhs_;
270  }
271  //**********************************************************************************************
272 
273  //**Right operand access************************************************************************
278  inline RightOperand rightOperand() const noexcept {
279  return rhs_;
280  }
281  //**********************************************************************************************
282 
283  //**********************************************************************************************
289  template< typename T >
290  inline bool canAlias( const T* alias ) const noexcept {
291  return ( IsExpression<MT1>::value && ( RequiresEvaluation<MT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
292  ( IsExpression<MT2>::value && ( RequiresEvaluation<MT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
293  }
294  //**********************************************************************************************
295 
296  //**********************************************************************************************
302  template< typename T >
303  inline bool isAliased( const T* alias ) const noexcept {
304  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
305  }
306  //**********************************************************************************************
307 
308  //**********************************************************************************************
313  inline bool isAligned() const noexcept {
314  return lhs_.isAligned() && rhs_.isAligned();
315  }
316  //**********************************************************************************************
317 
318  //**********************************************************************************************
323  inline bool canSMPAssign() const noexcept {
324  return lhs_.canSMPAssign() || rhs_.canSMPAssign() ||
325  ( rows() * columns() >= SMP_DMATTDMATADD_THRESHOLD );
326  }
327  //**********************************************************************************************
328 
329  private:
330  //**Member variables****************************************************************************
333  //**********************************************************************************************
334 
335  //**Assignment to dense matrices****************************************************************
349  template< typename MT // Type of the target dense matrix
350  , bool SO > // Storage order of the target dense matrix
351  friend inline DisableIf_< UseAssign<MT> >
352  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
353  {
355 
356  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
358 
359  constexpr size_t block( BLOCK_SIZE );
360 
361  const size_t m( rhs.rows() );
362  const size_t n( rhs.columns() );
363 
364  for( size_t ii=0UL; ii<m; ii+=block ) {
365  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
366  for( size_t jj=0UL; jj<n; jj+=block ) {
367  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
368  for( size_t i=ii; i<iend; ++i ) {
369  for( size_t j=jj; j<jend; ++j ) {
370  (~lhs)(i,j) = rhs.lhs_(i,j) + rhs.rhs_(i,j);
371  }
372  }
373  }
374  }
375  }
377  //**********************************************************************************************
378 
379  //**Assignment to dense matrices****************************************************************
393  template< typename MT // Type of the target dense matrix
394  , bool SO > // Storage order of the target dense matrix
395  friend inline EnableIf_< UseAssign<MT> >
396  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
397  {
399 
400  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
401  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
402 
403  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
404  addAssign( ~lhs, rhs.rhs_ );
405  }
406  else if( !IsOperation<MT2>::value && isSame( ~lhs, rhs.rhs_ ) ) {
407  addAssign( ~lhs, rhs.lhs_ );
408  }
409  else {
410  assign ( ~lhs, rhs.lhs_ );
411  addAssign( ~lhs, rhs.rhs_ );
412  }
413  }
415  //**********************************************************************************************
416 
417  //**Assignment to sparse matrices***************************************************************
429  template< typename MT // Type of the target sparse matrix
430  , bool SO > // Storage order of the target sparse matrix
431  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
432  {
434 
436 
443 
444  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
445  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
446 
447  const TmpType tmp( serial( rhs ) );
448  assign( ~lhs, tmp );
449  }
451  //**********************************************************************************************
452 
453  //**Addition assignment to dense matrices*******************************************************
467  template< typename MT // Type of the target dense matrix
468  , bool SO > // Storage order of the target dense matrix
469  friend inline DisableIf_< UseAssign<MT> >
470  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
471  {
473 
474  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
475  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
476 
477  constexpr size_t block( BLOCK_SIZE );
478 
479  const size_t m( rhs.rows() );
480  const size_t n( rhs.columns() );
481 
482  for( size_t ii=0UL; ii<m; ii+=block ) {
483  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
484  for( size_t jj=0UL; jj<n; jj+=block ) {
485  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
486  for( size_t i=ii; i<iend; ++i ) {
487  for( size_t j=jj; j<jend; ++j ) {
488  (~lhs)(i,j) += rhs.lhs_(i,j) + rhs.rhs_(i,j);
489  }
490  }
491  }
492  }
493  }
495  //**********************************************************************************************
496 
497  //**Addition assignment to dense matrices*******************************************************
511  template< typename MT // Type of the target dense matrix
512  , bool SO > // Storage order of the target dense matrix
513  friend inline EnableIf_< UseAssign<MT> >
514  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
515  {
517 
518  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
519  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
520 
521  addAssign( ~lhs, rhs.lhs_ );
522  addAssign( ~lhs, rhs.rhs_ );
523  }
525  //**********************************************************************************************
526 
527  //**Addition assignment to sparse matrices******************************************************
528  // No special implementation for the addition assignment to sparse matrices.
529  //**********************************************************************************************
530 
531  //**Subtraction assignment to dense matrices****************************************************
545  template< typename MT // Type of the target dense matrix
546  , bool SO > // Storage order of the target dense matrix
547  friend inline DisableIf_< UseAssign<MT> >
548  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
549  {
551 
552  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
553  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
554 
555  constexpr size_t block( BLOCK_SIZE );
556 
557  const size_t m( rhs.rows() );
558  const size_t n( rhs.columns() );
559 
560  for( size_t ii=0UL; ii<m; ii+=block ) {
561  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
562  for( size_t jj=0UL; jj<n; jj+=block ) {
563  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
564  for( size_t i=ii; i<iend; ++i ) {
565  for( size_t j=jj; j<jend; ++j ) {
566  (~lhs)(i,j) -= rhs.lhs_(i,j) + rhs.rhs_(i,j);
567  }
568  }
569  }
570  }
571  }
573  //**********************************************************************************************
574 
575  //**Subtraction assignment to dense matrices****************************************************
589  template< typename MT // Type of the target dense matrix
590  , bool SO > // Storage order of the target dense matrix
591  friend inline EnableIf_< UseAssign<MT> >
592  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
593  {
595 
596  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
597  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
598 
599  subAssign( ~lhs, rhs.lhs_ );
600  subAssign( ~lhs, rhs.rhs_ );
601  }
603  //**********************************************************************************************
604 
605  //**Subtraction assignment to sparse matrices***************************************************
606  // No special implementation for the subtraction assignment to sparse matrices.
607  //**********************************************************************************************
608 
609  //**Schur product assignment to dense matrices**************************************************
624  template< typename MT // Type of the target dense matrix
625  , bool SO > // Storage order of the target dense matrix
626  friend inline DisableIf_< UseAssign<MT> >
627  schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
628  {
630 
634 
635  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
636  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
637 
638  const ResultType tmp( serial( rhs ) );
639  schurAssign( ~lhs, tmp );
640  }
642  //**********************************************************************************************
643 
644  //**Schur product assignment to sparse matrices*************************************************
645  // No special implementation for the Schur product assignment to sparse matrices.
646  //**********************************************************************************************
647 
648  //**Multiplication assignment to dense matrices*************************************************
649  // No special implementation for the multiplication assignment to dense matrices.
650  //**********************************************************************************************
651 
652  //**Multiplication assignment to sparse matrices************************************************
653  // No special implementation for the multiplication assignment to sparse matrices.
654  //**********************************************************************************************
655 
656  //**SMP assignment to dense matrices************************************************************
670  template< typename MT // Type of the target dense matrix
671  , bool SO > // Storage order of the target dense matrix
672  friend inline EnableIf_< UseSMPAssign<MT> >
673  smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
674  {
676 
677  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
678  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
679 
680  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
681  smpAddAssign( ~lhs, rhs.rhs_ );
682  }
683  else if( !IsOperation<MT2>::value && isSame( ~lhs, rhs.rhs_ ) ) {
684  smpAddAssign( ~lhs, rhs.lhs_ );
685  }
686  else {
687  smpAssign ( ~lhs, rhs.lhs_ );
688  smpAddAssign( ~lhs, rhs.rhs_ );
689  }
690  }
692  //**********************************************************************************************
693 
694  //**SMP assignment to sparse matrices***********************************************************
708  template< typename MT // Type of the target sparse matrix
709  , bool SO > // Storage order of the target sparse matrix
710  friend inline EnableIf_< UseSMPAssign<MT> >
712  {
714 
716 
723 
724  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
725  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
726 
727  const TmpType tmp( rhs );
728  smpAssign( ~lhs, tmp );
729  }
731  //**********************************************************************************************
732 
733  //**SMP addition assignment to dense matrices***************************************************
748  template< typename MT // Type of the target dense matrix
749  , bool SO > // Storage order of the target dense matrix
750  friend inline EnableIf_< UseSMPAssign<MT> >
752  {
754 
755  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
756  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
757 
758  smpAddAssign( ~lhs, rhs.lhs_ );
759  smpAddAssign( ~lhs, rhs.rhs_ );
760  }
762  //**********************************************************************************************
763 
764  //**SMP addition assignment to sparse matrices**************************************************
765  // No special implementation for the SMP addition assignment to sparse matrices.
766  //**********************************************************************************************
767 
768  //**SMP subtraction assignment to dense matrices************************************************
783  template< typename MT // Type of the target dense matrix
784  , bool SO > // Storage order of the target dense matrix
785  friend inline EnableIf_< UseSMPAssign<MT> >
787  {
789 
790  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
791  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
792 
793  smpSubAssign( ~lhs, rhs.lhs_ );
794  smpSubAssign( ~lhs, rhs.rhs_ );
795  }
797  //**********************************************************************************************
798 
799  //**SMP subtraction assignment to sparse matrices***********************************************
800  // No special implementation for the SMP subtraction assignment to sparse matrices.
801  //**********************************************************************************************
802 
803  //**SMP Schur product assignment to dense matrices**********************************************
818  template< typename MT // Type of the target dense matrix
819  , bool SO > // Storage order of the target dense matrix
820  friend inline EnableIf_< UseSMPAssign<MT> >
822  {
824 
828 
829  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
830  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
831 
832  const ResultType tmp( rhs );
833  smpSchurAssign( ~lhs, tmp );
834  }
836  //**********************************************************************************************
837 
838  //**SMP Schur product assignment to sparse matrices*********************************************
839  // No special implementation for the SMP Schur product assignment to sparse matrices.
840  //**********************************************************************************************
841 
842  //**SMP multiplication assignment to dense matrices*********************************************
843  // No special implementation for the SMP multiplication assignment to dense matrices.
844  //**********************************************************************************************
845 
846  //**SMP multiplication assignment to sparse matrices********************************************
847  // No special implementation for the SMP multiplication assignment to sparse matrices.
848  //**********************************************************************************************
849 
850  //**Compile time checks*************************************************************************
858  //**********************************************************************************************
859 };
860 //*************************************************************************************************
861 
862 
863 
864 
865 //=================================================================================================
866 //
867 // GLOBAL BINARY ARITHMETIC OPERATORS
868 //
869 //=================================================================================================
870 
871 //*************************************************************************************************
884 template< typename MT1 // Type of the left-hand side dense matrix
885  , typename MT2 > // Type of the right-hand side dense matrix
886 inline const DMatTDMatAddExpr<MT1,MT2>
887  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
888  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
889 {
891 
892  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
893  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
894 
895  return DMatTDMatAddExpr<MT1,MT2>( ~lhs, ~rhs );
896 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
914 template< typename MT1 // Type of the left-hand side dense matrix
915  , typename MT2 > // Type of the right-hand side dense matrix
916 inline decltype(auto)
917  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
918  EnableIf_< And< IsSymmetric<MT1>, Not< IsSymmetric<MT2> > > >* = nullptr )
919 {
921 
922  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
923  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
924 
925  return trans( ~lhs ) + ~rhs;
926 }
928 //*************************************************************************************************
929 
930 
931 //*************************************************************************************************
944 template< typename MT1 // Type of the left-hand side dense matrix
945  , typename MT2 > // Type of the right-hand side dense matrix
946 inline decltype(auto)
947  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
948  EnableIf_< IsSymmetric<MT2> >* = nullptr )
949 {
951 
952  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
953  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
954 
955  return (~lhs) + trans( ~rhs );
956 }
958 //*************************************************************************************************
959 
960 
961 //*************************************************************************************************
990 template< typename MT1 // Type of the left-hand side dense matrix
991  , typename MT2 > // Type of the right-hand side dense matrix
992 inline decltype(auto)
993  operator+( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
994 {
996 
997  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
998  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
999  }
1000 
1001  return dmattdmatadd( ~lhs, ~rhs );
1002 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1019 template< typename MT1 // Type of the left-hand side dense matrix
1020  , typename MT2 > // Type of the right-hand side dense matrix
1021 inline const DMatTDMatAddExpr<MT2,MT1>
1022  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1023  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
1024 {
1026 
1027  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1028  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1029 
1030  return DMatTDMatAddExpr<MT2,MT1>( ~rhs, ~lhs );
1031 }
1033 //*************************************************************************************************
1034 
1035 
1036 //*************************************************************************************************
1049 template< typename MT1 // Type of the left-hand side dense matrix
1050  , typename MT2 > // Type of the right-hand side dense matrix
1051 inline decltype(auto)
1052  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1053  EnableIf_< And< Not< IsSymmetric<MT1> >, IsSymmetric<MT2> > >* = nullptr )
1054 {
1056 
1057  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1058  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1059 
1060  return trans( ~rhs ) + (~lhs);
1061 }
1063 //*************************************************************************************************
1064 
1065 
1066 //*************************************************************************************************
1079 template< typename MT1 // Type of the left-hand side dense matrix
1080  , typename MT2 > // Type of the right-hand side dense matrix >
1081 inline decltype(auto)
1082  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1083  EnableIf_< IsSymmetric<MT1> >* = nullptr )
1084 {
1086 
1087  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1088  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1089 
1090  return (~rhs) + trans( ~lhs );
1091 }
1093 //*************************************************************************************************
1094 
1095 
1096 //*************************************************************************************************
1125 template< typename MT1 // Type of the left-hand side dense matrix
1126  , typename MT2 > // Type of the right-hand side dense matrix
1127 inline decltype(auto)
1128  operator+( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1129 {
1131 
1132  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1133  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1134  }
1135 
1136  return tdmatdmatadd( ~lhs, ~rhs );
1137 }
1138 //*************************************************************************************************
1139 
1140 
1141 
1142 
1143 //=================================================================================================
1144 //
1145 // ROWS SPECIALIZATIONS
1146 //
1147 //=================================================================================================
1148 
1149 //*************************************************************************************************
1151 template< typename MT1, typename MT2 >
1152 struct Rows< DMatTDMatAddExpr<MT1,MT2> >
1153  : public Maximum< Rows<MT1>, Rows<MT2> >
1154 {};
1156 //*************************************************************************************************
1157 
1158 
1159 
1160 
1161 //=================================================================================================
1162 //
1163 // COLUMNS SPECIALIZATIONS
1164 //
1165 //=================================================================================================
1166 
1167 //*************************************************************************************************
1169 template< typename MT1, typename MT2 >
1170 struct Columns< DMatTDMatAddExpr<MT1,MT2> >
1171  : public Maximum< Columns<MT1>, Columns<MT2> >
1172 {};
1174 //*************************************************************************************************
1175 
1176 
1177 
1178 
1179 //=================================================================================================
1180 //
1181 // ISALIGNED SPECIALIZATIONS
1182 //
1183 //=================================================================================================
1184 
1185 //*************************************************************************************************
1187 template< typename MT1, typename MT2 >
1188 struct IsAligned< DMatTDMatAddExpr<MT1,MT2> >
1189  : public BoolConstant< And< IsAligned<MT1>, IsAligned<MT2> >::value >
1190 {};
1192 //*************************************************************************************************
1193 
1194 
1195 
1196 
1197 //=================================================================================================
1198 //
1199 // ISSYMMETRIC SPECIALIZATIONS
1200 //
1201 //=================================================================================================
1202 
1203 //*************************************************************************************************
1205 template< typename MT1, typename MT2 >
1206 struct IsSymmetric< DMatTDMatAddExpr<MT1,MT2> >
1207  : public BoolConstant< IsSymmetric<MT1>::value && IsSymmetric<MT2>::value >
1208 {};
1210 //*************************************************************************************************
1211 
1212 
1213 
1214 
1215 //=================================================================================================
1216 //
1217 // ISHERMITIAN SPECIALIZATIONS
1218 //
1219 //=================================================================================================
1220 
1221 //*************************************************************************************************
1223 template< typename MT1, typename MT2 >
1224 struct IsHermitian< DMatTDMatAddExpr<MT1,MT2> >
1225  : public BoolConstant< IsHermitian<MT1>::value && IsHermitian<MT2>::value >
1226 {};
1228 //*************************************************************************************************
1229 
1230 
1231 
1232 
1233 //=================================================================================================
1234 //
1235 // ISLOWER SPECIALIZATIONS
1236 //
1237 //=================================================================================================
1238 
1239 //*************************************************************************************************
1241 template< typename MT1, typename MT2 >
1242 struct IsLower< DMatTDMatAddExpr<MT1,MT2> >
1243  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1244 {};
1246 //*************************************************************************************************
1247 
1248 
1249 
1250 
1251 //=================================================================================================
1252 //
1253 // ISUNILOWER SPECIALIZATIONS
1254 //
1255 //=================================================================================================
1256 
1257 //*************************************************************************************************
1259 template< typename MT1, typename MT2 >
1260 struct IsUniLower< DMatTDMatAddExpr<MT1,MT2> >
1261  : public BoolConstant< Or< And< IsUniLower<MT1>, IsStrictlyLower<MT2> >
1262  , And< IsUniLower<MT2>, IsStrictlyLower<MT1> > >::value >
1263 {};
1265 //*************************************************************************************************
1266 
1267 
1268 
1269 
1270 //=================================================================================================
1271 //
1272 // ISSTRICTLYLOWER SPECIALIZATIONS
1273 //
1274 //=================================================================================================
1275 
1276 //*************************************************************************************************
1278 template< typename MT1, typename MT2 >
1279 struct IsStrictlyLower< DMatTDMatAddExpr<MT1,MT2> >
1280  : public BoolConstant< And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >::value >
1281 {};
1283 //*************************************************************************************************
1284 
1285 
1286 
1287 
1288 //=================================================================================================
1289 //
1290 // ISUPPER SPECIALIZATIONS
1291 //
1292 //=================================================================================================
1293 
1294 //*************************************************************************************************
1296 template< typename MT1, typename MT2 >
1297 struct IsUpper< DMatTDMatAddExpr<MT1,MT2> >
1298  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1299 {};
1301 //*************************************************************************************************
1302 
1303 
1304 
1305 
1306 //=================================================================================================
1307 //
1308 // ISUNIUPPER SPECIALIZATIONS
1309 //
1310 //=================================================================================================
1311 
1312 //*************************************************************************************************
1314 template< typename MT1, typename MT2 >
1315 struct IsUniUpper< DMatTDMatAddExpr<MT1,MT2> >
1316  : public BoolConstant< Or< And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >
1317  , And< IsUniUpper<MT2>, IsStrictlyUpper<MT1> > >::value >
1318 {};
1320 //*************************************************************************************************
1321 
1322 
1323 
1324 
1325 //=================================================================================================
1326 //
1327 // ISSTRICTLYUPPER SPECIALIZATIONS
1328 //
1329 //=================================================================================================
1330 
1331 //*************************************************************************************************
1333 template< typename MT1, typename MT2 >
1334 struct IsStrictlyUpper< DMatTDMatAddExpr<MT1,MT2> >
1335  : public BoolConstant< And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >::value >
1336 {};
1338 //*************************************************************************************************
1339 
1340 } // namespace blaze
1341 
1342 #endif
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTDMatAddExpr.h:258
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:181
#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:70
Header file for the Rows type trait.
DMatTDMatAddExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTDMatAddExpr class.
Definition: DMatTDMatAddExpr.h:201
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:786
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:71
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.
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
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: DMatTDMatAddExpr.h:278
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:232
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:88
Header file for the AddExprTrait class template.
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:175
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:88
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatAddExpr.h:323
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:116
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatAddExpr.h:172
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 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:115
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:72
ReturnType_< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:114
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:268
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:57
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:303
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 Columns type trait.
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:169
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:217
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:290
#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:108
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:170
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:178
ResultType_< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:111
#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:331
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:184
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:332
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:819
#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:248
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:790
ResultType_< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:112
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTDMatAddExpr.h:313
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:171
Header file for the IntegralConstant class template.
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:75
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
Compile time logical and evaluation.The And alias declaration performs at compile time a logical and ...
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:113
AddExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DMatTDMatAddExpr.h:129
Header file for the IsHermitian 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:250
#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:105