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 <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/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS DMATTDMATSUBEXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename MT1 // Type of the left-hand side dense matrix
103  , typename MT2 > // Type of the right-hand side dense matrix
105  : public MatMatSubExpr< DenseMatrix< DMatTDMatSubExpr<MT1,MT2>, false > >
106  , private Computation
107 {
108  private:
109  //**Type definitions****************************************************************************
116  //**********************************************************************************************
117 
118  //**Return type evaluation**********************************************************************
120 
125  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
126 
129  //**********************************************************************************************
130 
131  //**Serial evaluation strategy******************************************************************
133 
139  enum : bool { useAssign = RequiresEvaluation<MT1>::value || RequiresEvaluation<MT2>::value || !returnExpr };
140 
142  template< typename MT >
144  struct UseAssign {
145  enum : bool { value = useAssign };
146  };
148  //**********************************************************************************************
149 
150  //**Parallel evaluation strategy****************************************************************
152 
158  template< typename MT >
159  struct UseSMPAssign {
160  enum : bool { value = ( !MT1::smpAssignable || !MT2::smpAssignable ) && useAssign };
161  };
163  //**********************************************************************************************
164 
165  public:
166  //**Type definitions****************************************************************************
172 
175 
177  using CompositeType = const ResultType;
178 
180  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
181 
183  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
184  //**********************************************************************************************
185 
186  //**Compilation flags***************************************************************************
188  enum : bool { simdEnabled = false };
189 
191  enum : bool { smpAssignable = MT1::smpAssignable && MT2::smpAssignable };
192  //**********************************************************************************************
193 
194  //**Constructor*********************************************************************************
200  explicit inline DMatTDMatSubExpr( const MT1& lhs, const MT2& rhs ) noexcept
201  : lhs_( lhs ) // Left-hand side dense matrix of the subtraction expression
202  , rhs_( rhs ) // Right-hand side dense matrix of the subtraction expression
203  {
204  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
205  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
206  }
207  //**********************************************************************************************
208 
209  //**Access operator*****************************************************************************
216  inline ReturnType operator()( size_t i, size_t j ) const {
217  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
218  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
219  return lhs_(i,j) - rhs_(i,j);
220  }
221  //**********************************************************************************************
222 
223  //**At function*********************************************************************************
231  inline ReturnType at( size_t i, size_t j ) const {
232  if( i >= lhs_.rows() ) {
233  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
234  }
235  if( j >= lhs_.columns() ) {
236  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
237  }
238  return (*this)(i,j);
239  }
240  //**********************************************************************************************
241 
242  //**Rows function*******************************************************************************
247  inline size_t rows() const noexcept {
248  return lhs_.rows();
249  }
250  //**********************************************************************************************
251 
252  //**Columns function****************************************************************************
257  inline size_t columns() const noexcept {
258  return lhs_.columns();
259  }
260  //**********************************************************************************************
261 
262  //**Left operand access*************************************************************************
267  inline LeftOperand leftOperand() const noexcept {
268  return lhs_;
269  }
270  //**********************************************************************************************
271 
272  //**Right operand access************************************************************************
277  inline RightOperand rightOperand() const noexcept {
278  return rhs_;
279  }
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
288  template< typename T >
289  inline bool canAlias( const T* alias ) const noexcept {
290  return ( IsExpression<MT1>::value && ( RequiresEvaluation<MT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
291  ( IsExpression<MT2>::value && ( RequiresEvaluation<MT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
292  }
293  //**********************************************************************************************
294 
295  //**********************************************************************************************
301  template< typename T >
302  inline bool isAliased( const T* alias ) const noexcept {
303  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
304  }
305  //**********************************************************************************************
306 
307  //**********************************************************************************************
312  inline bool isAligned() const noexcept {
313  return lhs_.isAligned() && rhs_.isAligned();
314  }
315  //**********************************************************************************************
316 
317  //**********************************************************************************************
322  inline bool canSMPAssign() const noexcept {
323  return lhs_.canSMPAssign() || rhs_.canSMPAssign() ||
324  ( rows() * columns() >= SMP_DMATTDMATSUB_THRESHOLD );
325  }
326  //**********************************************************************************************
327 
328  private:
329  //**Member variables****************************************************************************
332  //**********************************************************************************************
333 
334  //**Assignment to dense matrices****************************************************************
348  template< typename MT // Type of the target dense matrix
349  , bool SO > // Storage order of the target dense matrix
350  friend inline DisableIf_< UseAssign<MT> >
351  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
352  {
354 
355  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
356  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
357 
358  constexpr size_t block( BLOCK_SIZE );
359 
360  const size_t m( rhs.rows() );
361  const size_t n( rhs.columns() );
362 
363  for( size_t ii=0UL; ii<m; ii+=block ) {
364  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
365  for( size_t jj=0UL; jj<n; jj+=block ) {
366  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
367  for( size_t i=ii; i<iend; ++i ) {
368  for( size_t j=jj; j<jend; ++j ) {
369  (~lhs)(i,j) = rhs.lhs_(i,j) - rhs.rhs_(i,j);
370  }
371  }
372  }
373  }
374  }
376  //**********************************************************************************************
377 
378  //**Assignment to dense matrices****************************************************************
392  template< typename MT // Type of the target dense matrix
393  , bool SO > // Storage order of the target dense matrix
394  friend inline EnableIf_< UseAssign<MT> >
395  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
396  {
398 
399  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
400  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
401 
402  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
403  subAssign( ~lhs, rhs.rhs_ );
404  }
405  else {
406  assign ( ~lhs, rhs.lhs_ );
407  subAssign( ~lhs, rhs.rhs_ );
408  }
409  }
411  //**********************************************************************************************
412 
413  //**Assignment to sparse matrices***************************************************************
425  template< typename MT // Type of the target sparse matrix
426  , bool SO > // Storage order of the target sparse matrix
427  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
428  {
430 
432 
439 
440  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
441  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
442 
443  const TmpType tmp( serial( rhs ) );
444  assign( ~lhs, tmp );
445  }
447  //**********************************************************************************************
448 
449  //**Addition assignment to dense matrices*******************************************************
464  template< typename MT // Type of the target dense matrix
465  , bool SO > // Storage order of the target dense matrix
466  friend inline DisableIf_< UseAssign<MT> >
467  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
468  {
470 
471  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
472  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
473 
474  constexpr size_t block( BLOCK_SIZE );
475 
476  const size_t m( rhs.rows() );
477  const size_t n( rhs.columns() );
478 
479  for( size_t ii=0UL; ii<m; ii+=block ) {
480  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
481  for( size_t jj=0UL; jj<n; jj+=block ) {
482  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
483  for( size_t i=ii; i<iend; ++i ) {
484  for( size_t j=jj; j<jend; ++j ) {
485  (~lhs)(i,j) += rhs.lhs_(i,j) - rhs.rhs_(i,j);
486  }
487  }
488  }
489  }
490  }
492  //**********************************************************************************************
493 
494  //**Addition assignment to dense matrices*******************************************************
509  template< typename MT // Type of the target dense matrix
510  , bool SO > // Storage order of the target dense matrix
511  friend inline EnableIf_< UseAssign<MT> >
512  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
513  {
515 
516  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
517  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
518 
519  addAssign( ~lhs, rhs.lhs_ );
520  subAssign( ~lhs, rhs.rhs_ );
521  }
523  //**********************************************************************************************
524 
525  //**Addition assignment to sparse matrices******************************************************
526  // No special implementation for the addition assignment to sparse matrices.
527  //**********************************************************************************************
528 
529  //**Subtraction assignment to dense matrices****************************************************
544  template< typename MT // Type of the target dense matrix
545  , bool SO > // Storage order of the target dense matrix
546  friend inline DisableIf_< UseAssign<MT> >
547  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
548  {
550 
551  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
552  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
553 
554  constexpr size_t block( BLOCK_SIZE );
555 
556  const size_t m( rhs.rows() );
557  const size_t n( rhs.columns() );
558 
559  for( size_t ii=0UL; ii<m; ii+=block ) {
560  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
561  for( size_t jj=0UL; jj<n; jj+=block ) {
562  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
563  for( size_t i=ii; i<iend; ++i ) {
564  for( size_t j=jj; j<jend; ++j ) {
565  (~lhs)(i,j) -= rhs.lhs_(i,j) - rhs.rhs_(i,j);
566  }
567  }
568  }
569  }
570  }
572  //**********************************************************************************************
573 
574  //**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 DMatTDMatSubExpr& 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  addAssign( ~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 EnableIf_< UseAssign<MT> >
627  schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& 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 DMatTDMatSubExpr& 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  smpSubAssign( ~lhs, rhs.rhs_ );
682  }
683  else {
684  smpAssign ( ~lhs, rhs.lhs_ );
685  smpSubAssign( ~lhs, rhs.rhs_ );
686  }
687  }
689  //**********************************************************************************************
690 
691  //**SMP assignment to sparse matrices***********************************************************
705  template< typename MT // Type of the target sparse matrix
706  , bool SO > // Storage order of the target sparse matrix
707  friend inline EnableIf_< UseSMPAssign<MT> >
709  {
711 
713 
720 
721  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
722  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
723 
724  const TmpType tmp( rhs );
725  smpAssign( ~lhs, tmp );
726  }
728  //**********************************************************************************************
729 
730  //**SMP addition assignment to dense matrices***************************************************
745  template< typename MT // Type of the target dense matrix
746  , bool SO > // Storage order of the target dense matrix
747  friend inline EnableIf_< UseSMPAssign<MT> >
749  {
751 
752  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
753  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
754 
755  smpAddAssign( ~lhs, rhs.lhs_ );
756  smpSubAssign( ~lhs, rhs.rhs_ );
757  }
759  //**********************************************************************************************
760 
761  //**SMP addition assignment to sparse matrices**************************************************
762  // No special implementation for the SMP addition assignment to sparse matrices.
763  //**********************************************************************************************
764 
765  //**SMP subtraction assignment to dense matrices************************************************
780  template< typename MT // Type of the target dense matrix
781  , bool SO > // Storage order of the target dense matrix
782  friend inline EnableIf_< UseSMPAssign<MT> >
784  {
786 
787  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
788  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
789 
790  smpSubAssign( ~lhs, rhs.lhs_ );
791  smpAddAssign( ~lhs, rhs.rhs_ );
792  }
794  //**********************************************************************************************
795 
796  //**SMP subtraction assignment to sparse matrices***********************************************
797  // No special implementation for the SMP subtraction assignment to sparse matrices.
798  //**********************************************************************************************
799 
800  //**SMP Schur product assignment to dense matrices**********************************************
815  template< typename MT // Type of the target dense matrix
816  , bool SO > // Storage order of the target dense matrix
817  friend inline EnableIf_< UseSMPAssign<MT> >
819  {
821 
825 
826  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
827  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
828 
829  const ResultType tmp( rhs );
830  smpSchurAssign( ~lhs, tmp );
831  }
833  //**********************************************************************************************
834 
835  //**SMP Schur product assignment to sparse matrices*********************************************
836  // No special implementation for the SMP Schur product assignment to sparse matrices.
837  //**********************************************************************************************
838 
839  //**SMP multiplication assignment to dense matrices*********************************************
840  // No special implementation for the SMP multiplication assignment to dense matrices.
841  //**********************************************************************************************
842 
843  //**SMP multiplication assignment to sparse matrices********************************************
844  // No special implementation for the SMP multiplication assignment to sparse matrices.
845  //**********************************************************************************************
846 
847  //**Compile time checks*************************************************************************
854  //**********************************************************************************************
855 };
856 //*************************************************************************************************
857 
858 
859 
860 
861 //=================================================================================================
862 //
863 // GLOBAL BINARY ARITHMETIC OPERATORS
864 //
865 //=================================================================================================
866 
867 //*************************************************************************************************
880 template< typename MT1 // Type of the left-hand side dense matrix
881  , typename MT2 > // Type of the right-hand side dense matrix
882 inline const DMatTDMatSubExpr<MT1,MT2>
883  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
884  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
885 {
887 
888  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
889  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
890 
891  return DMatTDMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
892 }
894 //*************************************************************************************************
895 
896 
897 //*************************************************************************************************
910 template< typename MT1 // Type of the left-hand side dense matrix
911  , typename MT2 > // Type of the right-hand side dense matrix
912 inline decltype(auto)
913  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
914  EnableIf_< And< IsSymmetric<MT1>, Not< IsSymmetric<MT2> > > >* = nullptr )
915 {
917 
918  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
919  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
920 
921  return trans( ~lhs ) - ~rhs;
922 }
924 //*************************************************************************************************
925 
926 
927 //*************************************************************************************************
940 template< typename MT1 // Type of the left-hand side dense matrix
941  , typename MT2 > // Type of the right-hand side dense matrix
942 inline decltype(auto)
943  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
944  EnableIf_< IsSymmetric<MT2> >* = nullptr )
945 {
947 
948  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
949  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
950 
951  return (~lhs) - trans( ~rhs );
952 }
954 //*************************************************************************************************
955 
956 
957 //*************************************************************************************************
986 template< typename MT1 // Type of the left-hand side dense matrix
987  , typename MT2 > // Type of the right-hand side dense matrix
988 inline decltype(auto)
989  operator-( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
990 {
992 
993  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
994  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
995  }
996 
997  return dmattdmatsub( ~lhs, ~rhs );
998 }
999 //*************************************************************************************************
1000 
1001 
1002 //*************************************************************************************************
1015 template< typename MT1 // Type of the left-hand side dense matrix
1016  , typename MT2 > // Type of the right-hand side dense matrix
1017 inline const DMatTDMatSubExpr<MT1,MT2>
1018  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1019  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
1020 {
1022 
1023  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1024  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1025 
1026  return DMatTDMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
1027 }
1029 //*************************************************************************************************
1030 
1031 
1032 //*************************************************************************************************
1045 template< typename MT1 // Type of the left-hand side dense matrix
1046  , typename MT2 > // Type of the right-hand side dense matrix
1047 inline decltype(auto)
1048  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1049  EnableIf_< And< Not< IsSymmetric<MT1> >, IsSymmetric<MT2> > >* = nullptr )
1050 {
1052 
1053  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1054  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1055 
1056  return (~lhs) - trans( ~rhs );
1057 }
1059 //*************************************************************************************************
1060 
1061 
1062 //*************************************************************************************************
1075 template< typename MT1 // Type of the left-hand side dense matrix
1076  , typename MT2 > // Type of the right-hand side dense matrix
1077 inline decltype(auto)
1078  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1079  EnableIf_< IsSymmetric<MT1> >* = nullptr )
1080 {
1082 
1083  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1084  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1085 
1086  return trans( ~lhs ) - (~rhs);
1087 }
1089 //*************************************************************************************************
1090 
1091 
1092 //*************************************************************************************************
1121 template< typename MT1 // Type of the left-hand side dense matrix
1122  , typename MT2 > // Type of the right-hand side dense matrix
1123 inline decltype(auto)
1124  operator-( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1125 {
1127 
1128  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1129  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1130  }
1131 
1132  return tdmatdmatsub( ~lhs, ~rhs );
1133 }
1134 //*************************************************************************************************
1135 
1136 
1137 
1138 
1139 //=================================================================================================
1140 //
1141 // ROWS SPECIALIZATIONS
1142 //
1143 //=================================================================================================
1144 
1145 //*************************************************************************************************
1147 template< typename MT1, typename MT2 >
1148 struct Rows< DMatTDMatSubExpr<MT1,MT2> >
1149  : public Maximum< Rows<MT1>, Rows<MT2> >
1150 {};
1152 //*************************************************************************************************
1153 
1154 
1155 
1156 
1157 //=================================================================================================
1158 //
1159 // COLUMNS SPECIALIZATIONS
1160 //
1161 //=================================================================================================
1162 
1163 //*************************************************************************************************
1165 template< typename MT1, typename MT2 >
1166 struct Columns< DMatTDMatSubExpr<MT1,MT2> >
1167  : public Maximum< Columns<MT1>, Columns<MT2> >
1168 {};
1170 //*************************************************************************************************
1171 
1172 
1173 
1174 
1175 //=================================================================================================
1176 //
1177 // ISALIGNED SPECIALIZATIONS
1178 //
1179 //=================================================================================================
1180 
1181 //*************************************************************************************************
1183 template< typename MT1, typename MT2 >
1184 struct IsAligned< DMatTDMatSubExpr<MT1,MT2> >
1185  : public BoolConstant< And< IsAligned<MT1>, IsAligned<MT2> >::value >
1186 {};
1188 //*************************************************************************************************
1189 
1190 
1191 
1192 
1193 //=================================================================================================
1194 //
1195 // ISSYMMETRIC SPECIALIZATIONS
1196 //
1197 //=================================================================================================
1198 
1199 //*************************************************************************************************
1201 template< typename MT1, typename MT2 >
1202 struct IsSymmetric< DMatTDMatSubExpr<MT1,MT2> >
1203  : public BoolConstant< IsSymmetric<MT1>::value && IsSymmetric<MT2>::value >
1204 {};
1206 //*************************************************************************************************
1207 
1208 
1209 
1210 
1211 //=================================================================================================
1212 //
1213 // ISHERMITIAN SPECIALIZATIONS
1214 //
1215 //=================================================================================================
1216 
1217 //*************************************************************************************************
1219 template< typename MT1, typename MT2 >
1220 struct IsHermitian< DMatTDMatSubExpr<MT1,MT2> >
1221  : public BoolConstant< IsHermitian<MT1>::value && IsHermitian<MT2>::value >
1222 {};
1224 //*************************************************************************************************
1225 
1226 
1227 
1228 
1229 //=================================================================================================
1230 //
1231 // ISLOWER SPECIALIZATIONS
1232 //
1233 //=================================================================================================
1234 
1235 //*************************************************************************************************
1237 template< typename MT1, typename MT2 >
1238 struct IsLower< DMatTDMatSubExpr<MT1,MT2> >
1239  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
1240 {};
1242 //*************************************************************************************************
1243 
1244 
1245 
1246 
1247 //=================================================================================================
1248 //
1249 // ISUNILOWER SPECIALIZATIONS
1250 //
1251 //=================================================================================================
1252 
1253 //*************************************************************************************************
1255 template< typename MT1, typename MT2 >
1256 struct IsUniLower< DMatTDMatSubExpr<MT1,MT2> >
1257  : public BoolConstant< And< IsUniLower<MT1>, IsStrictlyLower<MT2> >::value >
1258 {};
1260 //*************************************************************************************************
1261 
1262 
1263 
1264 
1265 //=================================================================================================
1266 //
1267 // ISSTRICTLYLOWER SPECIALIZATIONS
1268 //
1269 //=================================================================================================
1270 
1271 //*************************************************************************************************
1273 template< typename MT1, typename MT2 >
1274 struct IsStrictlyLower< DMatTDMatSubExpr<MT1,MT2> >
1275  : public BoolConstant< And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >::value >
1276 {};
1278 //*************************************************************************************************
1279 
1280 
1281 
1282 
1283 //=================================================================================================
1284 //
1285 // ISUPPER SPECIALIZATIONS
1286 //
1287 //=================================================================================================
1288 
1289 //*************************************************************************************************
1291 template< typename MT1, typename MT2 >
1292 struct IsUpper< DMatTDMatSubExpr<MT1,MT2> >
1293  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
1294 {};
1296 //*************************************************************************************************
1297 
1298 
1299 
1300 
1301 //=================================================================================================
1302 //
1303 // ISUNIUPPER SPECIALIZATIONS
1304 //
1305 //=================================================================================================
1306 
1307 //*************************************************************************************************
1309 template< typename MT1, typename MT2 >
1310 struct IsUniUpper< DMatTDMatSubExpr<MT1,MT2> >
1311  : public BoolConstant< And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >::value >
1312 {};
1314 //*************************************************************************************************
1315 
1316 
1317 
1318 
1319 //=================================================================================================
1320 //
1321 // ISSTRICTLYUPPER SPECIALIZATIONS
1322 //
1323 //=================================================================================================
1324 
1325 //*************************************************************************************************
1327 template< typename MT1, typename MT2 >
1328 struct IsStrictlyUpper< DMatTDMatSubExpr<MT1,MT2> >
1329  : public BoolConstant< And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >::value >
1330 {};
1332 //*************************************************************************************************
1333 
1334 } // namespace blaze
1335 
1336 #endif
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTDMatSubExpr.h:289
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:277
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:231
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTDMatSubExpr.h:177
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.
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
Header file for the subtraction trait.
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.
SubExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DMatTDMatSubExpr.h:128
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
ResultType_< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:110
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
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
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:180
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
LeftOperand lhs_
Left-hand side dense matrix of the subtraction expression.
Definition: DMatTDMatSubExpr.h:330
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
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
ReturnType_< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:113
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
ReturnType_< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:112
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
typename SubExprTrait< T1, T2 >::Type SubExprTrait_
Auxiliary alias declaration for the SubExprTrait class template.The SubExprTrait_ alias declaration p...
Definition: SubExprTrait.h:112
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
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTDMatSubExpr.h:267
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
Expression object for dense matrix-transpose dense matrix subtractions.The DMatTDMatSubExpr class rep...
Definition: DMatTDMatSubExpr.h:104
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.
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:57
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:302
#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
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
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTDMatSubExpr.h:170
#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
Header file for the MatMatSubExpr base class.
Header file for the IsOperation type trait class.
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
RightOperand rhs_
Right-hand side dense matrix of the subtraction expression.
Definition: DMatTDMatSubExpr.h:331
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
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
Constraint on the data type.
Header file for all forward declarations for expression class templates.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTDMatSubExpr.h:169
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
#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
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
SubTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DMatTDMatSubExpr.h:168
#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:257
CompositeType_< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:115
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:183
Header file for run time assertion macros.
DMatTDMatSubExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTDMatSubExpr class.
Definition: DMatTDMatSubExpr.h:200
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
#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
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTDMatSubExpr.h:312
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTDMatSubExpr.h:247
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
CompositeType_< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:114
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
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatSubExpr.h:171
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
typename SubTrait< T1, T2 >::Type SubTrait_
Auxiliary alias declaration for the SubTrait class template.The SubTrait_ alias declaration provides ...
Definition: SubTrait.h:250
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
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatSubExpr.h:322
Compile time logical and evaluation.The And alias declaration performs at compile time a logical and ...
Definition: And.h:76
#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:108
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTDMatSubExpr.h:216
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.
ResultType_< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:111
Header file for the IsHermitian type trait.
Header file for the SubExprTrait class template.
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DMatTDMatSubExpr.h:174
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, 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.