Blaze  3.6
SMatTSMatSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTSMATSUBEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTSMATSUBEXPR_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/MaybeUnused.h>
73 #include <blaze/util/mpl/If.h>
74 #include <blaze/util/Types.h>
76 
77 
78 namespace blaze {
79 
80 //=================================================================================================
81 //
82 // CLASS SMATTSMATSUBEXPR
83 //
84 //=================================================================================================
85 
86 //*************************************************************************************************
93 template< typename MT1 // Type of the left-hand side sparse matrix
94  , typename MT2 > // Type of the right-hand side sparse matrix
95 class SMatTSMatSubExpr
96  : public MatMatSubExpr< SparseMatrix< SMatTSMatSubExpr<MT1,MT2>, IsZero_v<MT1> > >
97  , private Computation
98 {
99  private:
100  //**Type definitions****************************************************************************
107  //**********************************************************************************************
108 
109  //**Return type evaluation**********************************************************************
111 
116  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
117 
119  using ExprReturnType = decltype( std::declval<RN1>() - std::declval<RN2>() );
120  //**********************************************************************************************
121 
122  //**Serial evaluation strategy******************************************************************
124 
129  template< typename T1, typename T2 >
130  static constexpr bool UseSymmetricKernel_v =
131  ( ( StorageOrder_v<T1> != StorageOrder_v<T2> ) && IsSymmetric_v<T2> );
133  //**********************************************************************************************
134 
135  //**Parallel evaluation strategy****************************************************************
137 
142  template< typename MT >
143  static constexpr bool UseSMPAssign_v = MT::smpAssignable;
145  //**********************************************************************************************
146 
147  public:
148  //**Type definitions****************************************************************************
151 
154 
159 
162 
164  using CompositeType = const ResultType;
165 
167  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
168 
170  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
171  //**********************************************************************************************
172 
173  //**Compilation flags***************************************************************************
175  static constexpr bool smpAssignable = false;
176  //**********************************************************************************************
177 
178  //**Constructor*********************************************************************************
184  explicit inline SMatTSMatSubExpr( const MT1& lhs, const MT2& rhs ) noexcept
185  : lhs_( lhs ) // Left-hand side sparse matrix of the subtraction expression
186  , rhs_( rhs ) // Right-hand side sparse matrix of the subtraction expression
187  {
188  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
189  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
190  }
191  //**********************************************************************************************
192 
193  //**Access operator*****************************************************************************
200  inline ReturnType operator()( size_t i, size_t j ) const {
201  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
202  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
203  return lhs_(i,j) - rhs_(i,j);
204  }
205  //**********************************************************************************************
206 
207  //**At function*********************************************************************************
215  inline ReturnType at( size_t i, size_t j ) const {
216  if( i >= lhs_.rows() ) {
217  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
218  }
219  if( j >= lhs_.columns() ) {
220  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
221  }
222  return (*this)(i,j);
223  }
224  //**********************************************************************************************
225 
226  //**Rows function*******************************************************************************
231  inline size_t rows() const noexcept {
232  return lhs_.rows();
233  }
234  //**********************************************************************************************
235 
236  //**Columns function****************************************************************************
241  inline size_t columns() const noexcept {
242  return lhs_.columns();
243  }
244  //**********************************************************************************************
245 
246  //**NonZeros function***************************************************************************
251  inline size_t nonZeros() const {
252  return lhs_.nonZeros() + rhs_.nonZeros();
253  }
254  //**********************************************************************************************
255 
256  //**NonZeros function***************************************************************************
262  inline size_t nonZeros( size_t i ) const {
263  return lhs_.nonZeros(i) + rhs_.nonZeros(i);
264  }
265  //**********************************************************************************************
266 
267  //**Left operand access*************************************************************************
272  inline LeftOperand leftOperand() const noexcept {
273  return lhs_;
274  }
275  //**********************************************************************************************
276 
277  //**Right operand access************************************************************************
282  inline RightOperand rightOperand() const noexcept {
283  return rhs_;
284  }
285  //**********************************************************************************************
286 
287  //**********************************************************************************************
293  template< typename T >
294  inline bool canAlias( const T* alias ) const noexcept {
295  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
296  }
297  //**********************************************************************************************
298 
299  //**********************************************************************************************
305  template< typename T >
306  inline bool isAliased( const T* alias ) const noexcept {
307  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
308  }
309  //**********************************************************************************************
310 
311  private:
312  //**Member variables****************************************************************************
315  //**********************************************************************************************
316 
317  //**Assignment to dense matrices****************************************************************
329  template< typename MT // Type of the target dense matrix
330  , bool SO > // Storage order of the target dense matrix
331  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
332  {
334 
335  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
336  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
337 
338  assign( ~lhs, rhs.lhs_ );
339 
340  if( !IsResizable_v< ElementType_t<MT> > ) {
341  subAssign( ~lhs, rhs.rhs_ );
342  }
343  else
344  {
345  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
346 
347  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
348  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
349  BLAZE_INTERNAL_ASSERT( B.rows() == (~lhs).rows() , "Invalid number of rows" );
350  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
351 
352  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
353  const auto end( B.end(j) );
354  for( auto element=B.begin(j); element!=end; ++element ) {
355  if( isDefault( (~lhs)(element->index(),j) ) )
356  (~lhs)(element->index(),j) = -element->value();
357  else
358  (~lhs)(element->index(),j) -= element->value();
359  }
360  }
361  }
362  }
364  //**********************************************************************************************
365 
366  //**Assignment to row-major sparse matrices*****************************************************
379  template< typename MT > // Type of the target sparse matrix
380  friend inline auto assign( SparseMatrix<MT,false>& lhs, const SMatTSMatSubExpr& rhs )
382  {
384 
385  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
386  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
387 
388  // Evaluation of the left-hand side sparse matrix operand
389  CT1 A( serial( rhs.lhs_ ) );
390 
391  // Evaluation of the right-hand side sparse matrix operand
392  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
393 
394  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
395  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
396  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
397  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
398  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
399  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
400 
401  // Final memory allocation (based on the evaluated operands)
402  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
403 
404  // Performing the matrix subtraction
405  for( size_t i=0UL; i<(~lhs).rows(); ++i )
406  {
407  const auto lend( A.end(i) );
408  const auto rend( B.end(i) );
409 
410  auto l( A.begin(i) );
411  auto r( B.begin(i) );
412 
413  while( l != lend && r != rend )
414  {
415  if( l->index() < r->index() ) {
416  (~lhs).append( i, l->index(), l->value() );
417  ++l;
418  }
419  else if( l->index() > r->index() ) {
420  (~lhs).append( i, r->index(), -r->value() );
421  ++r;
422  }
423  else {
424  (~lhs).append( i, l->index(), l->value() - r->value() );
425  ++l;
426  ++r;
427  }
428  }
429 
430  while( l != lend ) {
431  (~lhs).append( i, l->index(), l->value() );
432  ++l;
433  }
434 
435  while( r != rend ) {
436  (~lhs).append( i, r->index(), -r->value() );
437  ++r;
438  }
439 
440  (~lhs).finalize( i );
441  }
442  }
444  //**********************************************************************************************
445 
446  //**Assignment to row-major sparse matrices*****************************************************
459  template< typename MT > // Type of the target sparse matrix
460  friend inline auto assign( SparseMatrix<MT,false>& lhs, const SMatTSMatSubExpr& rhs )
461  -> EnableIf_t< UseSymmetricKernel_v<MT,MT2> >
462  {
464 
465  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
466  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
467 
468  assign( ~lhs, rhs.lhs_ - trans( rhs.rhs_ ) );
469  }
471  //**********************************************************************************************
472 
473  //**Assignment to column-major sparse matrices**************************************************
486  template< typename MT > // Type of the target sparse matrix
487  friend inline auto assign( SparseMatrix<MT,true>& lhs, const SMatTSMatSubExpr& rhs )
488  -> DisableIf_t< UseSymmetricKernel_v<MT,MT1> >
489  {
491 
493 
494  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
495  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
496 
497  // Evaluation of the left-hand side sparse matrix operand
498  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
499 
500  // Evaluation of the right-hand side sparse matrix operand
501  CT2 B( serial( rhs.rhs_ ) );
502 
503  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
504  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
505  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
506  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
507  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
508  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
509 
510  // Final memory allocation (based on the evaluated operands)
511  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
512 
513  // Performing the matrix subtraction
514  for( size_t j=0UL; j<(~lhs).columns(); ++j )
515  {
516  const auto lend( A.end(j) );
517  const auto rend( B.end(j) );
518 
519  auto l( A.begin(j) );
520  auto r( B.begin(j) );
521 
522  while( l != lend && r != rend )
523  {
524  if( l->index() < r->index() ) {
525  (~lhs).append( l->index(), j, l->value() );
526  ++l;
527  }
528  else if( l->index() > r->index() ) {
529  (~lhs).append( r->index(), j, -r->value() );
530  ++r;
531  }
532  else {
533  (~lhs).append( l->index(), j, l->value() - r->value() );
534  ++l;
535  ++r;
536  }
537  }
538 
539  while( l != lend ) {
540  (~lhs).append( l->index(), j, l->value() );
541  ++l;
542  }
543 
544  while( r != rend ) {
545  (~lhs).append( r->index(), j, -r->value() );
546  ++r;
547  }
548 
549  (~lhs).finalize( j );
550  }
551  }
553  //**********************************************************************************************
554 
555  //**Assignment to column-major sparse matrices**************************************************
568  template< typename MT > // Type of the target sparse matrix
569  friend inline auto assign( SparseMatrix<MT,true>& lhs, const SMatTSMatSubExpr& rhs )
570  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1> >
571  {
573 
575 
576  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
577  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
578 
579  assign( ~lhs, trans( rhs.lhs_ ) - rhs.rhs_ );
580  }
582  //**********************************************************************************************
583 
584  //**Addition assignment to dense matrices*******************************************************
597  template< typename MT // Type of the target dense matrix
598  , bool SO > // Storage order of the target dense matrix
599  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
600  {
602 
603  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
604  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
605 
606  addAssign( ~lhs, rhs.lhs_ );
607  subAssign( ~lhs, rhs.rhs_ );
608  }
610  //**********************************************************************************************
611 
612  //**Addition assignment to sparse matrices******************************************************
613  // No special implementation for the addition assignment to sparse matrices.
614  //**********************************************************************************************
615 
616  //**Subtraction assignment to dense matrices****************************************************
629  template< typename MT // Type of the target dense matrix
630  , bool SO > // Storage order of the target dense matrix
631  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
632  {
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  subAssign( ~lhs, rhs.lhs_ );
639  addAssign( ~lhs, rhs.rhs_ );
640  }
642  //**********************************************************************************************
643 
644  //**Subtraction assignment to sparse matrices***************************************************
645  // No special implementation for the subtraction assignment to sparse matrices.
646  //**********************************************************************************************
647 
648  //**Schur product assignment to dense matrices**************************************************
661  template< typename MT // Type of the target dense matrix
662  , bool SO > // Storage order of the target dense matrix
663  friend inline void schurAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
664  {
666 
669 
670  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
671  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
672 
673  const ResultType tmp( serial( rhs ) );
674  schurAssign( ~lhs, tmp );
675  }
677  //**********************************************************************************************
678 
679  //**Schur product assignment to sparse matrices*************************************************
680  // No special implementation for the Schur product assignment to sparse matrices.
681  //**********************************************************************************************
682 
683  //**Multiplication assignment to dense matrices*************************************************
684  // No special implementation for the multiplication assignment to dense matrices.
685  //**********************************************************************************************
686 
687  //**Multiplication assignment to sparse matrices************************************************
688  // No special implementation for the multiplication assignment to sparse matrices.
689  //**********************************************************************************************
690 
691  //**SMP assignment to dense matrices************************************************************
692  // No special implementation for the SMP assignment to dense matrices.
693  //**********************************************************************************************
694 
695  //**Assignment to sparse matrices***************************************************************
696  // No special implementation for the SMP assignment to sparse matrices.
697  //**********************************************************************************************
698 
699  //**SMP addition assignment to dense matrices***************************************************
714  template< typename MT // Type of the target dense matrix
715  , bool SO > // Storage order of the target dense matrix
716  friend inline auto smpAddAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
717  -> EnableIf_t< UseSMPAssign_v<MT> >
718  {
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  smpAddAssign( ~lhs, rhs.lhs_ );
725  smpSubAssign( ~lhs, rhs.rhs_ );
726  }
728  //**********************************************************************************************
729 
730  //**SMP addition assignment to sparse matrices**************************************************
731  // No special implementation for the SMP addition assignment to sparse matrices.
732  //**********************************************************************************************
733 
734  //**SMP subtraction assignment to dense matrices************************************************
749  template< typename MT // Type of the target dense matrix
750  , bool SO > // Storage order of the target dense matrix
751  friend inline auto smpSubAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
752  -> EnableIf_t< UseSMPAssign_v<MT> >
753  {
755 
756  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
757  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
758 
759  smpSubAssign( ~lhs, rhs.lhs_ );
760  smpAddAssign( ~lhs, rhs.rhs_ );
761  }
763  //**********************************************************************************************
764 
765  //**SMP subtraction assignment to sparse matrices***********************************************
766  // No special implementation for the SMP subtraction assignment to sparse matrices.
767  //**********************************************************************************************
768 
769  //**SMP Schur product assignment to dense matrices**********************************************
784  template< typename MT // Type of the target dense matrix
785  , bool SO > // Storage order of the target dense matrix
786  friend inline auto smpSchurAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSubExpr& rhs )
787  -> EnableIf_t< UseSMPAssign_v<MT> >
788  {
790 
793 
794  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
795  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
796 
797  const ResultType tmp( rhs );
798  smpSchurAssign( ~lhs, tmp );
799  }
801  //**********************************************************************************************
802 
803  //**SMP Schur product assignment to sparse matrices*********************************************
804  // No special implementation for the SMP Schur product assignment to sparse matrices.
805  //**********************************************************************************************
806 
807  //**SMP multiplication assignment to dense matrices*********************************************
808  // No special implementation for the SMP multiplication assignment to dense matrices.
809  //**********************************************************************************************
810 
811  //**SMP multiplication assignment to sparse matrices********************************************
812  // No special implementation for the SMP multiplication assignment to sparse matrices.
813  //**********************************************************************************************
814 
815  //**Compile time checks*************************************************************************
823  //**********************************************************************************************
824 };
825 //*************************************************************************************************
826 
827 
828 
829 
830 //=================================================================================================
831 //
832 // GLOBAL BINARY ARITHMETIC OPERATORS
833 //
834 //=================================================================================================
835 
836 //*************************************************************************************************
849 template< typename MT1 // Type of the left-hand side sparse matrix
850  , typename MT2 // Type of the right-hand side sparse matrix
851  , DisableIf_t< ( ( IsZero_v<MT1> || IsZero_v<MT2> ) &&
852  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
853  ( IsZero_v<MT1> && IsZero_v<MT2> ) >* = nullptr >
854 inline const SMatTSMatSubExpr<MT1,MT2>
855  smattsmatsub( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
856 {
858 
859  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
860  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
861 
862  return SMatTSMatSubExpr<MT1,MT2>( ~lhs, ~rhs );
863 }
865 //*************************************************************************************************
866 
867 
868 //*************************************************************************************************
882 template< typename MT1 // Type of the left-hand side sparse matrix
883  , typename MT2 // Type of the right-hand side sparse matrix
884  , EnableIf_t< !IsZero_v<MT1> && IsZero_v<MT2> &&
885  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* = nullptr >
886 inline const MT1&
887  smattsmatsub( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
888 {
890 
891  MAYBE_UNUSED( rhs );
892 
893  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
894  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
895 
896  return (~lhs);
897 }
899 //*************************************************************************************************
900 
901 
902 //*************************************************************************************************
916 template< typename MT1 // Type of the left-hand side sparse matrix
917  , typename MT2 // Type of the right-hand side sparse matrix
918  , EnableIf_t< IsZero_v<MT1> && !IsZero_v<MT2> &&
919  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* = nullptr >
920 inline decltype(auto)
921  smattsmatsub( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
922 {
924 
925  MAYBE_UNUSED( lhs );
926 
927  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
928  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
929 
930  return -(~rhs);
931 }
933 //*************************************************************************************************
934 
935 
936 //*************************************************************************************************
949 template< typename MT1 // Type of the left-hand side sparse matrix
950  , typename MT2 // Type of the right-hand side sparse matrix
951  , EnableIf_t< IsZero_v<MT1> && IsZero_v<MT2> >* = nullptr >
952 inline decltype(auto)
953  smattsmatsub( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
954 {
956 
957  MAYBE_UNUSED( rhs );
958 
959  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
960  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
961 
962  using ReturnType = const SubTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
963 
966 
967  return ReturnType( (~lhs).rows(), (~lhs).columns() );
968 }
970 //*************************************************************************************************
971 
972 
973 //*************************************************************************************************
1002 template< typename MT1 // Type of the left-hand side sparse matrix
1003  , typename MT2 > // Type of the right-hand side sparse matrix
1004 inline decltype(auto)
1005  operator-( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1006 {
1008 
1009  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1010  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1011  }
1012 
1013  return smattsmatsub( ~lhs, ~rhs );
1014 }
1015 //*************************************************************************************************
1016 
1017 } // namespace blaze
1018 
1019 #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
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: SMatTSMatSubExpr.h:282
Header file for auxiliary alias declarations.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatTSMatSubExpr.h:272
typename SubTrait< T1, T2 >::Type SubTrait_t
Auxiliary alias declaration for the SubTrait class template.The SubTrait_t alias declaration provides...
Definition: SubTrait.h:238
Header file for the subtraction trait.
Header file for basic type definitions.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatTSMatSubExpr.h:306
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTSMatSubExpr.h:156
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.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatTSMatSubExpr.h:251
Header file for the IsSame and IsStrictlySame type traits.
LeftOperand lhs_
Left-hand side sparse matrix of the subtraction expression.
Definition: SMatTSMatSubExpr.h:313
Constraint on the data type.
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:102
Header file for the MAYBE_UNUSED function template.
Header file for the Computation base class.
Constraints on the storage order of matrix types.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTSMatSubExpr.h:164
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
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 SparseMatrix base class.
Constraint on the data type.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTSMatSubExpr.h:215
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.The IsResizable_v variable template provid...
Definition: IsResizable.h:133
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatTSMatSubExpr.h:241
Header file for the DisableIf class template.
decltype(std::declval< RN1 >() - std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatTSMatSubExpr.h:119
Header file for the IsTemporary type trait class.
Header file for the IsSymmetric type trait.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatTSMatSubExpr.h:161
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatTSMatSubExpr.h:262
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
#define BLAZE_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
Expression object for sparse matrix-transpose sparse matrix subtractions.The SMatTSMatSubExpr class r...
Definition: Forward.h:144
#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.
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:106
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Header file for the exception macros of the math module.
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:105
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 the EnableIf class template.
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:101
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTSMatSubExpr.h:200
#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,...
Definition: Symmetric.h:79
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatTSMatSubExpr.h:158
#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
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
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
SubTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatTSMatSubExpr.h:155
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatTSMatSubExpr.h:157
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 all forward declarations for expression class templates.
Header file for the isDefault shim.
Constraint on the data type.
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
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
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:167
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatTSMatSubExpr.h:175
Header file for the IsComputation type trait class.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatTSMatSubExpr.h:294
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
Header file for the StorageOrder type trait.
Header file for the IntegralConstant class template.
SMatTSMatSubExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatTSMatSubExpr class.
Definition: SMatTSMatSubExpr.h:184
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:170
RightOperand rhs_
Right-hand side sparse matrix of the subtraction expression.
Definition: SMatTSMatSubExpr.h:314
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatTSMatSubExpr.h:231
#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:635
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
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:103
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:159
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
#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
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatTSMatSubExpr.h:116
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSubExpr.h:104
Header file for the IsExpression type trait class.
Header file for the function trace functionality.