Blaze  3.6
TSMatTSMatAddExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATADDEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATADDEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
66 #include <blaze/util/Assert.h>
67 #include <blaze/util/DisableIf.h>
68 #include <blaze/util/EnableIf.h>
71 #include <blaze/util/MaybeUnused.h>
72 #include <blaze/util/mpl/If.h>
73 #include <blaze/util/Types.h>
75 
76 
77 namespace blaze {
78 
79 //=================================================================================================
80 //
81 // CLASS TSMATTSMATADDEXPR
82 //
83 //=================================================================================================
84 
85 //*************************************************************************************************
92 template< typename MT1 // Type of the left-hand side sparse matrix
93  , typename MT2 > // Type of the right-hand side sparse matrix
94 class TSMatTSMatAddExpr
95  : public MatMatAddExpr< SparseMatrix< TSMatTSMatAddExpr<MT1,MT2>, true > >
96  , private Computation
97 {
98  private:
99  //**Type definitions****************************************************************************
106  //**********************************************************************************************
107 
108  //**Return type evaluation**********************************************************************
110 
115  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
116 
118  using ExprReturnType = decltype( std::declval<RN1>() + std::declval<RN2>() );
119  //**********************************************************************************************
120 
121  //**Serial evaluation strategy******************************************************************
123 
128  template< typename T1, typename T2, typename T3 >
129  static constexpr bool UseSymmetricKernel_v =
130  ( IsRowMajorMatrix_v<T1> && IsSymmetric_v<T2> && IsSymmetric_v<T3> );
132  //**********************************************************************************************
133 
134  //**Parallel evaluation strategy****************************************************************
136 
141  template< typename MT >
142  static constexpr bool UseSMPAssign_v = MT::smpAssignable;
144  //**********************************************************************************************
145 
146  public:
147  //**Type definitions****************************************************************************
154 
157 
159  using CompositeType = const ResultType;
160 
162  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
163 
165  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
166  //**********************************************************************************************
167 
168  //**Compilation flags***************************************************************************
170  static constexpr bool smpAssignable = false;
171  //**********************************************************************************************
172 
173  //**Constructor*********************************************************************************
179  explicit inline TSMatTSMatAddExpr( const MT1& lhs, const MT2& rhs ) noexcept
180  : lhs_( lhs ) // Left-hand side sparse matrix of the addition expression
181  , rhs_( rhs ) // Right-hand side sparse matrix of the addition expression
182  {
183  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
184  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
185  }
186  //**********************************************************************************************
187 
188  //**Access operator*****************************************************************************
195  inline ReturnType operator()( size_t i, size_t j ) const {
196  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
197  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
198  return lhs_(i,j) + rhs_(i,j);
199  }
200  //**********************************************************************************************
201 
202  //**At function*********************************************************************************
210  inline ReturnType at( size_t i, size_t j ) const {
211  if( i >= lhs_.rows() ) {
212  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
213  }
214  if( j >= lhs_.columns() ) {
215  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
216  }
217  return (*this)(i,j);
218  }
219  //**********************************************************************************************
220 
221  //**Rows function*******************************************************************************
226  inline size_t rows() const noexcept {
227  return lhs_.rows();
228  }
229  //**********************************************************************************************
230 
231  //**Columns function****************************************************************************
236  inline size_t columns() const noexcept {
237  return lhs_.columns();
238  }
239  //**********************************************************************************************
240 
241  //**NonZeros function***************************************************************************
246  inline size_t nonZeros() const {
247  return lhs_.nonZeros() + rhs_.nonZeros();
248  }
249  //**********************************************************************************************
250 
251  //**NonZeros function***************************************************************************
257  inline size_t nonZeros( size_t i ) const {
258  return lhs_.nonZeros(i) + rhs_.nonZeros(i);
259  }
260  //**********************************************************************************************
261 
262  //**Left operand access*************************************************************************
267  inline LeftOperand leftOperand() const noexcept {
268  return lhs_;
269  }
270  //**********************************************************************************************
271 
272  //**Right operand access************************************************************************
277  inline RightOperand rightOperand() const noexcept {
278  return rhs_;
279  }
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
288  template< typename T >
289  inline bool canAlias( const T* alias ) const noexcept {
290  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
291  }
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
300  template< typename T >
301  inline bool isAliased( const T* alias ) const noexcept {
302  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
303  }
304  //**********************************************************************************************
305 
306  private:
307  //**Member variables****************************************************************************
310  //**********************************************************************************************
311 
312  //**Assignment to dense matrices****************************************************************
325  template< typename MT // Type of the target dense matrix
326  , bool SO > // Storage order of the target dense matrix
327  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
328  {
330 
331  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
332  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
333 
334  assign( ~lhs, rhs.lhs_ );
335 
336  if( !IsResizable_v< ElementType_t<MT> > ) {
337  addAssign( ~lhs, rhs.rhs_ );
338  }
339  else
340  {
341  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
342 
343  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
344  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
345  BLAZE_INTERNAL_ASSERT( B.rows() == (~lhs).rows() , "Invalid number of rows" );
346  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
347 
348  for( size_t j=0UL; j<(~lhs).columns(); ++j ) {
349  const auto end( B.end(j) );
350  for( auto element=B.begin(j); element!=end; ++element ) {
351  if( isDefault( (~lhs)(element->index(),j) ) )
352  (~lhs)(element->index(),j) = element->value();
353  else
354  (~lhs)(element->index(),j) += element->value();
355  }
356  }
357  }
358  }
360  //**********************************************************************************************
361 
362  //**Assignment to row-major sparse matrices*****************************************************
375  template< typename MT > // Type of the target sparse matrix
376  friend inline auto assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatAddExpr& rhs )
378  {
380 
382 
383  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
384  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
385 
386  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
387  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
388 
389  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
390  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
391  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
392  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
393  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
394  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
395 
396  const size_t m( rhs.rows() );
397  const size_t n( rhs.columns() );
398 
399  // Counting the number of elements per column
400  std::vector<size_t> nonzeros( m, 0UL );
401  for( size_t j=0UL; j<n; ++j )
402  {
403  const auto lend( A.end(j) );
404  const auto rend( B.end(j) );
405 
406  auto l( A.begin(j) );
407  auto r( B.begin(j) );
408 
409  while( l != lend && r != rend )
410  {
411  if( l->index() < r->index() ) {
412  ++nonzeros[l->index()];
413  ++l;
414  }
415  else if( l->index() > r->index() ) {
416  ++nonzeros[r->index()];
417  ++r;
418  }
419  else {
420  ++nonzeros[l->index()];
421  ++l;
422  ++r;
423  }
424  }
425 
426  while( l != lend ) {
427  ++nonzeros[l->index()];
428  ++l;
429  }
430 
431  while( r != rend ) {
432  ++nonzeros[r->index()];
433  ++r;
434  }
435  }
436 
437  // Resizing the left-hand side sparse matrix
438  for( size_t i=0UL; i<m; ++i ) {
439  (~lhs).reserve( i, nonzeros[i] );
440  }
441 
442  // Performing the matrix addition
443  for( size_t j=0UL; j<n; ++j )
444  {
445  const auto lend( A.end(j) );
446  const auto rend( B.end(j) );
447 
448  auto l( A.begin(j) );
449  auto r( B.begin(j) );
450 
451  while( l != lend && r != rend )
452  {
453  if( l->index() < r->index() ) {
454  (~lhs).append( l->index(), j, l->value() );
455  ++l;
456  }
457  else if( l->index() > r->index() ) {
458  (~lhs).append( r->index(), j, r->value() );
459  ++r;
460  }
461  else {
462  (~lhs).append( l->index(), j, l->value() + r->value() );
463  ++l;
464  ++r;
465  }
466  }
467 
468  while( l != lend ) {
469  (~lhs).append( l->index(), j, l->value() );
470  ++l;
471  }
472 
473  while( r != rend ) {
474  (~lhs).append( r->index(), j, r->value() );
475  ++r;
476  }
477  }
478  }
480  //**********************************************************************************************
481 
482  //**Assignment to row-major sparse matrices*****************************************************
495  template< typename MT > // Type of the target sparse matrix
496  friend inline auto assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatAddExpr& rhs )
497  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1,MT2> >
498  {
500 
502 
503  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
504  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
505 
506  assign( ~lhs, trans( rhs.lhs_ ) + trans( rhs.rhs_ ) );
507  }
509  //**********************************************************************************************
510 
511  //**Assignment to column-major sparse matrices**************************************************
524  template< typename MT > // Type of the target sparse matrix
525  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatAddExpr& rhs )
526  {
528 
529  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
530  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
531 
532  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
533  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
534 
535  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
536  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
537  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
538  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
539  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
540  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
541 
542  // Final memory allocation (based on the evaluated operands)
543  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
544 
545  // Performing the matrix addition
546  for( size_t j=0UL; j<(~lhs).columns(); ++j )
547  {
548  const auto lend( A.end(j) );
549  const auto rend( B.end(j) );
550 
551  auto l( A.begin(j) );
552  auto r( B.begin(j) );
553 
554  while( l != lend && r != rend )
555  {
556  if( l->index() < r->index() ) {
557  (~lhs).append( l->index(), j, l->value() );
558  ++l;
559  }
560  else if( l->index() > r->index() ) {
561  (~lhs).append( r->index(), j, r->value() );
562  ++r;
563  }
564  else {
565  (~lhs).append( l->index(), j, l->value() + r->value() );
566  ++l;
567  ++r;
568  }
569  }
570 
571  while( l != lend ) {
572  (~lhs).append( l->index(), j, l->value() );
573  ++l;
574  }
575 
576  while( r != rend ) {
577  (~lhs).append( r->index(), j, r->value() );
578  ++r;
579  }
580 
581  (~lhs).finalize( j );
582  }
583  }
585  //**********************************************************************************************
586 
587  //**Addition assignment to dense matrices*******************************************************
600  template< typename MT // Type of the target dense matrix
601  , bool SO > // Storage order of the target dense matrix
602  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
603  {
605 
606  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
607  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
608 
609  addAssign( ~lhs, rhs.lhs_ );
610  addAssign( ~lhs, rhs.rhs_ );
611  }
613  //**********************************************************************************************
614 
615  //**Addition assignment to sparse matrices******************************************************
616  // No special implementation for the addition assignment to sparse matrices.
617  //**********************************************************************************************
618 
619  //**Subtraction assignment to dense matrices****************************************************
632  template< typename MT // Type of the target dense matrix
633  , bool SO > // Storage order of the target dense matrix
634  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
635  {
637 
638  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
639  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
640 
641  subAssign( ~lhs, rhs.lhs_ );
642  subAssign( ~lhs, rhs.rhs_ );
643  }
645  //**********************************************************************************************
646 
647  //**Subtraction assignment to sparse matrices***************************************************
648  // No special implementation for the subtraction assignment to sparse matrices.
649  //**********************************************************************************************
650 
651  //**Schur product assignment to dense matrices**************************************************
664  template< typename MT // Type of the target dense matrix
665  , bool SO > // Storage order of the target dense matrix
666  friend inline void schurAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
667  {
669 
673 
674  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
675  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
676 
677  const ResultType tmp( serial( rhs ) );
678  schurAssign( ~lhs, tmp );
679  }
681  //**********************************************************************************************
682 
683  //**Schur product assignment to sparse matrices*************************************************
684  // No special implementation for the Schur product assignment to sparse matrices.
685  //**********************************************************************************************
686 
687  //**Multiplication assignment to dense matrices*************************************************
688  // No special implementation for the multiplication assignment to dense matrices.
689  //**********************************************************************************************
690 
691  //**Multiplication assignment to sparse matrices************************************************
692  // No special implementation for the multiplication assignment to sparse matrices.
693  //**********************************************************************************************
694 
695  //**SMP assignment to dense matrices************************************************************
696  // No special implementation for the SMP assignment to dense matrices.
697  //**********************************************************************************************
698 
699  //**SMP assignment to sparse matrices***********************************************************
700  // No special implementation for the SMP assignment to sparse matrices.
701  //**********************************************************************************************
702 
703  //**SMP addition assignment to dense matrices***************************************************
718  template< typename MT // Type of the target dense matrix
719  , bool SO > // Storage order of the target dense matrix
720  friend inline auto smpAddAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
721  -> EnableIf_t< UseSMPAssign_v<MT> >
722  {
724 
725  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
726  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
727 
728  smpAddAssign( ~lhs, rhs.lhs_ );
729  smpAddAssign( ~lhs, rhs.rhs_ );
730  }
732  //**********************************************************************************************
733 
734  //**SMP addition assignment to sparse matrices**************************************************
735  // No special implementation for the SMP addition assignment to sparse matrices.
736  //**********************************************************************************************
737 
738  //**SMP subtraction assignment to dense matrices************************************************
753  template< typename MT // Type of the target dense matrix
754  , bool SO > // Storage order of the target dense matrix
755  friend inline auto smpSubAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
756  -> EnableIf_t< UseSMPAssign_v<MT> >
757  {
759 
760  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
761  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
762 
763  smpSubAssign( ~lhs, rhs.lhs_ );
764  smpSubAssign( ~lhs, rhs.rhs_ );
765  }
767  //**********************************************************************************************
768 
769  //**SMP subtraction assignment to sparse matrices***********************************************
770  // No special implementation for the SMP subtraction assignment to sparse matrices.
771  //**********************************************************************************************
772 
773  //**SMP Schur product assignment to dense matrices**********************************************
789  template< typename MT // Type of the target dense matrix
790  , bool SO > // Storage order of the target dense matrix
791  friend inline auto smpSchurAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatAddExpr& rhs )
792  -> EnableIf_t< UseSMPAssign_v<MT> >
793  {
795 
799 
800  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
801  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
802 
803  const ResultType tmp( rhs );
804  smpSchurAssign( ~lhs, tmp );
805  }
807  //**********************************************************************************************
808 
809  //**SMP Schur product assignment to sparse matrices*********************************************
810  // No special implementation for the SMP Schur product assignment to sparse matrices.
811  //**********************************************************************************************
812 
813  //**SMP multiplication assignment to dense matrices*********************************************
814  // No special implementation for the SMP multiplication assignment to dense matrices.
815  //**********************************************************************************************
816 
817  //**SMP multiplication assignment to sparse matrices********************************************
818  // No special implementation for the SMP multiplication assignment to sparse matrices.
819  //**********************************************************************************************
820 
821  //**Compile time checks*************************************************************************
829  //**********************************************************************************************
830 };
831 //*************************************************************************************************
832 
833 
834 
835 
836 //=================================================================================================
837 //
838 // GLOBAL BINARY ARITHMETIC OPERATORS
839 //
840 //=================================================================================================
841 
842 //*************************************************************************************************
854 template< typename MT1 // Type of the left-hand side sparse matrix
855  , typename MT2 // Type of the right-hand side sparse matrix
856  , DisableIf_t< ( ( IsZero_v<MT1> || IsZero_v<MT2> ) &&
857  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > ) ||
858  ( IsZero_v<MT1> && IsZero_v<MT2> ) >* = nullptr >
859 inline const TSMatTSMatAddExpr<MT1,MT2>
860  tsmattsmatadd( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
861 {
863 
864  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
865  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
866 
867  return TSMatTSMatAddExpr<MT1,MT2>( ~lhs, ~rhs );
868 }
870 //*************************************************************************************************
871 
872 
873 //*************************************************************************************************
887 template< typename MT1 // Type of the left-hand side sparse matrix
888  , typename MT2 // Type of the right-hand side sparse matrix
889  , EnableIf_t< !IsZero_v<MT1> && IsZero_v<MT2> &&
890  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* = nullptr >
891 inline const MT1&
892  tsmattsmatadd( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
893 {
895 
896  MAYBE_UNUSED( rhs );
897 
898  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
899  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
900 
901  return (~lhs);
902 }
904 //*************************************************************************************************
905 
906 
907 //*************************************************************************************************
921 template< typename MT1 // Type of the left-hand side sparse matrix
922  , typename MT2 // Type of the right-hand side sparse matrix
923  , EnableIf_t< IsZero_v<MT1> && !IsZero_v<MT2> &&
924  IsSame_v< ElementType_t<MT1>, ElementType_t<MT2> > >* = nullptr >
925 inline const MT2&
926  tsmattsmatadd( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
927 {
929 
930  MAYBE_UNUSED( lhs );
931 
932  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
933  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
934 
935  return (~rhs);
936 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
953 template< typename MT1 // Type of the left-hand side sparse matrix
954  , typename MT2 // Type of the right-hand side sparse matrix
955  , EnableIf_t< IsZero_v<MT1> && IsZero_v<MT2> >* = nullptr >
956 inline decltype(auto)
957  tsmattsmatadd( const SparseMatrix<MT1,true>& lhs, const SparseMatrix<MT2,true>& rhs )
958 {
960 
961  MAYBE_UNUSED( rhs );
962 
963  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
964  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
965 
966  using ReturnType = const AddTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
967 
970 
971  return ReturnType( (~lhs).rows(), (~lhs).columns() );
972 }
974 //*************************************************************************************************
975 
976 
977 //*************************************************************************************************
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,true>& 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 tsmattsmatadd( ~lhs, ~rhs );
1015 }
1016 //*************************************************************************************************
1017 
1018 } // namespace blaze
1019 
1020 #endif
#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
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatAddExpr.h:156
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:102
Header file for auxiliary alias declarations.
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatAddExpr.h:151
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatAddExpr.h:257
Header file for basic type definitions.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatAddExpr.h:152
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.
LeftOperand lhs_
Left-hand side sparse matrix of the addition expression.
Definition: TSMatTSMatAddExpr.h:308
Header file for the IsSame and IsStrictlySame type traits.
Constraint on the data type.
Header file for the MAYBE_UNUSED function template.
Header file for the Computation base class.
decltype(std::declval< RN1 >()+std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: TSMatTSMatAddExpr.h:118
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:165
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
TSMatTSMatAddExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatTSMatAddExpr class.
Definition: TSMatTSMatAddExpr.h:179
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
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatAddExpr.h:246
Header file for the SparseMatrix base class.
Constraint on the data type.
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.The IsResizable_v variable template provid...
Definition: IsResizable.h:133
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatAddExpr.h:159
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:162
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatAddExpr.h:289
Header file for the If class template.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatTSMatAddExpr.h:236
#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
Expression object for transpose sparse matrix-transpose sparse matrix additions.The TSMatTSMatAddExpr...
Definition: Forward.h:189
AddTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatAddExpr.h:150
#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
RightOperand rhs_
Right-hand side sparse matrix of the addition expression.
Definition: TSMatTSMatAddExpr.h:309
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: TSMatTSMatAddExpr.h:115
#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
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatAddExpr.h:301
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
typename AddTrait< T1, T2 >::Type AddTrait_t
Auxiliary alias declaration for the AddTrait class template.The AddTrait_t alias declaration provides...
Definition: AddTrait.h:238
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSMatTSMatAddExpr.h:153
Header file for the exception macros of the math module.
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
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATADDEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/matrix ...
Definition: MatMatAddExpr.h:103
Constraint on the data type.
Header file for the EnableIf class template.
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:104
#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
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
Header file for the addition trait.
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
Constraint on the data type.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatTSMatAddExpr.h:226
Header file for the IsZero type trait.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSMatTSMatAddExpr.h:170
#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
Header file for the MatMatAddExpr base class.
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
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 IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:103
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatAddExpr.h:195
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
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:100
Header file for the IntegralConstant class template.
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:101
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatTSMatAddExpr.h:210
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatAddExpr.h:277
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
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatAddExpr.h:105
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatAddExpr.h:267
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
Header file for the IsExpression type trait class.
Header file for the function trace functionality.