SMatSMatSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATSUBEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATSUBEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
49 #include <blaze/math/Exception.h>
75 #include <blaze/util/Assert.h>
76 #include <blaze/util/DisableIf.h>
77 #include <blaze/util/EnableIf.h>
80 #include <blaze/util/mpl/And.h>
81 #include <blaze/util/mpl/If.h>
82 #include <blaze/util/mpl/Max.h>
83 #include <blaze/util/Types.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS SMATSMATSUBEXPR
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
102 template< typename MT1 // Type of the left-hand side sparse matrix
103  , typename MT2 > // Type of the right-hand side sparse matrix
104 class SMatSMatSubExpr : public SparseMatrix< SMatSMatSubExpr<MT1,MT2>, false >
105  , private MatMatSubExpr
106  , private Computation
107 {
108  private:
109  //**Type definitions****************************************************************************
116  //**********************************************************************************************
117 
118  //**Return type evaluation**********************************************************************
120 
125  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
126 
129  //**********************************************************************************************
130 
131  //**Serial evaluation strategy******************************************************************
133 
138  template< typename T1, typename T2, typename T3 >
139  struct UseSymmetricKernel {
141  enum : bool { value = IsSymmetric<T2>::value && IsSymmetric<T3>::value };
142  };
144  //**********************************************************************************************
145 
146  //**Parallel evaluation strategy****************************************************************
148 
153  template< typename MT >
154  struct UseSMPAssign {
155  enum : bool { value = MT::smpAssignable };
156  };
158  //**********************************************************************************************
159 
160  public:
161  //**Type definitions****************************************************************************
167 
170 
172  typedef const ResultType CompositeType;
173 
175  typedef If_< IsExpression<MT1>, const MT1, const MT1& > LeftOperand;
176 
178  typedef If_< IsExpression<MT2>, const MT2, const MT2& > RightOperand;
179  //**********************************************************************************************
180 
181  //**Compilation flags***************************************************************************
183  enum : bool { smpAssignable = false };
184  //**********************************************************************************************
185 
186  //**Constructor*********************************************************************************
192  explicit inline SMatSMatSubExpr( const MT1& lhs, const MT2& rhs ) noexcept
193  : lhs_( lhs ) // Left-hand side sparse matrix of the subtraction expression
194  , rhs_( rhs ) // Right-hand side sparse matrix of the subtraction expression
195  {
196  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
197  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
198  }
199  //**********************************************************************************************
200 
201  //**Access operator*****************************************************************************
208  inline ReturnType operator()( size_t i, size_t j ) const {
209  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
210  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
211  return lhs_(i,j) - rhs_(i,j);
212  }
213  //**********************************************************************************************
214 
215  //**At function*********************************************************************************
223  inline ReturnType at( size_t i, size_t j ) const {
224  if( i >= lhs_.rows() ) {
225  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
226  }
227  if( j >= lhs_.columns() ) {
228  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
229  }
230  return (*this)(i,j);
231  }
232  //**********************************************************************************************
233 
234  //**Rows function*******************************************************************************
239  inline size_t rows() const noexcept {
240  return lhs_.rows();
241  }
242  //**********************************************************************************************
243 
244  //**Columns function****************************************************************************
249  inline size_t columns() const noexcept {
250  return lhs_.columns();
251  }
252  //**********************************************************************************************
253 
254  //**NonZeros function***************************************************************************
259  inline size_t nonZeros() const {
260  return lhs_.nonZeros() + rhs_.nonZeros();
261  }
262  //**********************************************************************************************
263 
264  //**NonZeros function***************************************************************************
270  inline size_t nonZeros( size_t i ) const {
271  return lhs_.nonZeros(i) + rhs_.nonZeros(i);
272  }
273  //**********************************************************************************************
274 
275  //**Left operand access*************************************************************************
280  inline LeftOperand leftOperand() const noexcept {
281  return lhs_;
282  }
283  //**********************************************************************************************
284 
285  //**Right operand access************************************************************************
290  inline RightOperand rightOperand() const noexcept {
291  return rhs_;
292  }
293  //**********************************************************************************************
294 
295  //**********************************************************************************************
301  template< typename T >
302  inline bool canAlias( const T* alias ) const noexcept {
303  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
304  }
305  //**********************************************************************************************
306 
307  //**********************************************************************************************
313  template< typename T >
314  inline bool isAliased( const T* alias ) const noexcept {
315  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
316  }
317  //**********************************************************************************************
318 
319  private:
320  //**Member variables****************************************************************************
321  LeftOperand lhs_;
322  RightOperand rhs_;
323  //**********************************************************************************************
324 
325  //**Assignment to dense matrices****************************************************************
337  template< typename MT // Type of the target dense matrix
338  , bool SO > // Storage order of the target dense matrix
339  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
340  {
342 
343  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
344  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
345 
346  typedef ConstIterator_< RemoveReference_<CT2> > RightIterator;
347 
348  assign( ~lhs, rhs.lhs_ );
349 
350  if( !IsResizable< ElementType_<MT> >::value ) {
351  subAssign( ~lhs, rhs.rhs_ );
352  }
353  else
354  {
355  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
356 
357  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
358  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
359  BLAZE_INTERNAL_ASSERT( B.rows() == (~lhs).rows() , "Invalid number of rows" );
360  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
361 
362  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
363  const RightIterator end( B.end(i) );
364  for( RightIterator element=B.begin(i); element!=end; ++element ) {
365  if( isDefault( (~lhs)(i,element->index()) ) )
366  (~lhs)(i,element->index()) = -element->value();
367  else
368  (~lhs)(i,element->index()) -= element->value();
369  }
370  }
371  }
372  }
374  //**********************************************************************************************
375 
376  //**Assignment to row-major sparse matrices*****************************************************
388  template< typename MT > // Type of the target sparse matrix
389  friend inline void assign( SparseMatrix<MT,false>& lhs, const SMatSMatSubExpr& rhs )
390  {
392 
393  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
394  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
395 
396  typedef ConstIterator_< RemoveReference_<CT1> > LeftIterator;
397  typedef ConstIterator_< RemoveReference_<CT2> > RightIterator;
398 
399  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
400  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
401 
402  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
403  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
404  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
405  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
406  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
407  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
408 
409  // Final memory allocation (based on the evaluated operands)
410  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
411 
412  // Performing the matrix subtraction
413  for( size_t i=0UL; i<(~lhs).rows(); ++i )
414  {
415  const LeftIterator lend( A.end(i) );
416  const RightIterator rend( B.end(i) );
417 
418  LeftIterator l( A.begin(i) );
419  RightIterator r( B.begin(i) );
420 
421  while( l != lend && r != rend )
422  {
423  if( l->index() < r->index() ) {
424  (~lhs).append( i, l->index(), l->value() );
425  ++l;
426  }
427  else if( l->index() > r->index() ) {
428  (~lhs).append( i, r->index(), -r->value() );
429  ++r;
430  }
431  else {
432  (~lhs).append( i, l->index(), l->value()-r->value() );
433  ++l;
434  ++r;
435  }
436  }
437 
438  while( l != lend ) {
439  (~lhs).append( i, l->index(), l->value() );
440  ++l;
441  }
442 
443  while( r != rend ) {
444  (~lhs).append( i, r->index(), -r->value() );
445  ++r;
446  }
447 
448  (~lhs).finalize( i );
449  }
450  }
452  //**********************************************************************************************
453 
454  //**Assignment to column-major sparse matrices**************************************************
466  template< typename MT > // Type of the target sparse matrix
467  friend inline DisableIf_< UseSymmetricKernel<MT,MT1,MT2> >
468  assign( SparseMatrix<MT,true>& lhs, const SMatSMatSubExpr& rhs )
469  {
471 
473 
474  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
475  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
476 
477  typedef ConstIterator_< RemoveReference_<CT1> > LeftIterator;
478  typedef ConstIterator_< RemoveReference_<CT2> > RightIterator;
479 
480  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
481  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
482 
483  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
484  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
485  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
486  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
487  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
488  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
489 
490  const size_t m( rhs.rows() );
491  const size_t n( rhs.columns() );
492 
493  // Counting the number of elements per column
494  std::vector<size_t> nonzeros( n, 0UL );
495  for( size_t i=0UL; i<m; ++i )
496  {
497  const LeftIterator lend( A.end(i) );
498  const RightIterator rend( B.end(i) );
499 
500  LeftIterator l( A.begin(i) );
501  RightIterator r( B.begin(i) );
502 
503  while( l != lend && r != rend )
504  {
505  if( l->index() < r->index() ) {
506  ++nonzeros[l->index()];
507  ++l;
508  }
509  else if( l->index() > r->index() ) {
510  ++nonzeros[r->index()];
511  ++r;
512  }
513  else {
514  ++nonzeros[l->index()];
515  ++l;
516  ++r;
517  }
518  }
519 
520  while( l != lend ) {
521  ++nonzeros[l->index()];
522  ++l;
523  }
524 
525  while( r != rend ) {
526  ++nonzeros[r->index()];
527  ++r;
528  }
529  }
530 
531  // Resizing the left-hand side sparse matrix
532  for( size_t j=0UL; j<n; ++j ) {
533  (~lhs).reserve( j, nonzeros[j] );
534  }
535 
536  // Performing the matrix subtraction
537  for( size_t i=0UL; i<m; ++i )
538  {
539  const LeftIterator lend( A.end(i) );
540  const RightIterator rend( B.end(i) );
541 
542  LeftIterator l( A.begin(i) );
543  RightIterator r( B.begin(i) );
544 
545  while( l != lend && r != rend )
546  {
547  if( l->index() < r->index() ) {
548  (~lhs).append( i, l->index(), l->value() );
549  ++l;
550  }
551  else if( l->index() > r->index() ) {
552  (~lhs).append( i, r->index(), -r->value() );
553  ++r;
554  }
555  else {
556  (~lhs).append( i, l->index(), l->value()-r->value() );
557  ++l;
558  ++r;
559  }
560  }
561 
562  while( l != lend ) {
563  (~lhs).append( i, l->index(), l->value() );
564  ++l;
565  }
566 
567  while( r != rend ) {
568  (~lhs).append( i, r->index(), -r->value() );
569  ++r;
570  }
571  }
572  }
574  //**********************************************************************************************
575 
576  //**Assignment to column-major sparse matrices**************************************************
588  template< typename MT > // Type of the target sparse matrix
589  friend inline EnableIf_< UseSymmetricKernel<MT,MT1,MT2> >
590  assign( SparseMatrix<MT,true>& lhs, const SMatSMatSubExpr& rhs )
591  {
593 
595 
596  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
597  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
598 
599  assign( ~lhs, trans( rhs.lhs_ ) - trans( rhs.rhs_ ) );
600  }
602  //**********************************************************************************************
603 
604  //**Addition assignment to dense matrices*******************************************************
616  template< typename MT // Type of the target dense matrix
617  , bool SO > // Storage order of the target dense matrix
618  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
619  {
621 
622  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
623  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
624 
625  addAssign( ~lhs, rhs.lhs_ );
626  subAssign( ~lhs, rhs.rhs_ );
627  }
629  //**********************************************************************************************
630 
631  //**Addition assignment to sparse matrices******************************************************
632  // No special implementation for the addition assignment to sparse matrices.
633  //**********************************************************************************************
634 
635  //**Subtraction assignment to dense matrices****************************************************
647  template< typename MT // Type of the target dense matrix
648  , bool SO > // Storage order of the target dense matrix
649  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
650  {
652 
653  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
654  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
655 
656  subAssign( ~lhs, rhs.lhs_ );
657  addAssign( ~lhs, rhs.rhs_ );
658  }
660  //**********************************************************************************************
661 
662  //**Subtraction assignment to sparse matrices***************************************************
663  // No special implementation for the subtraction assignment to sparse matrices.
664  //**********************************************************************************************
665 
666  //**Multiplication assignment to dense matrices*************************************************
667  // No special implementation for the multiplication assignment to dense matrices.
668  //**********************************************************************************************
669 
670  //**Multiplication assignment to sparse matrices************************************************
671  // No special implementation for the multiplication assignment to sparse matrices.
672  //**********************************************************************************************
673 
674  //**SMP assignment to dense matrices************************************************************
675  // No special implementation for the SMP assignment to dense matrices.
676  //**********************************************************************************************
677 
678  //**SMP assignment to sparse matrices***********************************************************
679  // No special implementation for the SMP assignment to sparse matrices.
680  //**********************************************************************************************
681 
682  //**SMP addition assignment to dense matrices***************************************************
696  template< typename MT // Type of the target dense matrix
697  , bool SO > // Storage order of the target dense matrix
698  friend inline EnableIf_< UseSMPAssign<MT> >
699  smpAddAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
700  {
702 
703  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
704  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
705 
706  smpAddAssign( ~lhs, rhs.lhs_ );
707  smpSubAssign( ~lhs, rhs.rhs_ );
708  }
710  //**********************************************************************************************
711 
712  //**SMP addition assignment to sparse matrices**************************************************
713  // No special implementation for the SMP addition assignment to sparse matrices.
714  //**********************************************************************************************
715 
716  //**SMP subtraction assignment to dense matrices************************************************
731  template< typename MT // Type of the target dense matrix
732  , bool SO > // Storage order of the target dense matrix
733  friend inline EnableIf_< UseSMPAssign<MT> >
734  smpSubAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
735  {
737 
738  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
739  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
740 
741  smpSubAssign( ~lhs, rhs.lhs_ );
742  smpAddAssign( ~lhs, rhs.rhs_ );
743  }
745  //**********************************************************************************************
746 
747  //**SMP subtraction assignment to sparse matrices***********************************************
748  // No special implementation for the SMP subtraction assignment to sparse matrices.
749  //**********************************************************************************************
750 
751  //**SMP multiplication assignment to dense matrices*********************************************
752  // No special implementation for the SMP multiplication assignment to dense matrices.
753  //**********************************************************************************************
754 
755  //**SMP multiplication assignment to sparse matrices********************************************
756  // No special implementation for the SMP multiplication assignment to sparse matrices.
757  //**********************************************************************************************
758 
759  //**Compile time checks*************************************************************************
767  //**********************************************************************************************
768 };
769 //*************************************************************************************************
770 
771 
772 
773 
774 //=================================================================================================
775 //
776 // GLOBAL BINARY ARITHMETIC OPERATORS
777 //
778 //=================================================================================================
779 
780 //*************************************************************************************************
806 template< typename T1 // Type of the left-hand side sparse matrix
807  , typename T2 > // Type of the right-hand side sparse matrix
808 inline const SMatSMatSubExpr<T1,T2>
810 {
812 
813  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
814  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
815  }
816 
817  return SMatSMatSubExpr<T1,T2>( ~lhs, ~rhs );
818 }
819 //*************************************************************************************************
820 
821 
822 
823 
824 //=================================================================================================
825 //
826 // ROWS SPECIALIZATIONS
827 //
828 //=================================================================================================
829 
830 //*************************************************************************************************
832 template< typename MT1, typename MT2 >
833 struct Rows< SMatSMatSubExpr<MT1,MT2> >
834  : public Max< Rows<MT1>, Rows<MT2> >
835 {};
837 //*************************************************************************************************
838 
839 
840 
841 
842 //=================================================================================================
843 //
844 // COLUMNS SPECIALIZATIONS
845 //
846 //=================================================================================================
847 
848 //*************************************************************************************************
850 template< typename MT1, typename MT2 >
851 struct Columns< SMatSMatSubExpr<MT1,MT2> >
852  : public Max< Columns<MT1>, Columns<MT2> >
853 {};
855 //*************************************************************************************************
856 
857 
858 
859 
860 //=================================================================================================
861 //
862 // ISSYMMETRIC SPECIALIZATIONS
863 //
864 //=================================================================================================
865 
866 //*************************************************************************************************
868 template< typename MT1, typename MT2 >
869 struct IsSymmetric< SMatSMatSubExpr<MT1,MT2> >
870  : public BoolConstant< IsSymmetric<MT1>::value && IsSymmetric<MT2>::value >
871 {};
873 //*************************************************************************************************
874 
875 
876 
877 
878 //=================================================================================================
879 //
880 // ISHERMITIAN SPECIALIZATIONS
881 //
882 //=================================================================================================
883 
884 //*************************************************************************************************
886 template< typename MT1, typename MT2 >
887 struct IsHermitian< SMatSMatSubExpr<MT1,MT2> >
888  : public BoolConstant< IsHermitian<MT1>::value && IsHermitian<MT2>::value >
889 {};
891 //*************************************************************************************************
892 
893 
894 
895 
896 //=================================================================================================
897 //
898 // ISLOWER SPECIALIZATIONS
899 //
900 //=================================================================================================
901 
902 //*************************************************************************************************
904 template< typename MT1, typename MT2 >
905 struct IsLower< SMatSMatSubExpr<MT1,MT2> >
906  : public BoolConstant< And< IsLower<MT1>, IsLower<MT2> >::value >
907 {};
909 //*************************************************************************************************
910 
911 
912 
913 
914 //=================================================================================================
915 //
916 // ISUNILOWER SPECIALIZATIONS
917 //
918 //=================================================================================================
919 
920 //*************************************************************************************************
922 template< typename MT1, typename MT2 >
923 struct IsUniLower< SMatSMatSubExpr<MT1,MT2> >
924  : public BoolConstant< And< IsUniLower<MT1>, IsStrictlyLower<MT2> >::value >
925 {};
927 //*************************************************************************************************
928 
929 
930 
931 
932 //=================================================================================================
933 //
934 // ISSTRICTLYLOWER SPECIALIZATIONS
935 //
936 //=================================================================================================
937 
938 //*************************************************************************************************
940 template< typename MT1, typename MT2 >
941 struct IsStrictlyLower< SMatSMatSubExpr<MT1,MT2> >
942  : public BoolConstant< And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >::value >
943 {};
945 //*************************************************************************************************
946 
947 
948 
949 
950 //=================================================================================================
951 //
952 // ISUPPER SPECIALIZATIONS
953 //
954 //=================================================================================================
955 
956 //*************************************************************************************************
958 template< typename MT1, typename MT2 >
959 struct IsUpper< SMatSMatSubExpr<MT1,MT2> >
960  : public BoolConstant< And< IsUpper<MT1>, IsUpper<MT2> >::value >
961 {};
963 //*************************************************************************************************
964 
965 
966 
967 
968 //=================================================================================================
969 //
970 // ISUNIUPPER SPECIALIZATIONS
971 //
972 //=================================================================================================
973 
974 //*************************************************************************************************
976 template< typename MT1, typename MT2 >
977 struct IsUniUpper< SMatSMatSubExpr<MT1,MT2> >
978  : public BoolConstant< And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >::value >
979 {};
981 //*************************************************************************************************
982 
983 
984 
985 
986 //=================================================================================================
987 //
988 // ISSTRICTLYUPPER SPECIALIZATIONS
989 //
990 //=================================================================================================
991 
992 //*************************************************************************************************
994 template< typename MT1, typename MT2 >
995 struct IsStrictlyUpper< SMatSMatSubExpr<MT1,MT2> >
996  : public BoolConstant< And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >::value >
997 {};
999 //*************************************************************************************************
1000 
1001 
1002 
1003 
1004 //=================================================================================================
1005 //
1006 // EXPRESSION TRAIT SPECIALIZATIONS
1007 //
1008 //=================================================================================================
1009 
1010 //*************************************************************************************************
1012 template< typename MT1, typename MT2, bool AF >
1013 struct SubmatrixExprTrait< SMatSMatSubExpr<MT1,MT2>, AF >
1014 {
1015  public:
1016  //**********************************************************************************************
1017  using Type = SubExprTrait_< SubmatrixExprTrait_<const MT1,AF>
1018  , SubmatrixExprTrait_<const MT2,AF> >;
1019  //**********************************************************************************************
1020 };
1022 //*************************************************************************************************
1023 
1024 
1025 //*************************************************************************************************
1027 template< typename MT1, typename MT2 >
1028 struct RowExprTrait< SMatSMatSubExpr<MT1,MT2> >
1029 {
1030  public:
1031  //**********************************************************************************************
1032  using Type = SubExprTrait_< RowExprTrait_<const MT1>
1033  , RowExprTrait_<const MT2> >;
1034  //**********************************************************************************************
1035 };
1037 //*************************************************************************************************
1038 
1039 
1040 //*************************************************************************************************
1042 template< typename MT1, typename MT2 >
1043 struct ColumnExprTrait< SMatSMatSubExpr<MT1,MT2> >
1044 {
1045  public:
1046  //**********************************************************************************************
1047  using Type = SubExprTrait_< ColumnExprTrait_<const MT1>
1048  , ColumnExprTrait_<const MT2> >;
1049  //**********************************************************************************************
1050 };
1052 //*************************************************************************************************
1053 
1054 } // namespace blaze
1055 
1056 #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
Header file for auxiliary alias declarations.
Header file for the Max class template.
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:70
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatSubExpr.h:208
Header file for basic type definitions.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatSubExpr.h:172
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:160
Header file for the serial shim.
Header file for the ColumnExprTrait class template.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatSMatSubExpr.h:239
SMatSMatSubExpr< MT1, MT2 > This
Type of this SMatSMatSubExpr instance.
Definition: SMatSMatSubExpr.h:162
Header file for the And class template.
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
Header file for the Computation base class.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
Constraints on the storage order of matrix types.
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:323
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:129
SubExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: SMatSMatSubExpr.h:128
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
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:343
Header file for the SparseMatrix base class.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatSubExpr.h:280
typename SubExprTrait< T1, T2 >::Type SubExprTrait_
Auxiliary alias declaration for the SubExprTrait class template.The SubExprTrait_ alias declaration p...
Definition: SubExprTrait.h:220
Constraint on the data type.
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
ReturnType_< MT2 > RN2
ReturnType type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:113
#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 Columns type trait.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Header file for the MatMatSubExpr base class.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatSubExpr.h:223
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatSubExpr.h:302
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.
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:111
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatSMatSubExpr.h:249
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:254
LeftOperand lhs_
Left-hand side sparse matrix of the subtraction expression.
Definition: SMatSMatSubExpr.h:321
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
If_< IsExpression< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:178
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatSMatSubExpr.h:169
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatSubExpr.h:314
ReturnType_< MT1 > RN1
ReturnType type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:112
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:110
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:114
#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
Header file for the SubmatrixExprTrait class template.
#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.
Expression object for sparse matrix-sparse matrix subtractions.The SMatSMatSubExpr class represents t...
Definition: Forward.h:100
RightOperand rhs_
Right-hand side sparse matrix of the subtraction expression.
Definition: SMatSMatSubExpr.h:322
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:160
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatSMatSubExpr.h:166
If_< IsExpression< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:175
Header file for the isDefault shim.
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatSubExpr.h:164
Constraint on the data type.
Constraints on the storage order of matrix types.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
Header file for the RemoveReference type trait.
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatSubExpr.h:259
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:115
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
SubTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatSMatSubExpr.h:163
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
Header file for the IsComputation type trait class.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatSubExpr.h:270
typename SubTrait< T1, T2 >::Type SubTrait_
Auxiliary alias declaration for the SubTrait class template.The SubTrait_ alias declaration provides ...
Definition: SubTrait.h:245
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
SMatSMatSubExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatSMatSubExpr class.
Definition: SMatSMatSubExpr.h:192
Header file for the IntegralConstant class template.
#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:109
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
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 SubExprTrait class template.
#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
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatSubExpr.h:290
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatSubExpr.h:165