Blaze  3.6
DMatTDMatSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTDMATSUBEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATTDMATSUBEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
64 #include <blaze/system/Blocking.h>
66 #include <blaze/util/Assert.h>
67 #include <blaze/util/DisableIf.h>
68 #include <blaze/util/EnableIf.h>
71 #include <blaze/util/mpl/If.h>
72 #include <blaze/util/Types.h>
73 
74 
75 namespace blaze {
76 
77 //=================================================================================================
78 //
79 // CLASS DMATTDMATSUBEXPR
80 //
81 //=================================================================================================
82 
83 //*************************************************************************************************
90 template< typename MT1 // Type of the left-hand side dense matrix
91  , typename MT2 > // Type of the right-hand side dense matrix
93  : public MatMatSubExpr< DenseMatrix< DMatTDMatSubExpr<MT1,MT2>, false > >
94  , private Computation
95 {
96  private:
97  //**Type definitions****************************************************************************
104  //**********************************************************************************************
105 
106  //**Return type evaluation**********************************************************************
108 
113  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
114 
116  using ExprReturnType = decltype( std::declval<RN1>() - std::declval<RN2>() );
117  //**********************************************************************************************
118 
119  //**Serial evaluation strategy******************************************************************
121 
127  static constexpr bool useAssign =
128  ( RequiresEvaluation_v<MT1> || RequiresEvaluation_v<MT2> || !returnExpr );
129 
131  template< typename MT >
133  static constexpr bool UseAssign_v = useAssign;
135  //**********************************************************************************************
136 
137  //**Parallel evaluation strategy****************************************************************
139 
145  template< typename MT >
146  static constexpr bool UseSMPAssign_v =
147  ( ( !MT1::smpAssignable || !MT2::smpAssignable ) && useAssign );
149  //**********************************************************************************************
150 
151  public:
152  //**Type definitions****************************************************************************
159 
162 
164  using CompositeType = const ResultType;
165 
167  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
168 
170  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
171  //**********************************************************************************************
172 
173  //**Compilation flags***************************************************************************
175  static constexpr bool simdEnabled = false;
176 
178  static constexpr bool smpAssignable = ( MT1::smpAssignable && MT2::smpAssignable );
179  //**********************************************************************************************
180 
181  //**Constructor*********************************************************************************
187  explicit inline DMatTDMatSubExpr( const MT1& lhs, const MT2& rhs ) noexcept
188  : lhs_( lhs ) // Left-hand side dense matrix of the subtraction expression
189  , rhs_( rhs ) // Right-hand side dense matrix of the subtraction expression
190  {
191  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
192  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
193  }
194  //**********************************************************************************************
195 
196  //**Access operator*****************************************************************************
203  inline ReturnType operator()( size_t i, size_t j ) const {
204  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
205  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
206  return lhs_(i,j) - rhs_(i,j);
207  }
208  //**********************************************************************************************
209 
210  //**At function*********************************************************************************
218  inline ReturnType at( size_t i, size_t j ) const {
219  if( i >= lhs_.rows() ) {
220  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
221  }
222  if( j >= lhs_.columns() ) {
223  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
224  }
225  return (*this)(i,j);
226  }
227  //**********************************************************************************************
228 
229  //**Rows function*******************************************************************************
234  inline size_t rows() const noexcept {
235  return lhs_.rows();
236  }
237  //**********************************************************************************************
238 
239  //**Columns function****************************************************************************
244  inline size_t columns() const noexcept {
245  return lhs_.columns();
246  }
247  //**********************************************************************************************
248 
249  //**Left operand access*************************************************************************
254  inline LeftOperand leftOperand() const noexcept {
255  return lhs_;
256  }
257  //**********************************************************************************************
258 
259  //**Right operand access************************************************************************
264  inline RightOperand rightOperand() const noexcept {
265  return rhs_;
266  }
267  //**********************************************************************************************
268 
269  //**********************************************************************************************
275  template< typename T >
276  inline bool canAlias( const T* alias ) const noexcept {
277  return ( IsExpression_v<MT1> && ( RequiresEvaluation_v<MT1> ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
278  ( IsExpression_v<MT2> && ( RequiresEvaluation_v<MT2> ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
279  }
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
288  template< typename T >
289  inline bool isAliased( const T* alias ) const noexcept {
290  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
291  }
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
299  inline bool isAligned() const noexcept {
300  return lhs_.isAligned() && rhs_.isAligned();
301  }
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
309  inline bool canSMPAssign() const noexcept {
310  return lhs_.canSMPAssign() || rhs_.canSMPAssign() ||
311  ( rows() * columns() >= SMP_DMATTDMATSUB_THRESHOLD );
312  }
313  //**********************************************************************************************
314 
315  private:
316  //**Member variables****************************************************************************
319  //**********************************************************************************************
320 
321  //**Assignment to dense matrices****************************************************************
335  template< typename MT // Type of the target dense matrix
336  , bool SO > // Storage order of the target dense matrix
337  friend inline auto assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
339  {
341 
342  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
343  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
344 
345  constexpr size_t block( BLOCK_SIZE );
346 
347  const size_t m( rhs.rows() );
348  const size_t n( rhs.columns() );
349 
350  for( size_t ii=0UL; ii<m; ii+=block ) {
351  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
352  for( size_t jj=0UL; jj<n; jj+=block ) {
353  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
354  for( size_t i=ii; i<iend; ++i ) {
355  for( size_t j=jj; j<jend; ++j ) {
356  (~lhs)(i,j) = rhs.lhs_(i,j) - rhs.rhs_(i,j);
357  }
358  }
359  }
360  }
361  }
363  //**********************************************************************************************
364 
365  //**Assignment to dense matrices****************************************************************
379  template< typename MT // Type of the target dense matrix
380  , bool SO > // Storage order of the target dense matrix
381  friend inline auto assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
383  {
385 
386  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
387  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
388 
389  if( !IsOperation_v<MT1> && isSame( ~lhs, rhs.lhs_ ) ) {
390  subAssign( ~lhs, rhs.rhs_ );
391  }
392  else if( ( !IsOperation_v<MT2> && isSame( ~lhs, rhs.rhs_ ) ) ||
393  ( !RequiresEvaluation_v<MT2> && rhs.rhs_.isAliased( &(~lhs) ) ) ) {
394  assign ( ~lhs, -rhs.rhs_ );
395  addAssign( ~lhs, rhs.lhs_ );
396  }
397  else {
398  assign ( ~lhs, rhs.lhs_ );
399  subAssign( ~lhs, rhs.rhs_ );
400  }
401  }
403  //**********************************************************************************************
404 
405  //**Assignment to sparse matrices***************************************************************
417  template< typename MT // Type of the target sparse matrix
418  , bool SO > // Storage order of the target sparse matrix
419  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
420  {
422 
423  using TmpType = If_t< SO, OppositeType, ResultType >;
424 
431 
432  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
433  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
434 
435  const TmpType tmp( serial( rhs ) );
436  assign( ~lhs, tmp );
437  }
439  //**********************************************************************************************
440 
441  //**Addition assignment to dense matrices*******************************************************
456  template< typename MT // Type of the target dense matrix
457  , bool SO > // Storage order of the target dense matrix
458  friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
459  -> DisableIf_t< UseAssign_v<MT> >
460  {
462 
463  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
464  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
465 
466  constexpr size_t block( BLOCK_SIZE );
467 
468  const size_t m( rhs.rows() );
469  const size_t n( rhs.columns() );
470 
471  for( size_t ii=0UL; ii<m; ii+=block ) {
472  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
473  for( size_t jj=0UL; jj<n; jj+=block ) {
474  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
475  for( size_t i=ii; i<iend; ++i ) {
476  for( size_t j=jj; j<jend; ++j ) {
477  (~lhs)(i,j) += rhs.lhs_(i,j) - rhs.rhs_(i,j);
478  }
479  }
480  }
481  }
482  }
484  //**********************************************************************************************
485 
486  //**Addition assignment to dense matrices*******************************************************
501  template< typename MT // Type of the target dense matrix
502  , bool SO > // Storage order of the target dense matrix
503  friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
504  -> EnableIf_t< UseAssign_v<MT> >
505  {
507 
508  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
509  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
510 
511  if( !RequiresEvaluation_v<MT2> ) {
512  subAssign( ~lhs, rhs.rhs_ );
513  addAssign( ~lhs, rhs.lhs_ );
514  }
515  else {
516  addAssign( ~lhs, rhs.lhs_ );
517  subAssign( ~lhs, rhs.rhs_ );
518  }
519  }
521  //**********************************************************************************************
522 
523  //**Addition assignment to sparse matrices******************************************************
524  // No special implementation for the addition assignment to sparse matrices.
525  //**********************************************************************************************
526 
527  //**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 DMatTDMatSubExpr& 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****************************************************
587  template< typename MT // Type of the target dense matrix
588  , bool SO > // Storage order of the target dense matrix
589  friend inline auto subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
590  -> EnableIf_t< UseAssign_v<MT> >
591  {
593 
594  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
595  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
596 
597  if( !RequiresEvaluation_v<MT2> ) {
598  addAssign( ~lhs, rhs.rhs_ );
599  subAssign( ~lhs, rhs.lhs_ );
600  }
601  else {
602  subAssign( ~lhs, rhs.lhs_ );
603  addAssign( ~lhs, rhs.rhs_ );
604  }
605  }
607  //**********************************************************************************************
608 
609  //**Subtraction assignment to sparse matrices***************************************************
610  // No special implementation for the subtraction assignment to sparse matrices.
611  //**********************************************************************************************
612 
613  //**Schur product assignment to dense matrices**************************************************
628  template< typename MT // Type of the target dense matrix
629  , bool SO > // Storage order of the target dense matrix
630  friend inline auto schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
631  -> EnableIf_t< UseAssign_v<MT> >
632  {
634 
638 
639  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
640  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
641 
642  const ResultType tmp( serial( rhs ) );
643  schurAssign( ~lhs, tmp );
644  }
646  //**********************************************************************************************
647 
648  //**Schur product assignment to sparse matrices*************************************************
649  // No special implementation for the Schur product assignment to sparse matrices.
650  //**********************************************************************************************
651 
652  //**Multiplication assignment to dense matrices*************************************************
653  // No special implementation for the multiplication assignment to dense matrices.
654  //**********************************************************************************************
655 
656  //**Multiplication assignment to sparse matrices************************************************
657  // No special implementation for the multiplication assignment to sparse matrices.
658  //**********************************************************************************************
659 
660  //**SMP assignment to dense matrices************************************************************
674  template< typename MT // Type of the target dense matrix
675  , bool SO > // Storage order of the target dense matrix
676  friend inline auto smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
677  -> EnableIf_t< UseSMPAssign_v<MT> >
678  {
680 
681  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
682  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
683 
684  if( !IsOperation_v<MT1> && isSame( ~lhs, rhs.lhs_ ) ) {
685  smpSubAssign( ~lhs, rhs.rhs_ );
686  }
687  else if( ( !IsOperation_v<MT2> && isSame( ~lhs, rhs.rhs_ ) ) ||
688  ( !RequiresEvaluation_v<MT2> && rhs.rhs_.isAliased( &(~lhs) ) ) ) {
689  smpAssign ( ~lhs, -rhs.rhs_ );
690  smpAddAssign( ~lhs, rhs.lhs_ );
691  }
692  else {
693  smpAssign ( ~lhs, rhs.lhs_ );
694  smpSubAssign( ~lhs, rhs.rhs_ );
695  }
696  }
698  //**********************************************************************************************
699 
700  //**SMP assignment to sparse matrices***********************************************************
714  template< typename MT // Type of the target sparse matrix
715  , bool SO > // Storage order of the target sparse matrix
716  friend inline auto smpAssign( SparseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
717  -> EnableIf_t< UseSMPAssign_v<MT> >
718  {
720 
721  using TmpType = If_t< SO, OppositeType, ResultType >;
722 
729 
730  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
731  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
732 
733  const TmpType tmp( rhs );
734  smpAssign( ~lhs, tmp );
735  }
737  //**********************************************************************************************
738 
739  //**SMP addition assignment to dense matrices***************************************************
754  template< typename MT // Type of the target dense matrix
755  , bool SO > // Storage order of the target dense matrix
756  friend inline auto smpAddAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
757  -> EnableIf_t< UseSMPAssign_v<MT> >
758  {
760 
761  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
762  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
763 
764  if( !RequiresEvaluation_v<MT2> ) {
765  smpSubAssign( ~lhs, rhs.rhs_ );
766  smpAddAssign( ~lhs, rhs.lhs_ );
767  }
768  else {
769  smpAddAssign( ~lhs, rhs.lhs_ );
770  smpSubAssign( ~lhs, rhs.rhs_ );
771  }
772  }
774  //**********************************************************************************************
775 
776  //**SMP addition assignment to sparse matrices**************************************************
777  // No special implementation for the SMP addition assignment to sparse matrices.
778  //**********************************************************************************************
779 
780  //**SMP subtraction assignment to dense matrices************************************************
795  template< typename MT // Type of the target dense matrix
796  , bool SO > // Storage order of the target dense matrix
797  friend inline auto smpSubAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
798  -> EnableIf_t< UseSMPAssign_v<MT> >
799  {
801 
802  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
803  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
804 
805  if( !RequiresEvaluation_v<MT2> ) {
806  smpAddAssign( ~lhs, rhs.rhs_ );
807  smpSubAssign( ~lhs, rhs.lhs_ );
808  }
809  else {
810  smpSubAssign( ~lhs, rhs.lhs_ );
811  smpAddAssign( ~lhs, rhs.rhs_ );
812  }
813  }
815  //**********************************************************************************************
816 
817  //**SMP subtraction assignment to sparse matrices***********************************************
818  // No special implementation for the SMP subtraction assignment to sparse matrices.
819  //**********************************************************************************************
820 
821  //**SMP Schur product assignment to dense matrices**********************************************
836  template< typename MT // Type of the target dense matrix
837  , bool SO > // Storage order of the target dense matrix
838  friend inline auto smpSchurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
839  -> EnableIf_t< UseSMPAssign_v<MT> >
840  {
842 
846 
847  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
848  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
849 
850  const ResultType tmp( rhs );
851  smpSchurAssign( ~lhs, tmp );
852  }
854  //**********************************************************************************************
855 
856  //**SMP Schur product assignment to sparse matrices*********************************************
857  // No special implementation for the SMP Schur product assignment to sparse matrices.
858  //**********************************************************************************************
859 
860  //**SMP multiplication assignment to dense matrices*********************************************
861  // No special implementation for the SMP multiplication assignment to dense matrices.
862  //**********************************************************************************************
863 
864  //**SMP multiplication assignment to sparse matrices********************************************
865  // No special implementation for the SMP multiplication assignment to sparse matrices.
866  //**********************************************************************************************
867 
868  //**Compile time checks*************************************************************************
875  //**********************************************************************************************
876 };
877 //*************************************************************************************************
878 
879 
880 
881 
882 //=================================================================================================
883 //
884 // GLOBAL BINARY ARITHMETIC OPERATORS
885 //
886 //=================================================================================================
887 
888 //*************************************************************************************************
901 template< typename MT1 // Type of the left-hand side dense matrix
902  , typename MT2 // Type of the right-hand side dense matrix
903  , EnableIf_t< !IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
904 inline const DMatTDMatSubExpr<MT1,MT2>
905  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
906 {
908 
909  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
910  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
911 
912  return DMatTDMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
913 }
915 //*************************************************************************************************
916 
917 
918 //*************************************************************************************************
931 template< typename MT1 // Type of the left-hand side dense matrix
932  , typename MT2 // Type of the right-hand side dense matrix
933  , EnableIf_t< IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
934 inline decltype(auto)
935  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
936 {
938 
939  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
940  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
941 
942  return trans( ~lhs ) - ~rhs;
943 }
945 //*************************************************************************************************
946 
947 
948 //*************************************************************************************************
961 template< typename MT1 // Type of the left-hand side dense matrix
962  , typename MT2 // Type of the right-hand side dense matrix
963  , EnableIf_t< IsSymmetric_v<MT2> >* = nullptr >
964 inline decltype(auto)
965  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
966 {
968 
969  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
970  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
971 
972  return (~lhs) - trans( ~rhs );
973 }
975 //*************************************************************************************************
976 
977 
978 //*************************************************************************************************
1007 template< typename MT1 // Type of the left-hand side dense matrix
1008  , typename MT2 > // Type of the right-hand side dense matrix
1009 inline decltype(auto)
1010  operator-( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
1011 {
1013 
1014  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1015  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1016  }
1017 
1018  return dmattdmatsub( ~lhs, ~rhs );
1019 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1036 template< typename MT1 // Type of the left-hand side dense matrix
1037  , typename MT2 // Type of the right-hand side dense matrix
1038  , EnableIf_t< !IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
1039 inline const DMatTDMatSubExpr<MT1,MT2>
1040  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1041 {
1043 
1044  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1045  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1046 
1047  return DMatTDMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
1048 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1066 template< typename MT1 // Type of the left-hand side dense matrix
1067  , typename MT2 // Type of the right-hand side dense matrix
1068  , EnableIf_t< !IsSymmetric_v<MT1> && IsSymmetric_v<MT2> >* = nullptr >
1069 inline decltype(auto)
1070  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1071 {
1073 
1074  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1075  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1076 
1077  return (~lhs) - trans( ~rhs );
1078 }
1080 //*************************************************************************************************
1081 
1082 
1083 //*************************************************************************************************
1096 template< typename MT1 // Type of the left-hand side dense matrix
1097  , typename MT2 // Type of the right-hand side dense matrix
1098  , EnableIf_t< IsSymmetric_v<MT1> >* = nullptr >
1099 inline decltype(auto)
1100  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1101 {
1103 
1104  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1105  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1106 
1107  return trans( ~lhs ) - (~rhs);
1108 }
1110 //*************************************************************************************************
1111 
1112 
1113 //*************************************************************************************************
1142 template< typename MT1 // Type of the left-hand side dense matrix
1143  , typename MT2 > // Type of the right-hand side dense matrix
1144 inline decltype(auto)
1145  operator-( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1146 {
1148 
1149  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1150  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1151  }
1152 
1153  return tdmatdmatsub( ~lhs, ~rhs );
1154 }
1155 //*************************************************************************************************
1156 
1157 
1158 
1159 
1160 //=================================================================================================
1161 //
1162 // ISALIGNED SPECIALIZATIONS
1163 //
1164 //=================================================================================================
1165 
1166 //*************************************************************************************************
1168 template< typename MT1, typename MT2 >
1169 struct IsAligned< DMatTDMatSubExpr<MT1,MT2> >
1170  : public BoolConstant< IsAligned_v<MT1> && IsAligned_v<MT2> >
1171 {};
1173 //*************************************************************************************************
1174 
1175 } // namespace blaze
1176 
1177 #endif
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTDMatSubExpr.h:276
Constraint on the data type.
#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
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose dense matrix operand.
Definition: DMatTDMatSubExpr.h:264
Header file for auxiliary alias declarations.
Header file for kernel specific block sizes.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatTDMatSubExpr.h:218
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTDMatSubExpr.h:164
typename SubTrait< T1, T2 >::Type SubTrait_t
Auxiliary alias declaration for the SubTrait class template.The SubTrait_t alias declaration provides...
Definition: SubTrait.h:238
Header file for the subtraction trait.
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.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
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
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatSubExpr.h:158
LeftOperand lhs_
Left-hand side dense matrix of the subtraction expression.
Definition: DMatTDMatSubExpr.h:317
Header file for the Computation base class.
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
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
ReturnType_t< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:100
SubTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DMatTDMatSubExpr.h:155
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
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTDMatSubExpr.h:254
Expression object for dense matrix-transpose dense matrix subtractions.The DMatTDMatSubExpr class rep...
Definition: DMatTDMatSubExpr.h:92
decltype(std::declval< RN1 >() - std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: DMatTDMatSubExpr.h:116
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:99
Header file for the IsSymmetric type trait.
Base class for all matrix/matrix subtraction expression templates.The MatMatSubExpr class serves as a...
Definition: MatMatSubExpr.h:67
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatTDMatSubExpr.h:289
#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
#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 MatMatSubExpr base class.
Header file for the IsOperation type trait class.
Header file for the IsAligned type trait.
RightOperand rhs_
Right-hand side dense matrix of the subtraction expression.
Definition: DMatTDMatSubExpr.h:318
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DMatTDMatSubExpr.h:178
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
Constraint on the data type.
Header file for the EnableIf class template.
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_DIFFERENT_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:106
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
#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
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTDMatSubExpr.h:244
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.
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DMatTDMatSubExpr.h:175
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the subtraction expression.
Definition: DMatTDMatSubExpr.h:127
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
DMatTDMatSubExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTDMatSubExpr class.
Definition: DMatTDMatSubExpr.h:187
ResultType_t< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:98
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTDMatSubExpr.h:157
#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
Header file for all forward declarations for expression class templates.
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
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: DMatTDMatSubExpr.h:113
CompositeType_t< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:102
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
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTDMatSubExpr.h:299
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant alias template represents ...
Definition: IntegralConstant.h:110
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTDMatSubExpr.h:234
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:167
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
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTDMatSubExpr.h:156
ReturnType_t< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:101
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
Header file for the IntegralConstant class template.
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:103
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatSubExpr.h:309
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DMatTDMatSubExpr.h:161
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATSUBEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatSubExpr.h:103
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTDMatSubExpr.h:203
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.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:170