SMatSMatAddExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATADDEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATADDEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
72 #include <blaze/util/Assert.h>
73 #include <blaze/util/DisableIf.h>
74 #include <blaze/util/EnableIf.h>
76 #include <blaze/util/mpl/And.h>
77 #include <blaze/util/mpl/If.h>
78 #include <blaze/util/mpl/Maximum.h>
79 #include <blaze/util/mpl/Or.h>
80 #include <blaze/util/Types.h>
82 
83 
84 namespace blaze {
85 
86 //=================================================================================================
87 //
88 // CLASS SMATSMATADDEXPR
89 //
90 //=================================================================================================
91 
92 //*************************************************************************************************
99 template< typename MT1 // Type of the left-hand side sparse matrix
100  , typename MT2 > // Type of the right-hand side sparse matrix
101 class SMatSMatAddExpr
102  : public MatMatAddExpr< SparseMatrix< SMatSMatAddExpr<MT1,MT2>, false > >
103  , private Computation
104 {
105  private:
106  //**Type definitions****************************************************************************
113  //**********************************************************************************************
114 
115  //**Return type evaluation**********************************************************************
117 
122  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
123 
126  //**********************************************************************************************
127 
128  //**Serial evaluation strategy******************************************************************
130 
135  template< typename T1, typename T2, typename T3 >
136  struct UseSymmetricKernel {
138  enum : bool { value = IsSymmetric<T2>::value && IsSymmetric<T3>::value };
139  };
141  //**********************************************************************************************
142 
143  //**Parallel evaluation strategy****************************************************************
145 
150  template< typename MT >
151  struct UseSMPAssign {
152  enum : bool { value = MT::smpAssignable };
153  };
155  //**********************************************************************************************
156 
157  public:
158  //**Type definitions****************************************************************************
164 
167 
169  using CompositeType = const ResultType;
170 
172  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
173 
175  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
176  //**********************************************************************************************
177 
178  //**Compilation flags***************************************************************************
180  enum : bool { smpAssignable = false };
181  //**********************************************************************************************
182 
183  //**Constructor*********************************************************************************
189  explicit inline SMatSMatAddExpr( const MT1& lhs, const MT2& rhs ) noexcept
190  : lhs_( lhs ) // Left-hand side sparse matrix of the addition expression
191  , rhs_( rhs ) // Right-hand side sparse matrix of the addition expression
192  {
193  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
194  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
195  }
196  //**********************************************************************************************
197 
198  //**Access operator*****************************************************************************
205  inline ReturnType operator()( size_t i, size_t j ) const {
206  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
207  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
208  return lhs_(i,j) + rhs_(i,j);
209  }
210  //**********************************************************************************************
211 
212  //**At function*********************************************************************************
220  inline ReturnType at( size_t i, size_t j ) const {
221  if( i >= lhs_.rows() ) {
222  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
223  }
224  if( j >= lhs_.columns() ) {
225  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
226  }
227  return (*this)(i,j);
228  }
229  //**********************************************************************************************
230 
231  //**Rows function*******************************************************************************
236  inline size_t rows() const noexcept {
237  return lhs_.rows();
238  }
239  //**********************************************************************************************
240 
241  //**Columns function****************************************************************************
246  inline size_t columns() const noexcept {
247  return lhs_.columns();
248  }
249  //**********************************************************************************************
250 
251  //**NonZeros function***************************************************************************
256  inline size_t nonZeros() const {
257  return lhs_.nonZeros() + rhs_.nonZeros();
258  }
259  //**********************************************************************************************
260 
261  //**NonZeros function***************************************************************************
267  inline size_t nonZeros( size_t i ) const {
268  return lhs_.nonZeros(i) + rhs_.nonZeros(i);
269  }
270  //**********************************************************************************************
271 
272  //**Left operand access*************************************************************************
277  inline LeftOperand leftOperand() const noexcept {
278  return lhs_;
279  }
280  //**********************************************************************************************
281 
282  //**Right operand access************************************************************************
287  inline RightOperand rightOperand() const noexcept {
288  return rhs_;
289  }
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
298  template< typename T >
299  inline bool canAlias( const T* alias ) const noexcept {
300  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
301  }
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
310  template< typename T >
311  inline bool isAliased( const T* alias ) const noexcept {
312  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
313  }
314  //**********************************************************************************************
315 
316  private:
317  //**Member variables****************************************************************************
320  //**********************************************************************************************
321 
322  //**Assignment to dense matrices****************************************************************
334  template< typename MT // Type of the target dense matrix
335  , bool SO > // Storage order of the target dense matrix
336  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatSMatAddExpr& rhs )
337  {
339 
340  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
341  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
342 
343  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
344 
345  assign( ~lhs, rhs.lhs_ );
346 
347  if( !IsResizable< ElementType_<MT> >::value ) {
348  addAssign( ~lhs, rhs.rhs_ );
349  }
350  else
351  {
352  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
353 
354  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
356  BLAZE_INTERNAL_ASSERT( B.rows() == (~lhs).rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
358 
359  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
360  const RightIterator end( B.end(i) );
361  for( RightIterator element=B.begin(i); element!=end; ++element ) {
362  if( isDefault( (~lhs)(i,element->index()) ) )
363  (~lhs)(i,element->index()) = element->value();
364  else
365  (~lhs)(i,element->index()) += element->value();
366  }
367  }
368  }
369  }
371  //**********************************************************************************************
372 
373  //**Assignment to row-major sparse matrices*****************************************************
385  template< typename MT > // Type of the target sparse matrix
386  friend inline void assign( SparseMatrix<MT,false>& lhs, const SMatSMatAddExpr& rhs )
387  {
389 
390  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
391  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
392 
393  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
394  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
395 
396  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
397  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
398 
399  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
400  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
401  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
402  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
403  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
404  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
405 
406  // Final memory allocation (based on the evaluated operands)
407  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
408 
409  // Performing the matrix addition
410  for( size_t i=0UL; i<(~lhs).rows(); ++i )
411  {
412  const LeftIterator lend( A.end(i) );
413  const RightIterator rend( B.end(i) );
414 
415  LeftIterator l( A.begin(i) );
416  RightIterator r( B.begin(i) );
417 
418  while( l != lend && r != rend )
419  {
420  if( l->index() < r->index() ) {
421  (~lhs).append( i, l->index(), l->value() );
422  ++l;
423  }
424  else if( l->index() > r->index() ) {
425  (~lhs).append( i, r->index(), r->value() );
426  ++r;
427  }
428  else {
429  (~lhs).append( i, l->index(), l->value() + r->value() );
430  ++l;
431  ++r;
432  }
433  }
434 
435  while( l != lend ) {
436  (~lhs).append( i, l->index(), l->value() );
437  ++l;
438  }
439 
440  while( r != rend ) {
441  (~lhs).append( i, r->index(), r->value() );
442  ++r;
443  }
444 
445  (~lhs).finalize( i );
446  }
447  }
449  //**********************************************************************************************
450 
451  //**Assignment to column-major sparse matrices**************************************************
463  template< typename MT > // Type of the target sparse matrix
465  assign( SparseMatrix<MT,true>& lhs, const SMatSMatAddExpr& rhs )
466  {
468 
470 
471  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
472  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
473 
474  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
475  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
476 
477  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
478  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
479 
480  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
481  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
482  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
483  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
484  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
485  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
486 
487  const size_t m( A.rows() );
488  const size_t n( A.columns() );
489 
490  // Counting the number of elements per column
491  std::vector<size_t> nonzeros( n, 0UL );
492  for( size_t i=0UL; i<m; ++i )
493  {
494  const LeftIterator lend( A.end(i) );
495  const RightIterator rend( B.end(i) );
496 
497  LeftIterator l( A.begin(i) );
498  RightIterator r( B.begin(i) );
499 
500  while( l != lend && r != rend )
501  {
502  if( l->index() < r->index() ) {
503  ++nonzeros[l->index()];
504  ++l;
505  }
506  else if( l->index() > r->index() ) {
507  ++nonzeros[r->index()];
508  ++r;
509  }
510  else {
511  ++nonzeros[l->index()];
512  ++l;
513  ++r;
514  }
515  }
516 
517  while( l != lend ) {
518  ++nonzeros[l->index()];
519  ++l;
520  }
521 
522  while( r != rend ) {
523  ++nonzeros[r->index()];
524  ++r;
525  }
526  }
527 
528  // Resizing the left-hand side sparse matrix
529  for( size_t j=0UL; j<n; ++j ) {
530  (~lhs).reserve( j, nonzeros[j] );
531  }
532 
533  // Performing the matrix addition
534  for( size_t i=0UL; i<m; ++i )
535  {
536  const LeftIterator lend( A.end(i) );
537  const RightIterator rend( B.end(i) );
538 
539  LeftIterator l( A.begin(i) );
540  RightIterator r( B.begin(i) );
541 
542  while( l != lend && r != rend )
543  {
544  if( l->index() < r->index() ) {
545  (~lhs).append( i, l->index(), l->value() );
546  ++l;
547  }
548  else if( l->index() > r->index() ) {
549  (~lhs).append( i, r->index(), r->value() );
550  ++r;
551  }
552  else {
553  (~lhs).append( i, l->index(), l->value() + r->value() );
554  ++l;
555  ++r;
556  }
557  }
558 
559  while( l != lend ) {
560  (~lhs).append( i, l->index(), l->value() );
561  ++l;
562  }
563 
564  while( r != rend ) {
565  (~lhs).append( i, r->index(), r->value() );
566  ++r;
567  }
568  }
569  }
571  //**********************************************************************************************
572 
573  //**Assignment to column-major sparse matrices**************************************************
585  template< typename MT > // Type of the target sparse matrix
587  assign( SparseMatrix<MT,true>& lhs, const SMatSMatAddExpr& rhs )
588  {
590 
592 
593  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
594  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
595 
596  assign( ~lhs, trans( rhs.lhs_ ) + trans( rhs.rhs_ ) );
597  }
599  //**********************************************************************************************
600 
601  //**Addition assignment to dense matrices*******************************************************
613  template< typename MT // Type of the target dense matrix
614  , bool SO > // Storage order of the target dense matrix
615  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatAddExpr& rhs )
616  {
618 
619  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
620  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
621 
622  addAssign( ~lhs, rhs.lhs_ );
623  addAssign( ~lhs, rhs.rhs_ );
624  }
626  //**********************************************************************************************
627 
628  //**Addition assignment to sparse matrices******************************************************
629  // No special implementation for the addition assignment to sparse matrices.
630  //**********************************************************************************************
631 
632  //**Subtraction assignment to dense matrices****************************************************
644  template< typename MT // Type of the target dense matrix
645  , bool SO > // Storage order of the target dense matrix
646  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatAddExpr& rhs )
647  {
649 
650  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
651  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
652 
653  subAssign( ~lhs, rhs.lhs_ );
654  subAssign( ~lhs, rhs.rhs_ );
655  }
657  //**********************************************************************************************
658 
659  //**Subtraction assignment to sparse matrices***************************************************
660  // No special implementation for the subtraction assignment to sparse matrices.
661  //**********************************************************************************************
662 
663  //**Schur product assignment to dense matrices**************************************************
675  template< typename MT // Type of the target dense matrix
676  , bool SO > // Storage order of the target dense matrix
677  friend inline void schurAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatAddExpr& rhs )
678  {
680 
684 
685  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
686  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
687 
688  const ResultType tmp( serial( rhs ) );
689  schurAssign( ~lhs, tmp );
690  }
692  //**********************************************************************************************
693 
694  //**Schur product assignment to sparse matrices******************************************************
695  // No special implementation for the Schur product assignment to sparse matrices.
696  //**********************************************************************************************
697 
698  //**Multiplication assignment to dense matrices*************************************************
699  // No special implementation for the multiplication assignment to dense matrices.
700  //**********************************************************************************************
701 
702  //**Multiplication assignment to sparse matrices************************************************
703  // No special implementation for the multiplication assignment to sparse matrices.
704  //**********************************************************************************************
705 
706  //**SMP assignment to dense matrices************************************************************
707  // No special implementation for the SMP assignment to dense matrices.
708  //**********************************************************************************************
709 
710  //**SMP assignment to sparse matrices***********************************************************
711  // No special implementation for the SMP assignment to sparse matrices.
712  //**********************************************************************************************
713 
714  //**SMP addition assignment to dense matrices***************************************************
728  template< typename MT // Type of the target dense matrix
729  , bool SO > // Storage order of the target dense matrix
730  friend inline EnableIf_< UseSMPAssign<MT> >
732  {
734 
735  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
736  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
737 
738  smpAddAssign( ~lhs, rhs.lhs_ );
739  smpAddAssign( ~lhs, rhs.rhs_ );
740  }
742  //**********************************************************************************************
743 
744  //**SMP addition assignment to sparse matrices**************************************************
745  // No special implementation for the SMP addition assignment to sparse matrices.
746  //**********************************************************************************************
747 
748  //**SMP subtraction assignment to dense matrices************************************************
762  template< typename MT // Type of the target dense matrix
763  , bool SO > // Storage order of the target dense matrix
764  friend inline EnableIf_< UseSMPAssign<MT> >
766  {
768 
769  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
770  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
771 
772  smpSubAssign( ~lhs, rhs.lhs_ );
773  smpSubAssign( ~lhs, rhs.rhs_ );
774  }
776  //**********************************************************************************************
777 
778  //**SMP subtraction assignment to sparse matrices***********************************************
779  // No special implementation for the SMP subtraction assignment to sparse matrices.
780  //**********************************************************************************************
781 
782  //**SMP Schur product assignment to dense matrices**********************************************
797  template< typename MT // Type of the target dense matrix
798  , bool SO > // Storage order of the target dense matrix
799  friend inline EnableIf_< UseSMPAssign<MT> >
801  {
803 
807 
808  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
809  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
810 
811  const ResultType tmp( rhs );
812  smpSchurAssign( ~lhs, tmp );
813  }
815  //**********************************************************************************************
816 
817  //**SMP Schur product assignment to sparse matrices*********************************************
818  // No special implementation for the SMP Schur product assignment to sparse matrices.
819  //**********************************************************************************************
820 
821  //**SMP multiplication assignment to dense matrices*********************************************
822  // No special implementation for the SMP multiplication assignment to dense matrices.
823  //**********************************************************************************************
824 
825  //**SMP multiplication assignment to sparse matrices********************************************
826  // No special implementation for the SMP multiplication assignment to sparse matrices.
827  //**********************************************************************************************
828 
829  //**Compile time checks*************************************************************************
837  //**********************************************************************************************
838 };
839 //*************************************************************************************************
840 
841 
842 
843 
844 //=================================================================================================
845 //
846 // GLOBAL BINARY ARITHMETIC OPERATORS
847 //
848 //=================================================================================================
849 
850 //*************************************************************************************************
876 template< typename MT1 // Type of the left-hand side sparse matrix
877  , typename MT2 > // Type of the right-hand side sparse matrix
878 inline decltype(auto)
879  operator+( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
880 {
882 
883  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
884  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
885  }
886 
887  using ReturnType = const SMatSMatAddExpr<MT1,MT2>;
888  return ReturnType( ~lhs, ~rhs );
889 }
890 //*************************************************************************************************
891 
892 
893 
894 
895 //=================================================================================================
896 //
897 // SIZE SPECIALIZATIONS
898 //
899 //=================================================================================================
900 
901 //*************************************************************************************************
903 template< typename MT1, typename MT2 >
904 struct Size< SMatSMatAddExpr<MT1,MT2>, 0UL >
905  : public Maximum< Size<MT1,0UL>, Size<MT2,0UL> >
906 {};
907 
908 template< typename MT1, typename MT2 >
909 struct Size< SMatSMatAddExpr<MT1,MT2>, 1UL >
910  : public Maximum< Size<MT1,1UL>, Size<MT2,1UL> >
911 {};
913 //*************************************************************************************************
914 
915 
916 
917 
918 //=================================================================================================
919 //
920 // ISSYMMETRIC SPECIALIZATIONS
921 //
922 //=================================================================================================
923 
924 //*************************************************************************************************
926 template< typename MT1, typename MT2 >
927 struct IsSymmetric< SMatSMatAddExpr<MT1,MT2> >
928  : public And< IsSymmetric<MT1>, IsSymmetric<MT2> >
929 {};
931 //*************************************************************************************************
932 
933 
934 
935 
936 //=================================================================================================
937 //
938 // ISHERMITIAN SPECIALIZATIONS
939 //
940 //=================================================================================================
941 
942 //*************************************************************************************************
944 template< typename MT1, typename MT2 >
945 struct IsHermitian< SMatSMatAddExpr<MT1,MT2> >
946  : public And< IsHermitian<MT1>, IsHermitian<MT2> >
947 {};
949 //*************************************************************************************************
950 
951 
952 
953 
954 //=================================================================================================
955 //
956 // ISLOWER SPECIALIZATIONS
957 //
958 //=================================================================================================
959 
960 //*************************************************************************************************
962 template< typename MT1, typename MT2 >
963 struct IsLower< SMatSMatAddExpr<MT1,MT2> >
964  : public And< IsLower<MT1>, IsLower<MT2> >
965 {};
967 //*************************************************************************************************
968 
969 
970 
971 
972 //=================================================================================================
973 //
974 // ISUNILOWER SPECIALIZATIONS
975 //
976 //=================================================================================================
977 
978 //*************************************************************************************************
980 template< typename MT1, typename MT2 >
981 struct IsUniLower< SMatSMatAddExpr<MT1,MT2> >
982  : public Or< And< IsUniLower<MT1>, IsStrictlyLower<MT2> >
983  , And< IsUniLower<MT2>, IsStrictlyLower<MT1> > >
984 {};
986 //*************************************************************************************************
987 
988 
989 
990 
991 //=================================================================================================
992 //
993 // ISSTRICTLYLOWER SPECIALIZATIONS
994 //
995 //=================================================================================================
996 
997 //*************************************************************************************************
999 template< typename MT1, typename MT2 >
1000 struct IsStrictlyLower< SMatSMatAddExpr<MT1,MT2> >
1001  : public And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >
1002 {};
1004 //*************************************************************************************************
1005 
1006 
1007 
1008 
1009 //=================================================================================================
1010 //
1011 // ISUPPER SPECIALIZATIONS
1012 //
1013 //=================================================================================================
1014 
1015 //*************************************************************************************************
1017 template< typename MT1, typename MT2 >
1018 struct IsUpper< SMatSMatAddExpr<MT1,MT2> >
1019  : public And< IsUpper<MT1>, IsUpper<MT2> >
1020 {};
1022 //*************************************************************************************************
1023 
1024 
1025 
1026 
1027 //=================================================================================================
1028 //
1029 // ISUNIUPPER SPECIALIZATIONS
1030 //
1031 //=================================================================================================
1032 
1033 //*************************************************************************************************
1035 template< typename MT1, typename MT2 >
1036 struct IsUniUpper< SMatSMatAddExpr<MT1,MT2> >
1037  : public Or< And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >
1038  , And< IsUniUpper<MT2>, IsStrictlyUpper<MT1> > >
1039 {};
1041 //*************************************************************************************************
1042 
1043 
1044 
1045 
1046 //=================================================================================================
1047 //
1048 // ISSTRICTLYUPPER SPECIALIZATIONS
1049 //
1050 //=================================================================================================
1051 
1052 //*************************************************************************************************
1054 template< typename MT1, typename MT2 >
1055 struct IsStrictlyUpper< SMatSMatAddExpr<MT1,MT2> >
1056  : public And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >
1057 {};
1059 //*************************************************************************************************
1060 
1061 } // namespace blaze
1062 
1063 #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
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:110
Header file for auxiliary alias declarations.
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
Header file for the IsUniUpper type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for basic type definitions.
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatSMatAddExpr.h:166
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatAddExpr.h:169
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatSMatAddExpr.h:163
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the And class template.
Compile time value evaluation.The Maximum alias declaration selects the larger of the two given templ...
Definition: Maximum.h:73
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
Header file for the AddExprTrait class template.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatAddExpr.h:267
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatAddExpr.h:220
Header file for the Computation base class.
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:172
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
Constraints on the storage order of matrix types.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:109
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
SMatSMatAddExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatSMatAddExpr class.
Definition: SMatSMatAddExpr.h:189
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatAddExpr.h:287
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the Maximum class template.
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
ReturnType_< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:111
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
typename AddExprTrait< T1, T2 >::Type AddExprTrait_
Auxiliary alias declaration for the AddExprTrait class template.The AddExprTrait_ alias declaration p...
Definition: AddExprTrait.h:112
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
ReturnType_< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:112
#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
AddExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: SMatSMatAddExpr.h:125
Header file for the Or class template.
#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
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatAddExpr.h:256
AddTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatSMatAddExpr.h:160
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for the IsLower type trait.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatAddExpr.h:161
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatAddExpr.h:277
RightOperand rhs_
Right-hand side sparse matrix of the addition expression.
Definition: SMatSMatAddExpr.h:319
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
BLAZE_ALWAYS_INLINE 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:430
#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:107
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:107
#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
Header file for run time assertion macros.
Header file for the addition trait.
LeftOperand lhs_
Left-hand side sparse matrix of the addition expression.
Definition: SMatSMatAddExpr.h:318
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
Constraint on the data type.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatAddExpr.h:299
#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.
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
Constraint on the data type.
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatAddExpr.h:162
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:175
Header file for the MatMatAddExpr base class.
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatSMatAddExpr.h:236
Header file for the IsComputation type trait class.
Expression object for sparse matrix-sparse matrix additions.The SMatSMatAddExpr class represents the ...
Definition: Forward.h:116
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatAddExpr.h:311
Compile time logical &#39;or&#39; evaluation.The Or alias declaration performs at compile time a logical &#39;or&#39;...
Definition: Or.h:76
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatAddExpr.h:108
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatAddExpr.h:205
Compile time logical &#39;and&#39; evaluation.The And alias declaration performs at compile time a logical &#39;a...
Definition: And.h:76
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
Header file for the IsUpper type trait.
Header file for the IsHermitian type trait.
Header file for the IsResizable type trait.
Header file for the Size type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatSMatAddExpr.h:246
typename AddTrait< T1, T2 >::Type AddTrait_
Auxiliary alias declaration for the AddTrait class template.The AddTrait_ alias declaration provides ...
Definition: AddTrait.h:291
#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
#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.