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 
73 #include <blaze/util/Assert.h>
74 #include <blaze/util/DisableIf.h>
75 #include <blaze/util/EnableIf.h>
76 #include <blaze/util/Exception.h>
78 #include <blaze/util/mpl/And.h>
79 #include <blaze/util/mpl/Max.h>
80 #include <blaze/util/SelectType.h>
81 #include <blaze/util/Types.h>
84 
85 
86 namespace blaze {
87 
88 //=================================================================================================
89 //
90 // CLASS SMATSMATSUBEXPR
91 //
92 //=================================================================================================
93 
94 //*************************************************************************************************
101 template< typename MT1 // Type of the left-hand side sparse matrix
102  , typename MT2 > // Type of the right-hand side sparse matrix
103 class SMatSMatSubExpr : public SparseMatrix< SMatSMatSubExpr<MT1,MT2>, false >
104  , private MatMatSubExpr
105  , private Computation
106 {
107  private:
108  //**Type definitions****************************************************************************
109  typedef typename MT1::ResultType RT1;
110  typedef typename MT2::ResultType RT2;
111  typedef typename MT1::ReturnType RN1;
112  typedef typename MT2::ReturnType RN2;
113  typedef typename MT1::CompositeType CT1;
114  typedef typename MT2::CompositeType CT2;
115  //**********************************************************************************************
116 
117  //**Return type evaluation**********************************************************************
119 
124  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
125 
128  //**********************************************************************************************
129 
130  //**Serial evaluation strategy******************************************************************
132 
137  template< typename T1, typename T2, typename T3 >
138  struct UseSymmetricKernel {
141  };
143  //**********************************************************************************************
144 
145  //**Parallel evaluation strategy****************************************************************
147 
152  template< typename MT >
153  struct UseSMPAssign {
154  enum { value = MT::smpAssignable };
155  };
157  //**********************************************************************************************
158 
159  public:
160  //**Type definitions****************************************************************************
166 
169 
171  typedef const ResultType CompositeType;
172 
174  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
175 
177  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
178  //**********************************************************************************************
179 
180  //**Compilation flags***************************************************************************
182  enum { smpAssignable = 0 };
183  //**********************************************************************************************
184 
185  //**Constructor*********************************************************************************
191  explicit inline SMatSMatSubExpr( const MT1& lhs, const MT2& rhs )
192  : lhs_( lhs ) // Left-hand side sparse matrix of the subtraction expression
193  , rhs_( rhs ) // Right-hand side sparse matrix of the subtraction expression
194  {
195  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
196  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
197  }
198  //**********************************************************************************************
199 
200  //**Access operator*****************************************************************************
207  inline ReturnType operator()( size_t i, size_t j ) const {
208  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
209  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
210  return lhs_(i,j) - rhs_(i,j);
211  }
212  //**********************************************************************************************
213 
214  //**At function*********************************************************************************
222  inline ReturnType at( size_t i, size_t j ) const {
223  if( i >= lhs_.rows() ) {
224  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
225  }
226  if( j >= lhs_.columns() ) {
227  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
228  }
229  return (*this)(i,j);
230  }
231  //**********************************************************************************************
232 
233  //**Rows function*******************************************************************************
238  inline size_t rows() const {
239  return lhs_.rows();
240  }
241  //**********************************************************************************************
242 
243  //**Columns function****************************************************************************
248  inline size_t columns() const {
249  return lhs_.columns();
250  }
251  //**********************************************************************************************
252 
253  //**NonZeros function***************************************************************************
258  inline size_t nonZeros() const {
259  return lhs_.nonZeros() + rhs_.nonZeros();
260  }
261  //**********************************************************************************************
262 
263  //**NonZeros function***************************************************************************
269  inline size_t nonZeros( size_t i ) const {
270  return lhs_.nonZeros(i) + rhs_.nonZeros(i);
271  }
272  //**********************************************************************************************
273 
274  //**Left operand access*************************************************************************
279  inline LeftOperand leftOperand() const {
280  return lhs_;
281  }
282  //**********************************************************************************************
283 
284  //**Right operand access************************************************************************
289  inline RightOperand rightOperand() const {
290  return rhs_;
291  }
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
300  template< typename T >
301  inline bool canAlias( const T* alias ) const {
302  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
303  }
304  //**********************************************************************************************
305 
306  //**********************************************************************************************
312  template< typename T >
313  inline bool isAliased( const T* alias ) const {
314  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
315  }
316  //**********************************************************************************************
317 
318  private:
319  //**Member variables****************************************************************************
320  LeftOperand lhs_;
321  RightOperand rhs_;
322  //**********************************************************************************************
323 
324  //**Assignment to dense matrices****************************************************************
336  template< typename MT // Type of the target dense matrix
337  , bool SO > // Storage order of the target dense matrix
338  friend inline void assign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
339  {
341 
342  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
343  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
344 
345  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
346 
347  assign( ~lhs, rhs.lhs_ );
348 
350  subAssign( ~lhs, rhs.rhs_ );
351  }
352  else
353  {
354  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
355 
356  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
358  BLAZE_INTERNAL_ASSERT( B.rows() == (~lhs).rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
360 
361  for( size_t i=0UL; i<(~lhs).rows(); ++i ) {
362  const RightIterator end( B.end(i) );
363  for( RightIterator element=B.begin(i); element!=end; ++element ) {
364  if( isDefault( (~lhs)(i,element->index()) ) )
365  (~lhs)(i,element->index()) = -element->value();
366  else
367  (~lhs)(i,element->index()) -= element->value();
368  }
369  }
370  }
371  }
373  //**********************************************************************************************
374 
375  //**Assignment to row-major sparse matrices*****************************************************
387  template< typename MT > // Type of the target sparse matrix
388  friend inline void assign( SparseMatrix<MT,false>& lhs, const SMatSMatSubExpr& rhs )
389  {
391 
392  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
393  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
394 
395  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
396  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
397 
398  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
399  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
400 
401  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
402  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
403  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
404  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
405  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
406  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
407 
408  // Final memory allocation (based on the evaluated operands)
409  (~lhs).reserve( A.nonZeros() + B.nonZeros() );
410 
411  // Performing the matrix subtraction
412  for( size_t i=0UL; i<(~lhs).rows(); ++i )
413  {
414  const LeftIterator lend( A.end(i) );
415  const RightIterator rend( B.end(i) );
416 
417  LeftIterator l( A.begin(i) );
418  RightIterator r( B.begin(i) );
419 
420  while( l != lend && r != rend )
421  {
422  if( l->index() < r->index() ) {
423  (~lhs).append( i, l->index(), l->value() );
424  ++l;
425  }
426  else if( l->index() > r->index() ) {
427  (~lhs).append( i, r->index(), -r->value() );
428  ++r;
429  }
430  else {
431  (~lhs).append( i, l->index(), l->value()-r->value() );
432  ++l;
433  ++r;
434  }
435  }
436 
437  while( l != lend ) {
438  (~lhs).append( i, l->index(), l->value() );
439  ++l;
440  }
441 
442  while( r != rend ) {
443  (~lhs).append( i, r->index(), -r->value() );
444  ++r;
445  }
446 
447  (~lhs).finalize( i );
448  }
449  }
451  //**********************************************************************************************
452 
453  //**Assignment to column-major sparse matrices**************************************************
465  template< typename MT > // Type of the target sparse matrix
466  friend inline typename DisableIf< UseSymmetricKernel<MT,MT1,MT2> >::Type
467  assign( SparseMatrix<MT,true>& lhs, const SMatSMatSubExpr& rhs )
468  {
470 
472 
473  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
474  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
475 
476  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
477  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
478 
479  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
480  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
481 
482  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
483  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
484  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
485  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
486  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
487  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
488 
489  const size_t m( rhs.rows() );
490  const size_t n( rhs.columns() );
491 
492  // Counting the number of elements per column
493  std::vector<size_t> nonzeros( n, 0UL );
494  for( size_t i=0UL; i<m; ++i )
495  {
496  const LeftIterator lend( A.end(i) );
497  const RightIterator rend( B.end(i) );
498 
499  LeftIterator l( A.begin(i) );
500  RightIterator r( B.begin(i) );
501 
502  while( l != lend && r != rend )
503  {
504  if( l->index() < r->index() ) {
505  ++nonzeros[l->index()];
506  ++l;
507  }
508  else if( l->index() > r->index() ) {
509  ++nonzeros[r->index()];
510  ++r;
511  }
512  else {
513  ++nonzeros[l->index()];
514  ++l;
515  ++r;
516  }
517  }
518 
519  while( l != lend ) {
520  ++nonzeros[l->index()];
521  ++l;
522  }
523 
524  while( r != rend ) {
525  ++nonzeros[r->index()];
526  ++r;
527  }
528  }
529 
530  // Resizing the left-hand side sparse matrix
531  for( size_t j=0UL; j<n; ++j ) {
532  (~lhs).reserve( j, nonzeros[j] );
533  }
534 
535  // Performing the matrix subtraction
536  for( size_t i=0UL; i<m; ++i )
537  {
538  const LeftIterator lend( A.end(i) );
539  const RightIterator rend( B.end(i) );
540 
541  LeftIterator l( A.begin(i) );
542  RightIterator r( B.begin(i) );
543 
544  while( l != lend && r != rend )
545  {
546  if( l->index() < r->index() ) {
547  (~lhs).append( i, l->index(), l->value() );
548  ++l;
549  }
550  else if( l->index() > r->index() ) {
551  (~lhs).append( i, r->index(), -r->value() );
552  ++r;
553  }
554  else {
555  (~lhs).append( i, l->index(), l->value()-r->value() );
556  ++l;
557  ++r;
558  }
559  }
560 
561  while( l != lend ) {
562  (~lhs).append( i, l->index(), l->value() );
563  ++l;
564  }
565 
566  while( r != rend ) {
567  (~lhs).append( i, r->index(), -r->value() );
568  ++r;
569  }
570  }
571  }
573  //**********************************************************************************************
574 
575  //**Assignment to column-major sparse matrices**************************************************
587  template< typename MT > // Type of the target sparse matrix
588  friend inline typename EnableIf< UseSymmetricKernel<MT,MT1,MT2> >::Type
589  assign( SparseMatrix<MT,true>& lhs, const SMatSMatSubExpr& rhs )
590  {
592 
594 
595  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
596  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
597 
598  assign( ~lhs, trans( rhs.lhs_ ) - trans( rhs.rhs_ ) );
599  }
601  //**********************************************************************************************
602 
603  //**Addition assignment to dense matrices*******************************************************
615  template< typename MT // Type of the target dense matrix
616  , bool SO > // Storage order of the target dense matrix
617  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
618  {
620 
621  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
622  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
623 
624  addAssign( ~lhs, rhs.lhs_ );
625  subAssign( ~lhs, rhs.rhs_ );
626  }
628  //**********************************************************************************************
629 
630  //**Addition assignment to sparse matrices******************************************************
631  // No special implementation for the addition assignment to sparse matrices.
632  //**********************************************************************************************
633 
634  //**Subtraction assignment to dense matrices****************************************************
646  template< typename MT // Type of the target dense matrix
647  , bool SO > // Storage order of the target dense matrix
648  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
649  {
651 
652  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
653  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
654 
655  subAssign( ~lhs, rhs.lhs_ );
656  addAssign( ~lhs, rhs.rhs_ );
657  }
659  //**********************************************************************************************
660 
661  //**Subtraction assignment to sparse matrices***************************************************
662  // No special implementation for the subtraction assignment to sparse matrices.
663  //**********************************************************************************************
664 
665  //**Multiplication assignment to dense matrices*************************************************
666  // No special implementation for the multiplication assignment to dense matrices.
667  //**********************************************************************************************
668 
669  //**Multiplication assignment to sparse matrices************************************************
670  // No special implementation for the multiplication assignment to sparse matrices.
671  //**********************************************************************************************
672 
673  //**SMP assignment to dense matrices************************************************************
674  // No special implementation for the SMP assignment to dense matrices.
675  //**********************************************************************************************
676 
677  //**SMP assignment to sparse matrices***********************************************************
678  // No special implementation for the SMP assignment to sparse matrices.
679  //**********************************************************************************************
680 
681  //**SMP addition assignment to dense matrices***************************************************
695  template< typename MT // Type of the target dense matrix
696  , bool SO > // Storage order of the target dense matrix
697  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
698  smpAddAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
699  {
701 
702  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
703  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
704 
705  smpAddAssign( ~lhs, rhs.lhs_ );
706  smpSubAssign( ~lhs, rhs.rhs_ );
707  }
709  //**********************************************************************************************
710 
711  //**SMP addition assignment to sparse matrices**************************************************
712  // No special implementation for the SMP addition assignment to sparse matrices.
713  //**********************************************************************************************
714 
715  //**SMP subtraction assignment to dense matrices************************************************
730  template< typename MT // Type of the target dense matrix
731  , bool SO > // Storage order of the target dense matrix
732  friend inline typename EnableIf< UseSMPAssign<MT> >::Type
733  smpSubAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSubExpr& rhs )
734  {
736 
737  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
738  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
739 
740  smpSubAssign( ~lhs, rhs.lhs_ );
741  smpAddAssign( ~lhs, rhs.rhs_ );
742  }
744  //**********************************************************************************************
745 
746  //**SMP subtraction assignment to sparse matrices***********************************************
747  // No special implementation for the SMP subtraction assignment to sparse matrices.
748  //**********************************************************************************************
749 
750  //**SMP multiplication assignment to dense matrices*********************************************
751  // No special implementation for the SMP multiplication assignment to dense matrices.
752  //**********************************************************************************************
753 
754  //**SMP multiplication assignment to sparse matrices********************************************
755  // No special implementation for the SMP multiplication assignment to sparse matrices.
756  //**********************************************************************************************
757 
758  //**Compile time checks*************************************************************************
766  //**********************************************************************************************
767 };
768 //*************************************************************************************************
769 
770 
771 
772 
773 //=================================================================================================
774 //
775 // GLOBAL BINARY ARITHMETIC OPERATORS
776 //
777 //=================================================================================================
778 
779 //*************************************************************************************************
805 template< typename T1 // Type of the left-hand side sparse matrix
806  , typename T2 > // Type of the right-hand side sparse matrix
807 inline const SMatSMatSubExpr<T1,T2>
809 {
811 
812  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
813  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
814  }
815 
816  return SMatSMatSubExpr<T1,T2>( ~lhs, ~rhs );
817 }
818 //*************************************************************************************************
819 
820 
821 
822 
823 //=================================================================================================
824 //
825 // ROWS SPECIALIZATIONS
826 //
827 //=================================================================================================
828 
829 //*************************************************************************************************
831 template< typename MT1, typename MT2 >
832 struct Rows< SMatSMatSubExpr<MT1,MT2> >
833  : public Max< Rows<MT1>, Rows<MT2> >
834 {};
836 //*************************************************************************************************
837 
838 
839 
840 
841 //=================================================================================================
842 //
843 // COLUMNS SPECIALIZATIONS
844 //
845 //=================================================================================================
846 
847 //*************************************************************************************************
849 template< typename MT1, typename MT2 >
850 struct Columns< SMatSMatSubExpr<MT1,MT2> >
851  : public Max< Columns<MT1>, Columns<MT2> >
852 {};
854 //*************************************************************************************************
855 
856 
857 
858 
859 //=================================================================================================
860 //
861 // ISSYMMETRIC SPECIALIZATIONS
862 //
863 //=================================================================================================
864 
865 //*************************************************************************************************
867 template< typename MT1, typename MT2 >
868 struct IsSymmetric< SMatSMatSubExpr<MT1,MT2> >
869  : public IsTrue< IsSymmetric<MT1>::value && IsSymmetric<MT2>::value >
870 {};
872 //*************************************************************************************************
873 
874 
875 
876 
877 //=================================================================================================
878 //
879 // ISHERMITIAN SPECIALIZATIONS
880 //
881 //=================================================================================================
882 
883 //*************************************************************************************************
885 template< typename MT1, typename MT2 >
886 struct IsHermitian< SMatSMatSubExpr<MT1,MT2> >
887  : public IsTrue< IsHermitian<MT1>::value && IsHermitian<MT2>::value >
888 {};
890 //*************************************************************************************************
891 
892 
893 
894 
895 //=================================================================================================
896 //
897 // ISLOWER SPECIALIZATIONS
898 //
899 //=================================================================================================
900 
901 //*************************************************************************************************
903 template< typename MT1, typename MT2 >
904 struct IsLower< SMatSMatSubExpr<MT1,MT2> >
905  : public IsTrue< And< IsLower<MT1>, IsLower<MT2> >::value >
906 {};
908 //*************************************************************************************************
909 
910 
911 
912 
913 //=================================================================================================
914 //
915 // ISUNILOWER SPECIALIZATIONS
916 //
917 //=================================================================================================
918 
919 //*************************************************************************************************
921 template< typename MT1, typename MT2 >
922 struct IsUniLower< SMatSMatSubExpr<MT1,MT2> >
923  : public IsTrue< And< IsUniLower<MT1>, IsStrictlyLower<MT2> >::value >
924 {};
926 //*************************************************************************************************
927 
928 
929 
930 
931 //=================================================================================================
932 //
933 // ISSTRICTLYLOWER SPECIALIZATIONS
934 //
935 //=================================================================================================
936 
937 //*************************************************************************************************
939 template< typename MT1, typename MT2 >
940 struct IsStrictlyLower< SMatSMatSubExpr<MT1,MT2> >
941  : public IsTrue< And< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >::value >
942 {};
944 //*************************************************************************************************
945 
946 
947 
948 
949 //=================================================================================================
950 //
951 // ISUPPER SPECIALIZATIONS
952 //
953 //=================================================================================================
954 
955 //*************************************************************************************************
957 template< typename MT1, typename MT2 >
958 struct IsUpper< SMatSMatSubExpr<MT1,MT2> >
959  : public IsTrue< And< IsUpper<MT1>, IsUpper<MT2> >::value >
960 {};
962 //*************************************************************************************************
963 
964 
965 
966 
967 //=================================================================================================
968 //
969 // ISUNIUPPER SPECIALIZATIONS
970 //
971 //=================================================================================================
972 
973 //*************************************************************************************************
975 template< typename MT1, typename MT2 >
976 struct IsUniUpper< SMatSMatSubExpr<MT1,MT2> >
977  : public IsTrue< And< IsUniUpper<MT1>, IsStrictlyUpper<MT2> >::value >
978 {};
980 //*************************************************************************************************
981 
982 
983 
984 
985 //=================================================================================================
986 //
987 // ISSTRICTLYUPPER SPECIALIZATIONS
988 //
989 //=================================================================================================
990 
991 //*************************************************************************************************
993 template< typename MT1, typename MT2 >
994 struct IsStrictlyUpper< SMatSMatSubExpr<MT1,MT2> >
995  : public IsTrue< And< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >::value >
996 {};
998 //*************************************************************************************************
999 
1000 
1001 
1002 
1003 //=================================================================================================
1004 //
1005 // EXPRESSION TRAIT SPECIALIZATIONS
1006 //
1007 //=================================================================================================
1008 
1009 //*************************************************************************************************
1011 template< typename MT1, typename MT2, bool AF >
1012 struct SubmatrixExprTrait< SMatSMatSubExpr<MT1,MT2>, AF >
1013 {
1014  public:
1015  //**********************************************************************************************
1016  typedef typename SubExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1017  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1018  //**********************************************************************************************
1019 };
1021 //*************************************************************************************************
1022 
1023 
1024 //*************************************************************************************************
1026 template< typename MT1, typename MT2 >
1027 struct RowExprTrait< SMatSMatSubExpr<MT1,MT2> >
1028 {
1029  public:
1030  //**********************************************************************************************
1031  typedef typename SubExprTrait< typename RowExprTrait<const MT1>::Type
1032  , typename RowExprTrait<const MT2>::Type >::Type Type;
1033  //**********************************************************************************************
1034 };
1036 //*************************************************************************************************
1037 
1038 
1039 //*************************************************************************************************
1041 template< typename MT1, typename MT2 >
1042 struct ColumnExprTrait< SMatSMatSubExpr<MT1,MT2> >
1043 {
1044  public:
1045  //**********************************************************************************************
1046  typedef typename SubExprTrait< typename ColumnExprTrait<const MT1>::Type
1047  , typename ColumnExprTrait<const MT2>::Type >::Type Type;
1048  //**********************************************************************************************
1049 };
1051 //*************************************************************************************************
1052 
1053 } // namespace blaze
1054 
1055 #endif
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatSubExpr.h:289
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
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:87
Header file for the Rows type trait.
Header file for the IsUniUpper type trait.
SubExprTrait< RN1, RN2 >::Type ExprReturnType
Expression return type for the subscript operator.
Definition: SMatSMatSubExpr.h:127
Header file for the subtraction trait.
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:114
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatSubExpr.h:207
Header file for basic type definitions.
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:250
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatSubExpr.h:171
SMatSMatSubExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the SMatSMatSubExpr class.
Definition: SMatSMatSubExpr.h:191
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
MT2::ReturnType RN2
ReturnType type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:112
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SMatSMatSubExpr.h:313
Header file for the ColumnExprTrait class template.
SMatSMatSubExpr< MT1, MT2 > This
Type of this SMatSMatSubExpr instance.
Definition: SMatSMatSubExpr.h:161
size_t rows() const
Returns the current number of rows of the matrix.
Definition: SMatSMatSubExpr.h:238
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatSubExpr.h:164
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
Header file for the And class template.
const SelectType< returnExpr, ExprReturnType, ElementType >::Type ReturnType
Return type for expression template evaluations.
Definition: SMatSMatSubExpr.h:168
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
Header file for the Computation base class.
Constraints on the storage order of matrix types.
MT1::CompositeType CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:113
Header file for the IsUniLower type trait.
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:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Header file for the SparseMatrix base class.
Constraint on the data type.
ResultType::ElementType ElementType
Resulting element type.
Definition: SMatSMatSubExpr.h:165
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatSubExpr.h:301
SubTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SMatSMatSubExpr.h:162
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
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
#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:79
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:110
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
Header file for the Columns type trait.
Header file for the MatMatSubExpr base class.
Header file for the IsLower type trait.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc)
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:642
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatSubExpr.h:222
MT1::ResultType RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:109
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Evaluation of the return type of a subtraction expression.Via this type trait it is possible to evalu...
Definition: SubExprTrait.h:104
LeftOperand lhs_
Left-hand side sparse matrix of the subtraction expression.
Definition: SMatSMatSubExpr.h:320
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the serial shim.
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
EnableIf< IsDenseMatrix< MT1 > >::Type 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
#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:116
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:79
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2587
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
Expression object for sparse matrix-sparse matrix subtractions.The SMatSMatSubExpr class represents t...
Definition: Forward.h:108
RightOperand rhs_
Right-hand side sparse matrix of the subtraction expression.
Definition: SMatSMatSubExpr.h:321
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:174
size_t columns() const
Returns the current number of columns of the matrix.
Definition: SMatSMatSubExpr.h:248
Header file for the isDefault shim.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatSubExpr.h:163
Constraint on the data type.
Constraints on the storage order of matrix types.
Header file for the RemoveReference type trait.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatSubExpr.h:258
LeftOperand leftOperand() const
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatSubExpr.h:279
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
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:269
EnableIf< IsDenseMatrix< MT1 > >::Type 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
#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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
Header file for the IsTrue value trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
#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:165
Base template for the SubTrait class.
Definition: SubTrait.h:138
Header file for the IsUpper type trait.
Header file for exception macros.
MT1::ReturnType RN1
ReturnType type of the left-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:111
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:79
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatSubExpr.h:177
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.