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>
72 #include <blaze/system/Blocking.h>
74 #include <blaze/util/Assert.h>
75 #include <blaze/util/DisableIf.h>
76 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/mpl/And.h>
79 #include <blaze/util/mpl/If.h>
80 #include <blaze/util/mpl/Maximum.h>
81 #include <blaze/util/mpl/Not.h>
82 #include <blaze/util/Types.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS DMATTDMATSUBEXPR
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
100 template< typename MT1 // Type of the left-hand side dense matrix
101  , typename MT2 > // Type of the right-hand side dense matrix
103  : public MatMatSubExpr< DenseMatrix< DMatTDMatSubExpr<MT1,MT2>, false > >
104  , private Computation
105 {
106  private:
107  //**Type definitions****************************************************************************
114  //**********************************************************************************************
115 
116  //**Return type evaluation**********************************************************************
118 
123  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
124 
127  //**********************************************************************************************
128 
129  //**Serial evaluation strategy******************************************************************
131 
137  enum : bool { useAssign = RequiresEvaluation<MT1>::value || RequiresEvaluation<MT2>::value || !returnExpr };
138 
140  template< typename MT >
142  struct UseAssign {
143  enum : bool { value = useAssign };
144  };
146  //**********************************************************************************************
147 
148  //**Parallel evaluation strategy****************************************************************
150 
156  template< typename MT >
157  struct UseSMPAssign {
158  enum : bool { value = ( !MT1::smpAssignable || !MT2::smpAssignable ) && useAssign };
159  };
161  //**********************************************************************************************
162 
163  public:
164  //**Type definitions****************************************************************************
170 
173 
175  using CompositeType = const ResultType;
176 
178  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
179 
181  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
182  //**********************************************************************************************
183 
184  //**Compilation flags***************************************************************************
186  enum : bool { simdEnabled = false };
187 
189  enum : bool { smpAssignable = MT1::smpAssignable && MT2::smpAssignable };
190  //**********************************************************************************************
191 
192  //**Constructor*********************************************************************************
198  explicit inline DMatTDMatSubExpr( const MT1& lhs, const MT2& rhs ) noexcept
199  : lhs_( lhs ) // Left-hand side dense matrix of the subtraction expression
200  , rhs_( rhs ) // Right-hand side dense matrix of the subtraction expression
201  {
202  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
203  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
204  }
205  //**********************************************************************************************
206 
207  //**Access operator*****************************************************************************
214  inline ReturnType operator()( size_t i, size_t j ) const {
215  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
216  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
217  return lhs_(i,j) - rhs_(i,j);
218  }
219  //**********************************************************************************************
220 
221  //**At function*********************************************************************************
229  inline ReturnType at( size_t i, size_t j ) const {
230  if( i >= lhs_.rows() ) {
231  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
232  }
233  if( j >= lhs_.columns() ) {
234  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
235  }
236  return (*this)(i,j);
237  }
238  //**********************************************************************************************
239 
240  //**Rows function*******************************************************************************
245  inline size_t rows() const noexcept {
246  return lhs_.rows();
247  }
248  //**********************************************************************************************
249 
250  //**Columns function****************************************************************************
255  inline size_t columns() const noexcept {
256  return lhs_.columns();
257  }
258  //**********************************************************************************************
259 
260  //**Left operand access*************************************************************************
265  inline LeftOperand leftOperand() const noexcept {
266  return lhs_;
267  }
268  //**********************************************************************************************
269 
270  //**Right operand access************************************************************************
275  inline RightOperand rightOperand() const noexcept {
276  return rhs_;
277  }
278  //**********************************************************************************************
279 
280  //**********************************************************************************************
286  template< typename T >
287  inline bool canAlias( const T* alias ) const noexcept {
288  return ( IsExpression<MT1>::value && ( RequiresEvaluation<MT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
289  ( IsExpression<MT2>::value && ( RequiresEvaluation<MT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
290  }
291  //**********************************************************************************************
292 
293  //**********************************************************************************************
299  template< typename T >
300  inline bool isAliased( const T* alias ) const noexcept {
301  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
302  }
303  //**********************************************************************************************
304 
305  //**********************************************************************************************
310  inline bool isAligned() const noexcept {
311  return lhs_.isAligned() && rhs_.isAligned();
312  }
313  //**********************************************************************************************
314 
315  //**********************************************************************************************
320  inline bool canSMPAssign() const noexcept {
321  return lhs_.canSMPAssign() || rhs_.canSMPAssign() ||
322  ( rows() * columns() >= SMP_DMATTDMATSUB_THRESHOLD );
323  }
324  //**********************************************************************************************
325 
326  private:
327  //**Member variables****************************************************************************
330  //**********************************************************************************************
331 
332  //**Assignment to dense matrices****************************************************************
346  template< typename MT // Type of the target dense matrix
347  , bool SO > // Storage order of the target dense matrix
348  friend inline DisableIf_< UseAssign<MT> >
349  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
350  {
352 
353  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
354  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
355 
356  constexpr size_t block( BLOCK_SIZE );
357 
358  const size_t m( rhs.rows() );
359  const size_t n( rhs.columns() );
360 
361  for( size_t ii=0UL; ii<m; ii+=block ) {
362  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
363  for( size_t jj=0UL; jj<n; jj+=block ) {
364  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
365  for( size_t i=ii; i<iend; ++i ) {
366  for( size_t j=jj; j<jend; ++j ) {
367  (~lhs)(i,j) = rhs.lhs_(i,j) - rhs.rhs_(i,j);
368  }
369  }
370  }
371  }
372  }
374  //**********************************************************************************************
375 
376  //**Assignment to dense matrices****************************************************************
390  template< typename MT // Type of the target dense matrix
391  , bool SO > // Storage order of the target dense matrix
392  friend inline EnableIf_< UseAssign<MT> >
393  assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
394  {
396 
397  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
398  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
399 
400  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
401  subAssign( ~lhs, rhs.rhs_ );
402  }
403  else {
404  assign ( ~lhs, rhs.lhs_ );
405  subAssign( ~lhs, rhs.rhs_ );
406  }
407  }
409  //**********************************************************************************************
410 
411  //**Assignment to sparse matrices***************************************************************
423  template< typename MT // Type of the target sparse matrix
424  , bool SO > // Storage order of the target sparse matrix
425  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
426  {
428 
430 
437 
438  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
439  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
440 
441  const TmpType tmp( serial( rhs ) );
442  assign( ~lhs, tmp );
443  }
445  //**********************************************************************************************
446 
447  //**Addition assignment to dense matrices*******************************************************
462  template< typename MT // Type of the target dense matrix
463  , bool SO > // Storage order of the target dense matrix
464  friend inline DisableIf_< UseAssign<MT> >
465  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
466  {
468 
469  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
470  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
471 
472  constexpr size_t block( BLOCK_SIZE );
473 
474  const size_t m( rhs.rows() );
475  const size_t n( rhs.columns() );
476 
477  for( size_t ii=0UL; ii<m; ii+=block ) {
478  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
479  for( size_t jj=0UL; jj<n; jj+=block ) {
480  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
481  for( size_t i=ii; i<iend; ++i ) {
482  for( size_t j=jj; j<jend; ++j ) {
483  (~lhs)(i,j) += rhs.lhs_(i,j) - rhs.rhs_(i,j);
484  }
485  }
486  }
487  }
488  }
490  //**********************************************************************************************
491 
492  //**Addition assignment to dense matrices*******************************************************
507  template< typename MT // Type of the target dense matrix
508  , bool SO > // Storage order of the target dense matrix
509  friend inline EnableIf_< UseAssign<MT> >
510  addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
511  {
513 
514  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
515  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
516 
517  addAssign( ~lhs, rhs.lhs_ );
518  subAssign( ~lhs, rhs.rhs_ );
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 DisableIf_< UseAssign<MT> >
545  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
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 EnableIf_< UseAssign<MT> >
590  subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
591  {
593 
594  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
595  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
596 
597  subAssign( ~lhs, rhs.lhs_ );
598  addAssign( ~lhs, rhs.rhs_ );
599  }
601  //**********************************************************************************************
602 
603  //**Subtraction assignment to sparse matrices***************************************************
604  // No special implementation for the subtraction assignment to sparse matrices.
605  //**********************************************************************************************
606 
607  //**Schur product assignment to dense matrices**************************************************
622  template< typename MT // Type of the target dense matrix
623  , bool SO > // Storage order of the target dense matrix
624  friend inline EnableIf_< UseAssign<MT> >
625  schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
626  {
628 
632 
633  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
634  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
635 
636  const ResultType tmp( serial( rhs ) );
637  schurAssign( ~lhs, tmp );
638  }
640  //**********************************************************************************************
641 
642  //**Schur product assignment to sparse matrices*************************************************
643  // No special implementation for the Schur product assignment to sparse matrices.
644  //**********************************************************************************************
645 
646  //**Multiplication assignment to dense matrices*************************************************
647  // No special implementation for the multiplication assignment to dense matrices.
648  //**********************************************************************************************
649 
650  //**Multiplication assignment to sparse matrices************************************************
651  // No special implementation for the multiplication assignment to sparse matrices.
652  //**********************************************************************************************
653 
654  //**SMP assignment to dense matrices************************************************************
668  template< typename MT // Type of the target dense matrix
669  , bool SO > // Storage order of the target dense matrix
670  friend inline EnableIf_< UseSMPAssign<MT> >
671  smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatSubExpr& rhs )
672  {
674 
675  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
676  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
677 
678  if( !IsOperation<MT1>::value && isSame( ~lhs, rhs.lhs_ ) ) {
679  smpSubAssign( ~lhs, rhs.rhs_ );
680  }
681  else {
682  smpAssign ( ~lhs, rhs.lhs_ );
683  smpSubAssign( ~lhs, rhs.rhs_ );
684  }
685  }
687  //**********************************************************************************************
688 
689  //**SMP assignment to sparse matrices***********************************************************
703  template< typename MT // Type of the target sparse matrix
704  , bool SO > // Storage order of the target sparse matrix
705  friend inline EnableIf_< UseSMPAssign<MT> >
707  {
709 
711 
718 
719  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
720  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
721 
722  const TmpType tmp( rhs );
723  smpAssign( ~lhs, tmp );
724  }
726  //**********************************************************************************************
727 
728  //**SMP addition assignment to dense matrices***************************************************
743  template< typename MT // Type of the target dense matrix
744  , bool SO > // Storage order of the target dense matrix
745  friend inline EnableIf_< UseSMPAssign<MT> >
747  {
749 
750  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
751  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
752 
753  smpAddAssign( ~lhs, rhs.lhs_ );
754  smpSubAssign( ~lhs, rhs.rhs_ );
755  }
757  //**********************************************************************************************
758 
759  //**SMP addition assignment to sparse matrices**************************************************
760  // No special implementation for the SMP addition assignment to sparse matrices.
761  //**********************************************************************************************
762 
763  //**SMP subtraction assignment to dense matrices************************************************
778  template< typename MT // Type of the target dense matrix
779  , bool SO > // Storage order of the target dense matrix
780  friend inline EnableIf_< UseSMPAssign<MT> >
782  {
784 
785  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
786  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
787 
788  smpSubAssign( ~lhs, rhs.lhs_ );
789  smpAddAssign( ~lhs, rhs.rhs_ );
790  }
792  //**********************************************************************************************
793 
794  //**SMP subtraction assignment to sparse matrices***********************************************
795  // No special implementation for the SMP subtraction assignment to sparse matrices.
796  //**********************************************************************************************
797 
798  //**SMP Schur product assignment to dense matrices**********************************************
813  template< typename MT // Type of the target dense matrix
814  , bool SO > // Storage order of the target dense matrix
815  friend inline EnableIf_< UseSMPAssign<MT> >
817  {
819 
823 
824  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
825  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
826 
827  const ResultType tmp( rhs );
828  smpSchurAssign( ~lhs, tmp );
829  }
831  //**********************************************************************************************
832 
833  //**SMP Schur product assignment to sparse matrices*********************************************
834  // No special implementation for the SMP Schur product assignment to sparse matrices.
835  //**********************************************************************************************
836 
837  //**SMP multiplication assignment to dense matrices*********************************************
838  // No special implementation for the SMP multiplication assignment to dense matrices.
839  //**********************************************************************************************
840 
841  //**SMP multiplication assignment to sparse matrices********************************************
842  // No special implementation for the SMP multiplication assignment to sparse matrices.
843  //**********************************************************************************************
844 
845  //**Compile time checks*************************************************************************
852  //**********************************************************************************************
853 };
854 //*************************************************************************************************
855 
856 
857 
858 
859 //=================================================================================================
860 //
861 // GLOBAL BINARY ARITHMETIC OPERATORS
862 //
863 //=================================================================================================
864 
865 //*************************************************************************************************
878 template< typename MT1 // Type of the left-hand side dense matrix
879  , typename MT2 > // Type of the right-hand side dense matrix
880 inline const DMatTDMatSubExpr<MT1,MT2>
881  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
882  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
883 {
885 
886  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
887  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
888 
889  return DMatTDMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
890 }
892 //*************************************************************************************************
893 
894 
895 //*************************************************************************************************
908 template< typename MT1 // Type of the left-hand side dense matrix
909  , typename MT2 > // Type of the right-hand side dense matrix
910 inline decltype(auto)
911  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
912  EnableIf_< And< IsSymmetric<MT1>, Not< IsSymmetric<MT2> > > >* = nullptr )
913 {
915 
916  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
917  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
918 
919  return trans( ~lhs ) - ~rhs;
920 }
922 //*************************************************************************************************
923 
924 
925 //*************************************************************************************************
938 template< typename MT1 // Type of the left-hand side dense matrix
939  , typename MT2 > // Type of the right-hand side dense matrix
940 inline decltype(auto)
941  dmattdmatsub( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs,
942  EnableIf_< IsSymmetric<MT2> >* = nullptr )
943 {
945 
946  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
947  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
948 
949  return (~lhs) - trans( ~rhs );
950 }
952 //*************************************************************************************************
953 
954 
955 //*************************************************************************************************
984 template< typename MT1 // Type of the left-hand side dense matrix
985  , typename MT2 > // Type of the right-hand side dense matrix
986 inline decltype(auto)
987  operator-( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs )
988 {
990 
991  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
992  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
993  }
994 
995  return dmattdmatsub( ~lhs, ~rhs );
996 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1013 template< typename MT1 // Type of the left-hand side dense matrix
1014  , typename MT2 > // Type of the right-hand side dense matrix
1015 inline const DMatTDMatSubExpr<MT1,MT2>
1016  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1017  EnableIf_< And< Not< IsSymmetric<MT1> >, Not< IsSymmetric<MT2> > > >* = nullptr )
1018 {
1020 
1021  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1022  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1023 
1024  return DMatTDMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
1025 }
1027 //*************************************************************************************************
1028 
1029 
1030 //*************************************************************************************************
1043 template< typename MT1 // Type of the left-hand side dense matrix
1044  , typename MT2 > // Type of the right-hand side dense matrix
1045 inline decltype(auto)
1046  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1047  EnableIf_< And< Not< IsSymmetric<MT1> >, IsSymmetric<MT2> > >* = nullptr )
1048 {
1050 
1051  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1052  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1053 
1054  return (~lhs) - trans( ~rhs );
1055 }
1057 //*************************************************************************************************
1058 
1059 
1060 //*************************************************************************************************
1073 template< typename MT1 // Type of the left-hand side dense matrix
1074  , typename MT2 > // Type of the right-hand side dense matrix
1075 inline decltype(auto)
1076  tdmatdmatsub( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs,
1077  EnableIf_< IsSymmetric<MT1> >* = nullptr )
1078 {
1080 
1081  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1082  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1083 
1084  return trans( ~lhs ) - (~rhs);
1085 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1119 template< typename MT1 // Type of the left-hand side dense matrix
1120  , typename MT2 > // Type of the right-hand side dense matrix
1121 inline decltype(auto)
1122  operator-( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs )
1123 {
1125 
1126  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1127  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1128  }
1129 
1130  return tdmatdmatsub( ~lhs, ~rhs );
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 
1136 
1137 //=================================================================================================
1138 //
1139 // SIZE SPECIALIZATIONS
1140 //
1141 //=================================================================================================
1142 
1143 //*************************************************************************************************
1145 template< typename MT1, typename MT2 >
1146 struct Size< DMatTDMatSubExpr<MT1,MT2>, 0UL >
1147  : public Maximum< Size<MT1,0UL>, Size<MT2,0UL> >
1148 {};
1149 
1150 template< typename MT1, typename MT2 >
1151 struct Size< DMatTDMatSubExpr<MT1,MT2>, 1UL >
1152  : public Maximum< Size<MT1,1UL>, Size<MT2,1UL> >
1153 {};
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 And< IsAligned<MT1>, IsAligned<MT2> >
1171 {};
1173 //*************************************************************************************************
1174 
1175 
1176 
1177 
1178 //=================================================================================================
1179 //
1180 // ISSYMMETRIC SPECIALIZATIONS
1181 //
1182 //=================================================================================================
1183 
1184 //*************************************************************************************************
1186 template< typename MT1, typename MT2 >
1187 struct IsSymmetric< DMatTDMatSubExpr<MT1,MT2> >
1188  : public And< IsSymmetric<MT1>, IsSymmetric<MT2> >
1189 {};
1191 //*************************************************************************************************
1192 
1193 
1194 
1195 
1196 //=================================================================================================
1197 //
1198 // ISHERMITIAN SPECIALIZATIONS
1199 //
1200 //=================================================================================================
1201 
1202 //*************************************************************************************************
1204 template< typename MT1, typename MT2 >
1205 struct IsHermitian< DMatTDMatSubExpr<MT1,MT2> >
1206  : public And< IsHermitian<MT1>, IsHermitian<MT2> >
1207 {};
1209 //*************************************************************************************************
1210 
1211 
1212 
1213 
1214 //=================================================================================================
1215 //
1216 // ISLOWER SPECIALIZATIONS
1217 //
1218 //=================================================================================================
1219 
1220 //*************************************************************************************************
1222 template< typename MT1, typename MT2 >
1223 struct IsLower< DMatTDMatSubExpr<MT1,MT2> >
1224  : public And< IsLower<MT1>, IsLower<MT2> >
1225 {};
1227 //*************************************************************************************************
1228 
1229 
1230 
1231 
1232 //=================================================================================================
1233 //
1234 // ISUNILOWER SPECIALIZATIONS
1235 //
1236 //=================================================================================================
1237 
1238 //*************************************************************************************************
1240 template< typename MT1, typename MT2 >
1241 struct IsUniLower< DMatTDMatSubExpr<MT1,MT2> >
1242  : public And< IsUniLower<MT1>, IsStrictlyLower<MT2> >
1243 {};
1245 //*************************************************************************************************
1246 
1247 
1248 
1249 
1250 //=================================================================================================
1251 //
1252 // ISSTRICTLYLOWER SPECIALIZATIONS
1253 //
1254 //=================================================================================================
1255 
1256 //*************************************************************************************************
1258 template< typename MT1, typename MT2 >
1259 struct IsStrictlyLower< DMatTDMatSubExpr<MT1,MT2> >
1260  : public And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >
1261 {};
1263 //*************************************************************************************************
1264 
1265 
1266 
1267 
1268 //=================================================================================================
1269 //
1270 // ISUPPER SPECIALIZATIONS
1271 //
1272 //=================================================================================================
1273 
1274 //*************************************************************************************************
1276 template< typename MT1, typename MT2 >
1277 struct IsUpper< DMatTDMatSubExpr<MT1,MT2> >
1278  : public And< IsUpper<MT1>, IsUpper<MT2> >
1279 {};
1281 //*************************************************************************************************
1282 
1283 
1284 
1285 
1286 //=================================================================================================
1287 //
1288 // ISUNIUPPER SPECIALIZATIONS
1289 //
1290 //=================================================================================================
1291 
1292 //*************************************************************************************************
1294 template< typename MT1, typename MT2 >
1295 struct IsUniUpper< DMatTDMatSubExpr<MT1,MT2> >
1296  : public And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >
1297 {};
1299 //*************************************************************************************************
1300 
1301 
1302 
1303 
1304 //=================================================================================================
1305 //
1306 // ISSTRICTLYUPPER SPECIALIZATIONS
1307 //
1308 //=================================================================================================
1309 
1310 //*************************************************************************************************
1312 template< typename MT1, typename MT2 >
1313 struct IsStrictlyUpper< DMatTDMatSubExpr<MT1,MT2> >
1314  : public And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >
1315 {};
1317 //*************************************************************************************************
1318 
1319 } // namespace blaze
1320 
1321 #endif
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTDMatSubExpr.h:287
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:275
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:229
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatTDMatSubExpr.h:175
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
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:949
Header file for basic type definitions.
Compile time check whether the given type is an operational expression template.This type trait class...
Definition: IsOperation.h:70
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
SubExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: DMatTDMatSubExpr.h:126
#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:108
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:178
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
LeftOperand lhs_
Left-hand side dense matrix of the subtraction expression.
Definition: DMatTDMatSubExpr.h:328
Header file for the Computation base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
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:111
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
ReturnType_< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:110
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:71
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTDMatSubExpr.h:265
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:102
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: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:300
#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:168
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the DenseMatrix base class.
Header file for the Not class template.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
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:329
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:167
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:166
#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:255
CompositeType_< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:113
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatSubExpr.h:181
Header file for run time assertion macros.
DMatTDMatSubExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the DMatTDMatSubExpr class.
Definition: DMatTDMatSubExpr.h:198
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:816
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTDMatSubExpr.h:310
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTDMatSubExpr.h:245
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:112
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
ElementType_< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatSubExpr.h:169
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:291
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatSubExpr.h:320
Compile time logical &#39;and&#39; evaluation.The And alias declaration performs at compile time a logical &#39;a...
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:107
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTDMatSubExpr.h:214
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:109
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:172
Header file for the Size type trait.
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.