TSMatSMatSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATSMATSUBEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATSMATSUBEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
67 #include <blaze/util/Assert.h>
68 #include <blaze/util/DisableIf.h>
69 #include <blaze/util/EnableIf.h>
72 #include <blaze/util/mpl/If.h>
73 #include <blaze/util/Types.h>
76 #include <blaze/util/Unused.h>
77 
78 
79 namespace blaze {
80 
81 //=================================================================================================
82 //
83 // CLASS TSMATSMATSUBEXPR
84 //
85 //=================================================================================================
86 
87 //*************************************************************************************************
94 template< typename MT1 // Type of the left-hand side sparse matrix
95  , typename MT2 > // Type of the right-hand side sparse matrix
96 class TSMatSMatSubExpr
97  : public MatMatSubExpr< SparseMatrix< TSMatSMatSubExpr<MT1,MT2>, IsZero_v<MT2> > >
98  , private Computation
99 {
100  private:
101  //**Type definitions****************************************************************************
108  //**********************************************************************************************
109 
110  //**Return type evaluation**********************************************************************
112 
117  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
118 
120  using ExprReturnType = decltype( std::declval<RN1>() - std::declval<RN2>() );
121  //**********************************************************************************************
122 
123  //**Serial evaluation strategy******************************************************************
125 
130  template< typename T1, typename T2 >
131  static constexpr bool UseSymmetricKernel_v =
132  ( IsVoid_v< EnableIf_t< StorageOrder_v<T1> != StorageOrder_v<T2> > > && IsSymmetric_v<T2> );
134  //**********************************************************************************************
135 
136  //**Parallel evaluation strategy****************************************************************
138 
143  template< typename MT >
144  static constexpr bool UseSMPAssign_v = MT::smpAssignable;
146  //**********************************************************************************************
147 
148  public:
149  //**Type definitions****************************************************************************
152 
155 
160 
163 
165  using CompositeType = const ResultType;
166 
168  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
169 
171  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
172  //**********************************************************************************************
173 
174  //**Compilation flags***************************************************************************
176  static constexpr bool smpAssignable = false;
177  //**********************************************************************************************
178 
179  //**Constructor*********************************************************************************
185  explicit inline TSMatSMatSubExpr( const MT1& lhs, const MT2& rhs ) noexcept
186  : lhs_( lhs ) // Left-hand side sparse matrix of the subtraction expression
187  , rhs_( rhs ) // Right-hand side sparse matrix of the subtraction expression
188  {
189  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
190  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
191  }
192  //**********************************************************************************************
193 
194  //**Access operator*****************************************************************************
201  inline ReturnType operator()( size_t i, size_t j ) const {
202  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
203  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
204  return lhs_(i,j) - rhs_(i,j);
205  }
206  //**********************************************************************************************
207 
208  //**At function*********************************************************************************
216  inline ReturnType at( size_t i, size_t j ) const {
217  if( i >= lhs_.rows() ) {
218  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
219  }
220  if( j >= lhs_.columns() ) {
221  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
222  }
223  return (*this)(i,j);
224  }
225  //**********************************************************************************************
226 
227  //**Rows function*******************************************************************************
232  inline size_t rows() const noexcept {
233  return lhs_.rows();
234  }
235  //**********************************************************************************************
236 
237  //**Columns function****************************************************************************
242  inline size_t columns() const noexcept {
243  return lhs_.columns();
244  }
245  //**********************************************************************************************
246 
247  //**NonZeros function***************************************************************************
252  inline size_t nonZeros() const {
253  return lhs_.nonZeros() + rhs_.nonZeros();
254  }
255  //**********************************************************************************************
256 
257  //**NonZeros function***************************************************************************
263  inline size_t nonZeros( size_t i ) const {
264  return lhs_.nonZeros(i) + rhs_.nonZeros(i);
265  }
266  //**********************************************************************************************
267 
268  //**Left operand access*************************************************************************
273  inline LeftOperand leftOperand() const noexcept {
274  return lhs_;
275  }
276  //**********************************************************************************************
277 
278  //**Right operand access************************************************************************
283  inline RightOperand rightOperand() const noexcept {
284  return rhs_;
285  }
286  //**********************************************************************************************
287 
288  //**********************************************************************************************
294  template< typename T >
295  inline bool canAlias( const T* alias ) const noexcept {
296  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
297  }
298  //**********************************************************************************************
299 
300  //**********************************************************************************************
306  template< typename T >
307  inline bool isAliased( const T* alias ) const noexcept {
308  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
309  }
310  //**********************************************************************************************
311 
312  private:
313  //**Member variables****************************************************************************
316  //**********************************************************************************************
317 
318  //**Assignment to dense matrices****************************************************************
330  template< typename MT // Type of the target dense matrix
331  , bool SO > // Storage order of the target dense matrix
332  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
333  {
335 
336  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
337  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
338 
339  assign( ~lhs, rhs.lhs_ );
340 
341  if( !IsResizable_v< ElementType_t<MT> > ) {
342  subAssign( ~lhs, rhs.rhs_ );
343  }
344  else
345  {
346  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
347 
348  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
349  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
350  BLAZE_INTERNAL_ASSERT( B.rows() == (~lhs).rows() , "Invalid number of rows" );
351  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
352 
353  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
354  const auto end( B.end(i) );
355  for( auto element=B.begin(i); element!=end; ++element ) {
356  if( isDefault( (~lhs)(i,element->index()) ) )
357  (~lhs)(i,element->index()) = -element->value();
358  else
359  (~lhs)(i,element->index()) -= element->value();
360  }
361  }
362  }
363  }
365  //**********************************************************************************************
366 
367  //**Assignment to row-major sparse matrices*****************************************************
380  template< typename MT > // Type of the target sparse matrix
381  friend inline auto assign( SparseMatrix<MT,false>& lhs, const TSMatSMatSubExpr& rhs )
383  {
385 
386  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
387  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
388 
389  // Evaluation of the left-hand side sparse matrix operand
390  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
391 
392  // Evaluation of the right-hand side sparse matrix operand
393  CT2 B( serial( rhs.rhs_ ) );
394 
395  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
396  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
397  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
398  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
399  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
400  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
401 
402  // Final memory allocation (based on the evaluated operands)
403  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
404 
405  // Performing the matrix subtraction
406  for( size_t i=0UL; i<(~lhs).rows(); ++i )
407  {
408  const auto lend( A.end(i) );
409  const auto rend( B.end(i) );
410 
411  auto l( A.begin(i) );
412  auto r( B.begin(i) );
413 
414  while( l != lend && r != rend )
415  {
416  if( l->index() < r->index() ) {
417  (~lhs).append( i, l->index(), l->value() );
418  ++l;
419  }
420  else if( l->index() > r->index() ) {
421  (~lhs).append( i, r->index(), -r->value() );
422  ++r;
423  }
424  else {
425  (~lhs).append( i, l->index(), l->value() - r->value() );
426  ++l;
427  ++r;
428  }
429  }
430 
431  while( l != lend ) {
432  (~lhs).append( i, l->index(), l->value() );
433  ++l;
434  }
435 
436  while( r != rend ) {
437  (~lhs).append( i, r->index(), -r->value() );
438  ++r;
439  }
440 
441  (~lhs).finalize( i );
442  }
443  }
445  //**********************************************************************************************
446 
447  //**Assignment to row-major sparse matrices*****************************************************
460  template< typename MT > // Type of the target sparse matrix
461  friend inline auto assign( SparseMatrix<MT,false>& lhs, const TSMatSMatSubExpr& rhs )
462  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1> >
463  {
465 
466  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
467  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
468 
469  assign( ~lhs, trans( rhs.lhs_ ) - rhs.rhs_ );
470  }
472  //**********************************************************************************************
473 
474  //**Assignment to column-major sparse matrices**************************************************
487  template< typename MT > // Type of the target sparse matrix
488  friend inline auto assign( SparseMatrix<MT,true>& lhs, const TSMatSMatSubExpr& rhs )
489  -> DisableIf_t< UseSymmetricKernel_v<MT,MT2> >
490  {
492 
494 
495  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
496  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
497 
498  // Evaluation of the left-hand side sparse matrix operand
499  CT1 A( serial( rhs.lhs_ ) );
500 
501  // Evaluation of the right-hand side sparse matrix operand
502  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
503 
504  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
505  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
506  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
507  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
508  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
509  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
510 
511  // Final memory allocation (based on the evaluated operands)
512  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
513 
514  // Performing the matrix subtraction
515  for( size_t j=0UL; j<(~lhs).columns(); ++j )
516  {
517  const auto lend( A.end(j) );
518  const auto rend( B.end(j) );
519 
520  auto l( A.begin(j) );
521  auto r( B.begin(j) );
522 
523  while( l != lend && r != rend )
524  {
525  if( l->index() < r->index() ) {
526  (~lhs).append( l->index(), j, l->value() );
527  ++l;
528  }
529  else if( l->index() > r->index() ) {
530  (~lhs).append( r->index(), j, -r->value() );
531  ++r;
532  }
533  else {
534  (~lhs).append( l->index(), j, l->value() - r->value() );
535  ++l;
536  ++r;
537  }
538  }
539 
540  while( l != lend ) {
541  (~lhs).append( l->index(), j, l->value() );
542  ++l;
543  }
544 
545  while( r != rend ) {
546  (~lhs).append( r->index(), j, -r->value() );
547  ++r;
548  }
549 
550  (~lhs).finalize( j );
551  }
552  }
554  //**********************************************************************************************
555 
556  //**Assignment to column-major sparse matrices**************************************************
569  template< typename MT > // Type of the target sparse matrix
570  friend inline auto assign( SparseMatrix<MT,true>& lhs, const TSMatSMatSubExpr& rhs )
571  -> EnableIf_t< UseSymmetricKernel_v<MT,MT2> >
572  {
574 
576 
577  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
578  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
579 
580  assign( ~lhs, rhs.lhs_ - trans( rhs.rhs_ ) );
581  }
583  //**********************************************************************************************
584 
585  //**Addition assignment to dense matrices*******************************************************
598  template< typename MT // Type of the target dense matrix
599  , bool SO > // Storage order of the target dense matrix
600  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
601  {
603 
604  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
605  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
606 
607  addAssign( ~lhs, rhs.lhs_ );
608  subAssign( ~lhs, rhs.rhs_ );
609  }
611  //**********************************************************************************************
612 
613  //**Addition assignment to sparse matrices******************************************************
614  // No special implementation for the addition assignment to sparse matrices.
615  //**********************************************************************************************
616 
617  //**Subtraction assignment to dense matrices****************************************************
630  template< typename MT // Type of the target dense matrix
631  , bool SO > // Storage order of the target dense matrix
632  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
633  {
635 
636  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
637  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
638 
639  subAssign( ~lhs, rhs.lhs_ );
640  addAssign( ~lhs, rhs.rhs_ );
641  }
643  //**********************************************************************************************
644 
645  //**Subtraction assignment to sparse matrices***************************************************
646  // No special implementation for the subtraction assignment to sparse matrices.
647  //**********************************************************************************************
648 
649  //**Schur product assignment to dense matrices**************************************************
662  template< typename MT // Type of the target dense matrix
663  , bool SO > // Storage order of the target dense matrix
664  friend inline void schurAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
665  {
667 
670 
671  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
672  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
673 
674  const ResultType tmp( serial( rhs ) );
675  schurAssign( ~lhs, tmp );
676  }
678  //**********************************************************************************************
679 
680  //**Schur product assignment to sparse matrices*************************************************
681  // No special implementation for the Schur product assignment to sparse matrices.
682  //**********************************************************************************************
683 
684  //**Multiplication assignment to dense matrices*************************************************
685  // No special implementation for the multiplication assignment to dense matrices.
686  //**********************************************************************************************
687 
688  //**Multiplication assignment to sparse matrices************************************************
689  // No special implementation for the multiplication assignment to sparse matrices.
690  //**********************************************************************************************
691 
692  //**SMP assignment to dense matrices************************************************************
693  // No special implementation for the SMP assignment to dense matrices.
694  //**********************************************************************************************
695 
696  //**SMP assignment to sparse matrices***********************************************************
697  // No special implementation for the SMP assignment to sparse matrices.
698  //**********************************************************************************************
699 
700  //**SMP addition assignment to dense matrices*******************************************************
715  template< typename MT // Type of the target dense matrix
716  , bool SO > // Storage order of the target dense matrix
717  friend inline auto smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
718  -> EnableIf_t< UseSMPAssign_v<MT> >
719  {
721 
722  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
723  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
724 
725  smpAddAssign( ~lhs, rhs.lhs_ );
726  smpSubAssign( ~lhs, rhs.rhs_ );
727  }
729  //**********************************************************************************************
730 
731  //**SMP addition assignment to sparse matrices**************************************************
732  // No special implementation for the SMP addition assignment to sparse matrices.
733  //**********************************************************************************************
734 
735  //**SMP subtraction assignment to dense matrices************************************************
750  template< typename MT // Type of the target dense matrix
751  , bool SO > // Storage order of the target dense matrix
752  friend inline auto smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
753  -> EnableIf_t< UseSMPAssign_v<MT> >
754  {
756 
757  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
758  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
759 
760  smpSubAssign( ~lhs, rhs.lhs_ );
761  smpAddAssign( ~lhs, rhs.rhs_ );
762  }
764  //**********************************************************************************************
765 
766  //**SMP subtraction assignment to sparse matrices***********************************************
767  // No special implementation for the SMP subtraction assignment to sparse matrices.
768  //**********************************************************************************************
769 
770  //**SMP Schur product assignment to dense matrices**********************************************
785  template< typename MT // Type of the target dense matrix
786  , bool SO > // Storage order of the target dense matrix
787  friend inline auto smpSchurAssign( DenseMatrix<MT,SO>& lhs, const TSMatSMatSubExpr& rhs )
788  -> EnableIf_t< UseSMPAssign_v<MT> >
789  {
791 
794 
795  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
796  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
797 
798  const ResultType tmp( rhs );
799  smpSchurAssign( ~lhs, tmp );
800  }
802  //**********************************************************************************************
803 
804  //**SMP Schur product assignment to sparse matrices*********************************************
805  // No special implementation for the SMP Schur product assignment to sparse matrices.
806  //**********************************************************************************************
807 
808  //**SMP multiplication assignment to dense matrices*********************************************
809  // No special implementation for the SMP multiplication assignment to dense matrices.
810  //**********************************************************************************************
811 
812  //**SMP multiplication assignment to sparse matrices********************************************
813  // No special implementation for the SMP multiplication assignment to sparse matrices.
814  //**********************************************************************************************
815 
816  //**Compile time checks*************************************************************************
824  //**********************************************************************************************
825 };
826 //*************************************************************************************************
827 
828 
829 
830 
831 //=================================================================================================
832 //
833 // GLOBAL BINARY ARITHMETIC OPERATORS
834 //
835 //=================================================================================================
836 
837 //*************************************************************************************************
850 template< typename MT1 // Type of the left-hand side sparse matrix
851  , typename MT2 // Type of the right-hand side sparse matrix
852  , DisableIf_t< ( ( IsZero_v<MT1> || IsZero_v<MT2> ) &&
853  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
854  ( IsZero_v<MT1> && IsZero_v<MT2> ) >* = nullptr >
855 inline const TSMatSMatSubExpr<MT1,MT2>
856  tsmatsmatsub( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
857 {
859 
860  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
861  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
862 
863  return TSMatSMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
864 }
866 //*************************************************************************************************
867 
868 
869 //*************************************************************************************************
883 template< typename MT1 // Type of the left-hand side sparse matrix
884  , typename MT2 // Type of the right-hand side sparse matrix
885  , EnableIf_t< !IsZero_v<MT1> && IsZero_v<MT2> &&
886  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* = nullptr >
887 inline const MT1&
888  tsmatsmatsub( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
889 {
891 
892  UNUSED_PARAMETER( rhs );
893 
894  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
895  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
896 
897  return (~lhs);
898 }
900 //*************************************************************************************************
901 
902 
903 //*************************************************************************************************
917 template< typename MT1 // Type of the left-hand side sparse matrix
918  , typename MT2 // Type of the right-hand side sparse matrix
919  , EnableIf_t< IsZero_v<MT1> && !IsZero_v<MT2> &&
920  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* = nullptr >
921 inline decltype(auto)
922  tsmatsmatsub( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
923 {
925 
926  UNUSED_PARAMETER( lhs );
927 
928  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
929  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
930 
931  return -(~rhs);
932 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
950 template< typename MT1 // Type of the left-hand side sparse matrix
951  , typename MT2 // Type of the right-hand side sparse matrix
952  , EnableIf_t< IsZero_v<MT1> && IsZero_v<MT2> >* = nullptr >
953 inline decltype(auto)
954  tsmatsmatsub( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
955 {
957 
958  UNUSED_PARAMETER( rhs );
959 
960  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
961  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
962 
963  using ReturnType = const SubTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
964 
967 
968  return ReturnType( (~lhs).rows(), (~lhs).columns() );
969 }
971 //*************************************************************************************************
972 
973 
974 //*************************************************************************************************
1003 template< typename MT1 // Type of the left-hand side sparse matrix
1004  , typename MT2 > // Type of the right-hand side sparse matrix
1005 inline decltype(auto)
1006  operator-( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,false>& rhs )
1007 {
1009 
1010  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1011  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1012  }
1013 
1014  return tsmatsmatsub( ~lhs, ~rhs );
1015 }
1016 //*************************************************************************************************
1017 
1018 } // namespace blaze
1019 
1020 #endif
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
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatSMatSubExpr.h:232
Header file for auxiliary alias declarations.
typename SubTrait< T1, T2 >::Type SubTrait_t
Auxiliary alias declaration for the SubTrait class template.The SubTrait_t alias declaration provides...
Definition: SubTrait.h:238
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
Header file for basic type definitions.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: TSMatSMatSubExpr.h:283
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatSMatSubExpr.h:242
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatSMatSubExpr.h:307
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the serial shim.
Header file for the IsSame and IsStrictlySame type traits.
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatSMatSubExpr.h:157
Constraint on the data type.
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatSMatSubExpr.h:273
If_t< IsExpression_v< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:171
SubTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatSMatSubExpr.h:156
Header file for the Computation base class.
Constraints on the storage order of matrix types.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:137
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Header file for the IsVoid type trait.
Header file for the SparseMatrix base class.
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatSMatSubExpr.h:158
Constraint on the data type.
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:104
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the IsSymmetric type trait.
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.The IsResizable_v variable template provid...
Definition: IsResizable.h:134
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:105
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type...
Definition: Zero.h:61
TSMatSMatSubExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatSMatSubExpr class.
Definition: TSMatSMatSubExpr.h:185
#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 MatMatSubExpr base class.
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatSMatSubExpr.h:165
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatSMatSubExpr.h:295
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:106
Header file for the exception macros of the math module.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatSMatSubExpr.h:201
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatSMatSubExpr.h:263
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#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
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:103
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: TSMatSMatSubExpr.h:117
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: TSMatSMatSubExpr.h:162
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
Header file for the IsZero type trait.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for the isDefault shim.
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatSMatSubExpr.h:159
Constraint on the data type.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatSMatSubExpr.h:176
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
LeftOperand lhs_
Left-hand side sparse matrix of the subtraction expression.
Definition: TSMatSMatSubExpr.h:314
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:107
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Header file for the IsComputation type trait class.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatSMatSubExpr.h:216
If_t< IsExpression_v< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:168
Header file for the StorageOrder type trait.
Header file for the IntegralConstant class template.
decltype(std::declval< RN1 >() - std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: TSMatSMatSubExpr.h:120
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatSMatSubExpr.h:252
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATSUBEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatSubExpr.h:103
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
Expression object for transpose sparse matrix-sparse matrix subtractions.The TSMatSMatSubExpr class r...
Definition: Forward.h:175
Header file for the IsResizable type trait.
constexpr bool IsSame_v
Auxiliary variable template for the IsSame type trait.The IsSame_v variable template provides a conve...
Definition: IsSame.h:161
#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
RightOperand rhs_
Right-hand side sparse matrix of the subtraction expression.
Definition: TSMatSMatSubExpr.h:315
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatSMatSubExpr.h:102