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 <utility>
44 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
65 #include <blaze/system/Blocking.h>
67 #include <blaze/util/Assert.h>
68 #include <blaze/util/DisableIf.h>
69 #include <blaze/util/EnableIf.h>
72 #include <blaze/util/mpl/If.h>
73 #include <blaze/util/Types.h>
74 
75 
76 namespace blaze {
77 
78 //=================================================================================================
79 //
80 // CLASS DMATTDMATADDEXPR
81 //
82 //=================================================================================================
83 
84 //*************************************************************************************************
91 template< typename MT1 // Type of the left-hand side dense matrix
92  , typename MT2 > // Type of the right-hand side dense matrix
94  : public MatMatAddExpr< DenseMatrix< DMatTDMatAddExpr<MT1,MT2>, false > >
95  , private Computation
96 {
97  private:
98  //**Type definitions****************************************************************************
105  //**********************************************************************************************
106 
107  //**Return type evaluation**********************************************************************
109 
114  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
115 
117  using ExprReturnType = decltype( std::declval<RN1>() + std::declval<RN2>() );
118  //**********************************************************************************************
119 
120  //**Serial evaluation strategy******************************************************************
122 
128  static constexpr bool useAssign =
129  ( RequiresEvaluation_v<MT1> || RequiresEvaluation_v<MT2> || !returnExpr );
130 
132  template< typename MT >
134  static constexpr bool UseAssign_v = useAssign;
136  //**********************************************************************************************
137 
138  //**Parallel evaluation strategy****************************************************************
140 
146  template< typename MT >
147  static constexpr bool UseSMPAssign_v =
150  //**********************************************************************************************
151 
152  public:
153  //**Type definitions****************************************************************************
160 
163 
165  using CompositeType = const ResultType;
166 
168  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
169 
171  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
172  //**********************************************************************************************
173 
174  //**Compilation flags***************************************************************************
176  static constexpr bool simdEnabled = false;
177 
179  static constexpr bool smpAssignable = ( MT1::smpAssignable && MT2::smpAssignable );
180  //**********************************************************************************************
181 
182  //**Constructor*********************************************************************************
188  explicit inline DMatTDMatAddExpr( const MT1& lhs, const MT2& rhs ) noexcept
189  : lhs_( lhs ) // Left-hand side dense matrix of the addition expression
190  , rhs_( rhs ) // Right-hand side dense matrix of the addition expression
191  {
192  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
193  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
194  }
195  //**********************************************************************************************
196 
197  //**Access operator*****************************************************************************
204  inline ReturnType operator()( size_t i, size_t j ) const {
205  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
206  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
207  return lhs_(i,j) + rhs_(i,j);
208  }
209  //**********************************************************************************************
210 
211  //**At function*********************************************************************************
219  inline ReturnType at( size_t i, size_t j ) const {
220  if( i >= lhs_.rows() ) {
221  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
222  }
223  if( j >= lhs_.columns() ) {
224  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
225  }
226  return (*this)(i,j);
227  }
228  //**********************************************************************************************
229 
230  //**Rows function*******************************************************************************
235  inline size_t rows() const noexcept {
236  return lhs_.rows();
237  }
238  //**********************************************************************************************
239 
240  //**Columns function****************************************************************************
245  inline size_t columns() const noexcept {
246  return lhs_.columns();
247  }
248  //**********************************************************************************************
249 
250  //**Left operand access*************************************************************************
255  inline LeftOperand leftOperand() const noexcept {
256  return lhs_;
257  }
258  //**********************************************************************************************
259 
260  //**Right operand access************************************************************************
265  inline RightOperand rightOperand() const noexcept {
266  return rhs_;
267  }
268  //**********************************************************************************************
269 
270  //**********************************************************************************************
276  template< typename T >
277  inline bool canAlias( const T* alias ) const noexcept {
278  return ( IsExpression_v<MT1> && ( RequiresEvaluation_v<MT1> ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
279  ( IsExpression_v<MT2> && ( RequiresEvaluation_v<MT2> ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
280  }
281  //**********************************************************************************************
282 
283  //**********************************************************************************************
289  template< typename T >
290  inline bool isAliased( const T* alias ) const noexcept {
291  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
292  }
293  //**********************************************************************************************
294 
295  //**********************************************************************************************
300  inline bool isAligned() const noexcept {
301  return lhs_.isAligned() && rhs_.isAligned();
302  }
303  //**********************************************************************************************
304 
305  //**********************************************************************************************
310  inline bool canSMPAssign() const noexcept {
311  return lhs_.canSMPAssign() || rhs_.canSMPAssign() ||
312  ( rows() * columns() >= SMP_DMATTDMATADD_THRESHOLD );
313  }
314  //**********************************************************************************************
315 
316  private:
317  //**Member variables****************************************************************************
320  //**********************************************************************************************
321 
322  //**Assignment to dense matrices****************************************************************
336  template< typename MT // Type of the target dense matrix
337  , bool SO > // Storage order of the target dense matrix
338  friend inline auto assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
340  {
342 
343  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
344  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
345 
346  constexpr size_t block( BLOCK_SIZE );
347 
348  const size_t m( rhs.rows() );
349  const size_t n( rhs.columns() );
350 
351  for( size_t ii=0UL; ii<m; ii+=block ) {
352  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
353  for( size_t jj=0UL; jj<n; jj+=block ) {
354  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
355  for( size_t i=ii; i<iend; ++i ) {
356  for( size_t j=jj; j<jend; ++j ) {
357  (~lhs)(i,j) = rhs.lhs_(i,j) + rhs.rhs_(i,j);
358  }
359  }
360  }
361  }
362  }
364  //**********************************************************************************************
365 
366  //**Assignment to dense matrices****************************************************************
380  template< typename MT // Type of the target dense matrix
381  , bool SO > // Storage order of the target dense matrix
382  friend inline auto assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
384  {
386 
387  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
388  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
389 
390  if( !IsOperation_v<MT1> && isSame( ~lhs, rhs.lhs_ ) ) {
391  addAssign( ~lhs, rhs.rhs_ );
392  }
393  else if( !IsOperation_v<MT2> && isSame( ~lhs, rhs.rhs_ ) ) {
394  addAssign( ~lhs, rhs.lhs_ );
395  }
396  else if( !RequiresEvaluation_v<MT2> ) {
397  assign ( ~lhs, rhs.rhs_ );
398  addAssign( ~lhs, rhs.lhs_ );
399  }
400  else {
401  assign ( ~lhs, rhs.lhs_ );
402  addAssign( ~lhs, rhs.rhs_ );
403  }
404  }
406  //**********************************************************************************************
407 
408  //**Assignment to sparse matrices***************************************************************
420  template< typename MT // Type of the target sparse matrix
421  , bool SO > // Storage order of the target sparse matrix
422  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
423  {
425 
426  using TmpType = If_t< SO, OppositeType, ResultType >;
427 
434 
435  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
436  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
437 
438  const TmpType tmp( serial( rhs ) );
439  assign( ~lhs, tmp );
440  }
442  //**********************************************************************************************
443 
444  //**Addition assignment to dense matrices*******************************************************
458  template< typename MT // Type of the target dense matrix
459  , bool SO > // Storage order of the target dense matrix
460  friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
461  -> DisableIf_t< UseAssign_v<MT> >
462  {
464 
465  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
466  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
467 
468  constexpr size_t block( BLOCK_SIZE );
469 
470  const size_t m( rhs.rows() );
471  const size_t n( rhs.columns() );
472 
473  for( size_t ii=0UL; ii<m; ii+=block ) {
474  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
475  for( size_t jj=0UL; jj<n; jj+=block ) {
476  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
477  for( size_t i=ii; i<iend; ++i ) {
478  for( size_t j=jj; j<jend; ++j ) {
479  (~lhs)(i,j) += rhs.lhs_(i,j) + rhs.rhs_(i,j);
480  }
481  }
482  }
483  }
484  }
486  //**********************************************************************************************
487 
488  //**Addition assignment to dense matrices*******************************************************
502  template< typename MT // Type of the target dense matrix
503  , bool SO > // Storage order of the target dense matrix
504  friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
505  -> EnableIf_t< UseAssign_v<MT> >
506  {
508 
509  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
510  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
511 
512  if( !RequiresEvaluation_v<MT2> ) {
513  addAssign( ~lhs, rhs.rhs_ );
514  addAssign( ~lhs, rhs.lhs_ );
515  }
516  else {
517  addAssign( ~lhs, rhs.lhs_ );
518  addAssign( ~lhs, rhs.rhs_ );
519  }
520  }
522  //**********************************************************************************************
523 
524  //**Addition assignment to sparse matrices******************************************************
525  // No special implementation for the addition assignment to sparse matrices.
526  //**********************************************************************************************
527 
528  //**Subtraction assignment to dense matrices****************************************************
542  template< typename MT // Type of the target dense matrix
543  , bool SO > // Storage order of the target dense matrix
544  friend inline auto subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
545  -> DisableIf_t< UseAssign_v<MT> >
546  {
548 
549  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
550  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
551 
552  constexpr size_t block( BLOCK_SIZE );
553 
554  const size_t m( rhs.rows() );
555  const size_t n( rhs.columns() );
556 
557  for( size_t ii=0UL; ii<m; ii+=block ) {
558  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
559  for( size_t jj=0UL; jj<n; jj+=block ) {
560  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
561  for( size_t i=ii; i<iend; ++i ) {
562  for( size_t j=jj; j<jend; ++j ) {
563  (~lhs)(i,j) -= rhs.lhs_(i,j) + rhs.rhs_(i,j);
564  }
565  }
566  }
567  }
568  }
570  //**********************************************************************************************
571 
572  //**Subtraction assignment to dense matrices****************************************************
586  template< typename MT // Type of the target dense matrix
587  , bool SO > // Storage order of the target dense matrix
588  friend inline auto subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
589  -> EnableIf_t< UseAssign_v<MT> >
590  {
592 
593  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
594  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
595 
596  if( !RequiresEvaluation_v<MT2> ) {
597  subAssign( ~lhs, rhs.rhs_ );
598  subAssign( ~lhs, rhs.lhs_ );
599  }
600  else {
601  subAssign( ~lhs, rhs.lhs_ );
602  subAssign( ~lhs, rhs.rhs_ );
603  }
604  }
606  //**********************************************************************************************
607 
608  //**Subtraction assignment to sparse matrices***************************************************
609  // No special implementation for the subtraction assignment to sparse matrices.
610  //**********************************************************************************************
611 
612  //**Schur product assignment to dense matrices**************************************************
627  template< typename MT // Type of the target dense matrix
628  , bool SO > // Storage order of the target dense matrix
629  friend inline auto schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
630  -> DisableIf_t< UseAssign_v<MT> >
631  {
633 
637 
638  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
639  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
640 
641  const ResultType tmp( serial( rhs ) );
642  schurAssign( ~lhs, tmp );
643  }
645  //**********************************************************************************************
646 
647  //**Schur product assignment to sparse matrices*************************************************
648  // No special implementation for the Schur product assignment to sparse matrices.
649  //**********************************************************************************************
650 
651  //**Multiplication assignment to dense matrices*************************************************
652  // No special implementation for the multiplication assignment to dense matrices.
653  //**********************************************************************************************
654 
655  //**Multiplication assignment to sparse matrices************************************************
656  // No special implementation for the multiplication assignment to sparse matrices.
657  //**********************************************************************************************
658 
659  //**SMP assignment to dense matrices************************************************************
673  template< typename MT // Type of the target dense matrix
674  , bool SO > // Storage order of the target dense matrix
675  friend inline auto smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
676  -> EnableIf_t< UseSMPAssign_v<MT> >
677  {
679 
680  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
681  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
682 
683  if( !IsOperation_v<MT1> && isSame( ~lhs, rhs.lhs_ ) ) {
684  smpAddAssign( ~lhs, rhs.rhs_ );
685  }
686  else if( !IsOperation_v<MT2> && isSame( ~lhs, rhs.rhs_ ) ) {
687  smpAddAssign( ~lhs, rhs.lhs_ );
688  }
689  else if( !RequiresEvaluation_v<MT2> ) {
690  smpAssign ( ~lhs, rhs.rhs_ );
691  smpAddAssign( ~lhs, rhs.lhs_ );
692  }
693  else {
694  smpAssign ( ~lhs, rhs.lhs_ );
695  smpAddAssign( ~lhs, rhs.rhs_ );
696  }
697  }
699  //**********************************************************************************************
700 
701  //**SMP assignment to sparse matrices***********************************************************
715  template< typename MT // Type of the target sparse matrix
716  , bool SO > // Storage order of the target sparse matrix
717  friend inline auto smpAssign( SparseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
718  -> EnableIf_t< UseSMPAssign_v<MT> >
719  {
721 
722  using TmpType = If_t< SO, OppositeType, ResultType >;
723 
730 
731  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
732  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
733 
734  const TmpType tmp( rhs );
735  smpAssign( ~lhs, tmp );
736  }
738  //**********************************************************************************************
739 
740  //**SMP addition assignment to dense matrices***************************************************
755  template< typename MT // Type of the target dense matrix
756  , bool SO > // Storage order of the target dense matrix
757  friend inline auto smpAddAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
758  -> EnableIf_t< UseSMPAssign_v<MT> >
759  {
761 
762  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
763  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
764 
765  if( !RequiresEvaluation_v<MT2> ) {
766  smpAddAssign( ~lhs, rhs.rhs_ );
767  smpAddAssign( ~lhs, rhs.lhs_ );
768  }
769  else {
770  smpAddAssign( ~lhs, rhs.lhs_ );
771  smpAddAssign( ~lhs, rhs.rhs_ );
772  }
773  }
775  //**********************************************************************************************
776 
777  //**SMP addition assignment to sparse matrices**************************************************
778  // No special implementation for the SMP addition assignment to sparse matrices.
779  //**********************************************************************************************
780 
781  //**SMP subtraction assignment to dense matrices************************************************
796  template< typename MT // Type of the target dense matrix
797  , bool SO > // Storage order of the target dense matrix
798  friend inline auto smpSubAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
799  -> EnableIf_t< UseSMPAssign_v<MT> >
800  {
802 
803  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
804  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
805 
806  if( !RequiresEvaluation_v<MT2> ) {
807  smpSubAssign( ~lhs, rhs.rhs_ );
808  smpSubAssign( ~lhs, rhs.lhs_ );
809  }
810  else {
811  smpSubAssign( ~lhs, rhs.lhs_ );
812  smpSubAssign( ~lhs, rhs.rhs_ );
813  }
814  }
816  //**********************************************************************************************
817 
818  //**SMP subtraction assignment to sparse matrices***********************************************
819  // No special implementation for the SMP subtraction assignment to sparse matrices.
820  //**********************************************************************************************
821 
822  //**SMP Schur product assignment to dense matrices**********************************************
837  template< typename MT // Type of the target dense matrix
838  , bool SO > // Storage order of the target dense matrix
839  friend inline auto smpSchurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatAddExpr& rhs )
840  -> EnableIf_t< UseSMPAssign_v<MT> >
841  {
843 
847 
848  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
849  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
850 
851  const ResultType tmp( rhs );
852  smpSchurAssign( ~lhs, tmp );
853  }
855  //**********************************************************************************************
856 
857  //**SMP Schur product assignment to sparse matrices*********************************************
858  // No special implementation for the SMP Schur product assignment to sparse matrices.
859  //**********************************************************************************************
860 
861  //**SMP multiplication assignment to dense matrices*********************************************
862  // No special implementation for the SMP multiplication assignment to dense matrices.
863  //**********************************************************************************************
864 
865  //**SMP multiplication assignment to sparse matrices********************************************
866  // No special implementation for the SMP multiplication assignment to sparse matrices.
867  //**********************************************************************************************
868 
869  //**Compile time checks*************************************************************************
877  //**********************************************************************************************
878 };
879 //*************************************************************************************************
880 
881 
882 
883 
884 //=================================================================================================
885 //
886 // GLOBAL BINARY ARITHMETIC OPERATORS
887 //
888 //=================================================================================================
889 
890 //*************************************************************************************************
903 template< typename MT1 // Type of the left-hand side dense matrix
904  , typename MT2 // Type of the right-hand side dense matrix
905  , EnableIf_t< !IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
906 inline const DMatTDMatAddExpr<MT1,MT2>
907  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
908 {
910 
911  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
912  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
913 
914  return DMatTDMatAddExpr<MT1,MT2>( ~lhs, ~rhs );
915 }
917 //*************************************************************************************************
918 
919 
920 //*************************************************************************************************
933 template< typename MT1 // Type of the left-hand side dense matrix
934  , typename MT2 // Type of the right-hand side dense matrix
935  , EnableIf_t< IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
936 inline decltype(auto)
937  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
938 {
940 
941  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
942  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
943 
944  return trans( ~lhs ) + ~rhs;
945 }
947 //*************************************************************************************************
948 
949 
950 //*************************************************************************************************
963 template< typename MT1 // Type of the left-hand side dense matrix
964  , typename MT2 // Type of the right-hand side dense matrix
965  , EnableIf_t< IsSymmetric_v<MT2> >* = nullptr >
966 inline decltype(auto)
967  dmattdmatadd( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
968 {
970 
971  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
972  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
973 
974  return (~lhs) + trans( ~rhs );
975 }
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
1009 template< typename MT1 // Type of the left-hand side dense matrix
1010  , typename MT2 > // Type of the right-hand side dense matrix
1011 inline decltype(auto)
1012  operator+( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
1013 {
1015 
1016  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1017  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1018  }
1019 
1020  return dmattdmatadd( ~lhs, ~rhs );
1021 }
1022 //*************************************************************************************************
1023 
1024 
1025 //*************************************************************************************************
1038 template< typename MT1 // Type of the left-hand side dense matrix
1039  , typename MT2 // Type of the right-hand side dense matrix
1040  , EnableIf_t< !IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
1041 inline const DMatTDMatAddExpr<MT2,MT1>
1042  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1043 {
1045 
1046  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1047  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1048 
1049  return DMatTDMatAddExpr<MT2,MT1>( ~rhs, ~lhs );
1050 }
1052 //*************************************************************************************************
1053 
1054 
1055 //*************************************************************************************************
1068 template< typename MT1 // Type of the left-hand side dense matrix
1069  , typename MT2 // Type of the right-hand side dense matrix
1070  , EnableIf_t< !IsSymmetric_v<MT1> && IsSymmetric_v<MT2> >* = nullptr >
1071 inline decltype(auto)
1072  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1073 {
1075 
1076  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1077  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1078 
1079  return trans( ~rhs ) + (~lhs);
1080 }
1082 //*************************************************************************************************
1083 
1084 
1085 //*************************************************************************************************
1098 template< typename MT1 // Type of the left-hand side dense matrix
1099  , typename MT2 // Type of the right-hand side dense matrix >
1100  , EnableIf_t< IsSymmetric_v<MT1> >* = nullptr >
1101 inline decltype(auto)
1102  tdmatdmatadd( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1103 {
1105 
1106  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1107  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1108 
1109  return (~rhs) + trans( ~lhs );
1110 }
1112 //*************************************************************************************************
1113 
1114 
1115 //*************************************************************************************************
1144 template< typename MT1 // Type of the left-hand side dense matrix
1145  , typename MT2 > // Type of the right-hand side dense matrix
1146 inline decltype(auto)
1147  operator+( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1148 {
1150 
1151  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1152  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1153  }
1154 
1155  return tdmatdmatadd( ~lhs, ~rhs );
1156 }
1157 //*************************************************************************************************
1158 
1159 
1160 
1161 
1162 //=================================================================================================
1163 //
1164 // ISALIGNED SPECIALIZATIONS
1165 //
1166 //=================================================================================================
1167 
1168 //*************************************************************************************************
1170 template< typename MT1, typename MT2 >
1171 struct IsAligned< DMatTDMatAddExpr<MT1,MT2> >
1172  : public BoolConstant< IsAligned_v<MT1> && IsAligned_v<MT2> >
1173 {};
1175 //*************************************************************************************************
1176 
1177 
1178 
1179 
1180 //=================================================================================================
1181 //
1182 // ISSTRICTLYUPPER SPECIALIZATIONS
1183 //
1184 //=================================================================================================
1185 
1186 //*************************************************************************************************
1188 template< typename MT1, typename MT2 >
1189 struct IsStrictlyUpper< DMatTDMatAddExpr<MT1,MT2> >
1190  : public BoolConstant< IsStrictlyUpper_v<MT1> && IsStrictlyUpper_v<MT2> >
1191 {};
1193 //*************************************************************************************************
1194 
1195 } // namespace blaze
1196 
1197 #endif
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTDMatAddExpr.h:245
#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.
DMatTDMatAddExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTDMatAddExpr class.
Definition: DMatTDMatAddExpr.h:188
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:992
Header file for basic type definitions.
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTDMatAddExpr.h:157
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
ReturnType_t< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:102
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the addition expression. ...
Definition: DMatTDMatAddExpr.h:128
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
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
CompositeType_t< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:103
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: DMatTDMatAddExpr.h:265
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatTDMatAddExpr.h:219
If_t< IsExpression_v< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:171
Header file for the Computation base class.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatAddExpr.h:310
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:100
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: DMatTDMatAddExpr.h:114
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Constraint on the data type.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
ReturnType_t< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:101
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTDMatAddExpr.h:255
decltype(std::declval< RN1 >()+std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: DMatTDMatAddExpr.h:117
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.
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:290
#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.
If_t< IsExpression_v< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:168
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:158
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.
typename AddTrait< T1, T2 >::Type AddTrait_t
Auxiliary alias declaration for the AddTrait class template.The AddTrait_t alias declaration provides...
Definition: AddTrait.h:238
Header file for the IsAligned type trait.
Constraints on the storage order of matrix types.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTDMatAddExpr.h:204
Header file for the exception macros of the math module.
AddTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:156
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTDMatAddExpr.h:277
#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:103
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTDMatAddExpr.h:165
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatAddExpr.h:159
#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:318
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
Header file for the addition trait.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
RightOperand rhs_
Right-hand side dense matrix of the addition expression.
Definition: DMatTDMatAddExpr.h:319
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
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
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:808
#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.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:101
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
#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:235
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:104
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
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:300
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DMatTDMatAddExpr.h:162
Header file for the IntegralConstant class template.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DMatTDMatAddExpr.h:179
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DMatTDMatAddExpr.h:176
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
ResultType_t< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTDMatAddExpr.h:99
#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
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:93