SMatScalarMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSCALARMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSCALARMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
70 #include <blaze/util/Assert.h>
73 #include <blaze/util/EnableIf.h>
75 #include <blaze/util/mpl/And.h>
76 #include <blaze/util/mpl/If.h>
77 #include <blaze/util/mpl/Or.h>
78 #include <blaze/util/Types.h>
81 
82 
83 namespace blaze {
84 
85 //=================================================================================================
86 //
87 // CLASS SMATSCALARMULTEXPR
88 //
89 //=================================================================================================
90 
91 //*************************************************************************************************
98 template< typename MT // Type of the left-hand side sparse matrix
99  , typename ST // Type of the right-hand side scalar value
100  , bool SO > // Storage order
101 class SMatScalarMultExpr
102  : public MatScalarMultExpr< SparseMatrix< SMatScalarMultExpr<MT,ST,SO>, SO > >
103  , private Computation
104 {
105  private:
106  //**Type definitions****************************************************************************
107  using RT = ResultType_<MT>;
108  using RN = ReturnType_<MT>;
110  //**********************************************************************************************
111 
112  //**Return type evaluation**********************************************************************
114 
119  enum : bool { returnExpr = !IsTemporary<RN>::value };
120 
123  //**********************************************************************************************
124 
125  //**Serial evaluation strategy******************************************************************
127 
133  enum : bool { useAssign = RequiresEvaluation<MT>::value };
134 
136  template< typename MT2 >
138  struct UseAssign {
139  enum : bool { value = useAssign };
140  };
142  //**********************************************************************************************
143 
144  //**Parallel evaluation strategy****************************************************************
146 
152  template< typename MT2 >
153  struct UseSMPAssign {
154  enum : bool { value = ( !MT2::smpAssignable || !MT::smpAssignable ) && useAssign };
155  };
157  //**********************************************************************************************
158 
159  public:
160  //**Type definitions****************************************************************************
166 
169 
172 
174  using LeftOperand = If_< IsExpression<MT>, const MT, const MT& >;
175 
177  using RightOperand = ST;
178  //**********************************************************************************************
179 
180  //**ConstIterator class definition**************************************************************
184  {
185  public:
186  //**Type definitions*************************************************************************
189 
192 
193  using IteratorCategory = std::forward_iterator_tag;
194  using ValueType = Element;
198 
199  // STL iterator requirements
205  //*******************************************************************************************
206 
207  //**Constructor******************************************************************************
210  inline ConstIterator( IteratorType matrix, RightOperand scalar )
211  : matrix_( matrix ) // Iterator over the elements of the left-hand side sparse matrix expression
212  , scalar_( scalar ) // Right-hand side scalar of the multiplication expression
213  {}
214  //*******************************************************************************************
215 
216  //**Prefix increment operator****************************************************************
222  ++matrix_;
223  return *this;
224  }
225  //*******************************************************************************************
226 
227  //**Element access operator******************************************************************
232  inline const Element operator*() const {
233  return Element( matrix_->value() * scalar_, matrix_->index() );
234  }
235  //*******************************************************************************************
236 
237  //**Element access operator******************************************************************
242  inline const ConstIterator* operator->() const {
243  return this;
244  }
245  //*******************************************************************************************
246 
247  //**Value function***************************************************************************
252  inline ReturnType value() const {
253  return matrix_->value() * scalar_;
254  }
255  //*******************************************************************************************
256 
257  //**Index function***************************************************************************
262  inline size_t index() const {
263  return matrix_->index();
264  }
265  //*******************************************************************************************
266 
267  //**Equality operator************************************************************************
273  inline bool operator==( const ConstIterator& rhs ) const {
274  return matrix_ == rhs.matrix_;
275  }
276  //*******************************************************************************************
277 
278  //**Inequality operator**********************************************************************
284  inline bool operator!=( const ConstIterator& rhs ) const {
285  return matrix_ != rhs.matrix_;
286  }
287  //*******************************************************************************************
288 
289  //**Subtraction operator*********************************************************************
295  inline DifferenceType operator-( const ConstIterator& rhs ) const {
296  return matrix_ - rhs.matrix_;
297  }
298  //*******************************************************************************************
299 
300  private:
301  //**Member variables*************************************************************************
304  //*******************************************************************************************
305  };
306  //**********************************************************************************************
307 
308  //**Compilation flags***************************************************************************
310  enum : bool { smpAssignable = false };
311  //**********************************************************************************************
312 
313  //**Constructor*********************************************************************************
319  explicit inline SMatScalarMultExpr( const MT& matrix, ST scalar ) noexcept
320  : matrix_( matrix ) // Left-hand side sparse matrix of the multiplication expression
321  , scalar_( scalar ) // Right-hand side scalar of the multiplication expression
322  {}
323  //**********************************************************************************************
324 
325  //**Access operator*****************************************************************************
332  inline ReturnType operator()( size_t i, size_t j ) const {
333  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
334  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
335  return matrix_(i,j) * scalar_;
336  }
337  //**********************************************************************************************
338 
339  //**At function*********************************************************************************
347  inline ReturnType at( size_t i, size_t j ) const {
348  if( i >= matrix_.rows() ) {
349  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
350  }
351  if( j >= matrix_.columns() ) {
352  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
353  }
354  return (*this)(i,j);
355  }
356  //**********************************************************************************************
357 
358  //**Begin function******************************************************************************
364  inline ConstIterator begin( size_t i ) const {
365  return ConstIterator( matrix_.begin(i), scalar_ );
366  }
367  //**********************************************************************************************
368 
369  //**End function********************************************************************************
375  inline ConstIterator end( size_t i ) const {
376  return ConstIterator( matrix_.end(i), scalar_ );
377  }
378  //**********************************************************************************************
379 
380  //**Rows function*******************************************************************************
385  inline size_t rows() const noexcept {
386  return matrix_.rows();
387  }
388  //**********************************************************************************************
389 
390  //**Columns function****************************************************************************
395  inline size_t columns() const noexcept {
396  return matrix_.columns();
397  }
398  //**********************************************************************************************
399 
400  //**NonZeros function***************************************************************************
405  inline size_t nonZeros() const {
406  return matrix_.nonZeros();
407  }
408  //**********************************************************************************************
409 
410  //**NonZeros function***************************************************************************
416  inline size_t nonZeros( size_t i ) const {
417  return matrix_.nonZeros(i);
418  }
419  //**********************************************************************************************
420 
421  //**Find function*******************************************************************************
428  inline ConstIterator find( size_t i, size_t j ) const {
430  return ConstIterator( matrix_.find( i, j ), scalar_ );
431  }
432  //**********************************************************************************************
433 
434  //**LowerBound function*************************************************************************
441  inline ConstIterator lowerBound( size_t i, size_t j ) const {
443  return ConstIterator( matrix_.lowerBound( i, j ), scalar_ );
444  }
445  //**********************************************************************************************
446 
447  //**UpperBound function*************************************************************************
454  inline ConstIterator upperBound( size_t i, size_t j ) const {
456  return ConstIterator( matrix_.upperBound( i, j ), scalar_ );
457  }
458  //**********************************************************************************************
459 
460  //**Left operand access*************************************************************************
465  inline LeftOperand leftOperand() const noexcept {
466  return matrix_;
467  }
468  //**********************************************************************************************
469 
470  //**Right operand access************************************************************************
475  inline RightOperand rightOperand() const noexcept {
476  return scalar_;
477  }
478  //**********************************************************************************************
479 
480  //**********************************************************************************************
486  template< typename T >
487  inline bool canAlias( const T* alias ) const noexcept {
488  return matrix_.canAlias( alias );
489  }
490  //**********************************************************************************************
491 
492  //**********************************************************************************************
498  template< typename T >
499  inline bool isAliased( const T* alias ) const noexcept {
500  return matrix_.isAliased( alias );
501  }
502  //**********************************************************************************************
503 
504  private:
505  //**Member variables****************************************************************************
508  //**********************************************************************************************
509 
510  //**Assignment to dense matrices****************************************************************
524  template< typename MT2 // Type of the target dense matrix
525  , bool SO2 > // Storage order of the target dense matrix
526  friend inline EnableIf_< UseAssign<MT2> >
527  assign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
528  {
530 
531  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
532  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
533 
534  assign( ~lhs, rhs.matrix_ );
535  (~lhs) *= rhs.scalar_;
536  }
538  //**********************************************************************************************
539 
540  //**Assignment to sparse matrices***************************************************************
554  template< typename MT2 // Type of the target sparse matrix
555  , bool SO2 > // Storage order of the target sparse matrix
556  friend inline EnableIf_< UseAssign<MT2> >
557  assign( SparseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
558  {
560 
561  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
562  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
563 
564  assign( ~lhs, rhs.matrix_ );
565  (~lhs) *= rhs.scalar_;
566  }
568  //**********************************************************************************************
569 
570  //**Addition assignment to dense matrices*******************************************************
584  template< typename MT2 // Type of the target dense matrix
585  , bool SO2 > // Storage order of the target dense matrix
586  friend inline EnableIf_< UseAssign<MT2> >
587  addAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
588  {
590 
593 
594  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
595  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
596 
597  const ResultType tmp( serial( rhs ) );
598  addAssign( ~lhs, tmp );
599  }
601  //**********************************************************************************************
602 
603  //**Addition assignment to sparse matrices******************************************************
604  // No special implementation for the addition assignment to sparse matrices.
605  //**********************************************************************************************
606 
607  //**Subtraction assignment to dense matrices****************************************************
621  template< typename MT2 // Type of the target dense matrix
622  , bool SO2 > // Storage order of the target dense matrix
623  friend inline EnableIf_< UseAssign<MT2> >
624  subAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
625  {
627 
630 
631  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
632  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
633 
634  const ResultType tmp( serial( rhs ) );
635  subAssign( ~lhs, tmp );
636  }
638  //**********************************************************************************************
639 
640  //**Subtraction assignment to sparse matrices***************************************************
641  // No special implementation for the subtraction assignment to sparse matrices.
642  //**********************************************************************************************
643 
644  //**Schur product assignment to dense matrices**************************************************
658  template< typename MT2 // Type of the target dense matrix
659  , bool SO2 > // Storage order of the target dense matrix
660  friend inline EnableIf_< UseAssign<MT2> >
661  schurAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
662  {
664 
667 
668  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
669  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
670 
671  const ResultType tmp( serial( rhs ) );
672  schurAssign( ~lhs, tmp );
673  }
675  //**********************************************************************************************
676 
677  //**Schur product assignment to sparse matrices*************************************************
678  // No special implementation for the Schur product assignment to sparse matrices.
679  //**********************************************************************************************
680 
681  //**Multiplication assignment to dense matrices*************************************************
682  // No special implementation for the multiplication assignment to dense matrices.
683  //**********************************************************************************************
684 
685  //**Multiplication assignment to sparse matrices************************************************
686  // No special implementation for the multiplication assignment to sparse matrices.
687  //**********************************************************************************************
688 
689  //**SMP assignment to dense matrices************************************************************
690  // No special implementation for the SMP assignment to dense matrices.
691  //**********************************************************************************************
692 
693  //**SMP assignment to sparse matrices***********************************************************
694  // No special implementation for the SMP assignment to sparse matrices.
695  //**********************************************************************************************
696 
697  //**SMP addition assignment to dense matrices***************************************************
711  template< typename MT2 // Type of the target dense matrix
712  , bool SO2 > // Storage order of the target dense matrix
713  friend inline EnableIf_< UseSMPAssign<MT2> >
714  smpAddAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
715  {
717 
720 
721  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
722  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
723 
724  const ResultType tmp( rhs );
725  smpAddAssign( ~lhs, tmp );
726  }
728  //**********************************************************************************************
729 
730  //**SMP addition assignment to sparse matrices**************************************************
731  // No special implementation for the SMP addition assignment to sparse matrices.
732  //**********************************************************************************************
733 
734  //**SMP Schur product assignment to dense matrices**********************************************
748  template< typename MT2 // Type of the target dense matrix
749  , bool SO2 > // Storage order of the target dense matrix
750  friend inline EnableIf_< UseSMPAssign<MT2> >
751  smpSchurAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
752  {
754 
757 
758  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
759  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
760 
761  const ResultType tmp( rhs );
762  smpSchurAssign( ~lhs, tmp );
763  }
765  //**********************************************************************************************
766 
767  //**SMP Schur product assignment to sparse matrices*********************************************
768  // No special implementation for the SMP Schur product assignment to sparse matrices.
769  //**********************************************************************************************
770 
771  //**SMP subtraction assignment to dense matrices************************************************
785  template< typename MT2 // Type of the target dense matrix
786  , bool SO2 > // Storage order of the target dense matrix
787  friend inline EnableIf_< UseSMPAssign<MT2> >
788  smpSubAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
789  {
791 
794 
795  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
796  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
797 
798  const ResultType tmp( rhs );
799  smpSubAssign( ~lhs, tmp );
800  }
802  //**********************************************************************************************
803 
804  //**SMP subtraction assignment to sparse matrices***********************************************
805  // No special implementation for the SMP subtraction assignment to sparse matrices.
806  //**********************************************************************************************
807 
808  //**SMP multiplication assignment to dense matrices*********************************************
809  // No special implementation for the SMP multiplication assignment to dense matrices.
810  //**********************************************************************************************
811 
812  //**SMP multiplication assignment to sparse matrices********************************************
813  // No special implementation for the SMP multiplication assignment to sparse matrices.
814  //**********************************************************************************************
815 
816  //**Compile time checks*************************************************************************
823  //**********************************************************************************************
824 };
825 //*************************************************************************************************
826 
827 
828 
829 
830 //=================================================================================================
831 //
832 // GLOBAL UNARY ARITHMETIC OPERATORS
833 //
834 //=================================================================================================
835 
836 //*************************************************************************************************
853 template< typename MT // Data type of the sparse matrix
854  , bool SO > // Storage order
855 inline decltype(auto) operator-( const SparseMatrix<MT,SO>& sm )
856 {
858 
859  using ScalarType = UnderlyingBuiltin_<MT>;
861  return ReturnType( ~sm, ScalarType(-1) );
862 }
863 //*************************************************************************************************
864 
865 
866 
867 
868 //=================================================================================================
869 //
870 // GLOBAL BINARY ARITHMETIC OPERATORS
871 //
872 //=================================================================================================
873 
874 //*************************************************************************************************
895 template< typename MT // Type of the left-hand side sparse matrix
896  , bool SO // Storage order of the left-hand side sparse matrix
897  , typename ST // Type of the right-hand side scalar
898  , typename = EnableIf_< IsNumeric<ST> > >
899 inline decltype(auto) operator*( const SparseMatrix<MT,SO>& mat, ST scalar )
900 {
902 
903  using ScalarType = MultTrait_< UnderlyingBuiltin_<MT>, ST >;
905  return ReturnType( ~mat, scalar );
906 }
907 //*************************************************************************************************
908 
909 
910 //*************************************************************************************************
931 template< typename ST // Type of the left-hand side scalar
932  , typename MT // Type of the right-hand side sparse matrix
933  , bool SO // Storage order of the right-hand side sparse matrix
934  , typename = EnableIf_< IsNumeric<ST> > >
935 inline decltype(auto) operator*( ST scalar, const SparseMatrix<MT,SO>& mat )
936 {
938 
939  using ScalarType = MultTrait_< ST, UnderlyingBuiltin_<MT> >;
941  return ReturnType( ~mat, scalar );
942 }
943 //*************************************************************************************************
944 
945 
946 
947 
948 //=================================================================================================
949 //
950 // GLOBAL RESTRUCTURING UNARY ARITHMETIC OPERATORS
951 //
952 //=================================================================================================
953 
954 //*************************************************************************************************
966 template< typename MT // Type of the sparse matrix
967  , typename ST // Type of the scalar
968  , bool SO > // Storage order
969 inline decltype(auto) operator-( const SMatScalarMultExpr<MT,ST,SO>& sm )
970 {
972 
974  return ReturnType( sm.leftOperand(), -sm.rightOperand() );
975 }
977 //*************************************************************************************************
978 
979 
980 
981 
982 //=================================================================================================
983 //
984 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
985 //
986 //=================================================================================================
987 
988 //*************************************************************************************************
1001 template< typename MT // Type of the sparse matrix
1002  , typename ST1 // Type of the first scalar
1003  , bool SO // Storage order of the sparse matrix
1004  , typename ST2 // Type of the second scalar
1005  , typename = EnableIf_< IsNumeric<ST2> > >
1006 inline decltype(auto) operator*( const SMatScalarMultExpr<MT,ST1,SO>& mat, ST2 scalar )
1007 {
1009 
1010  return mat.leftOperand() * ( mat.rightOperand() * scalar );
1011 }
1013 //*************************************************************************************************
1014 
1015 
1016 //*************************************************************************************************
1029 template< typename ST1 // Type of the first scalar
1030  , typename MT // Type of the sparse matrix
1031  , typename ST2 // Type of the second scalar
1032  , bool SO // Storage order of the sparse matrix
1033  , typename = EnableIf_< IsNumeric<ST1> > >
1034 inline decltype(auto) operator*( ST1 scalar, const SMatScalarMultExpr<MT,ST2,SO>& mat )
1035 {
1037 
1038  return mat.leftOperand() * ( scalar * mat.rightOperand() );
1039 }
1041 //*************************************************************************************************
1042 
1043 
1044 //*************************************************************************************************
1057 template< typename MT // Type of the sparse matrix
1058  , typename ST1 // Type of the first scalar
1059  , bool SO // Storage order of the sparse matrix
1060  , typename ST2 // Type of the second scalar
1062 inline decltype(auto) operator/( const SMatScalarMultExpr<MT,ST1,SO>& mat, ST2 scalar )
1063 {
1065 
1066  return mat.leftOperand() * ( mat.rightOperand() / scalar );
1067 }
1069 //*************************************************************************************************
1070 
1071 
1072 //*************************************************************************************************
1086 template< typename MT // Type of the sparse matrix of the left-hand side expression
1087  , typename ST // Type of the scalar of the left-hand side expression
1088  , bool SO // Storage order of the left-hand side expression
1089  , typename VT > // Type of the right-hand side dense vector
1090 inline decltype(auto)
1092 {
1094 
1095  return ( mat.leftOperand() * (~vec) ) * mat.rightOperand();
1096 }
1098 //*************************************************************************************************
1099 
1100 
1101 //*************************************************************************************************
1115 template< typename VT // Type of the left-hand side dense vector
1116  , typename MT // Type of the sparse matrix of the right-hand side expression
1117  , typename ST // Type of the scalar of the right-hand side expression
1118  , bool SO > // Storage order of the right-hand side expression
1119 inline decltype(auto)
1121 {
1123 
1124  return ( (~vec) * mat.leftOperand() ) * mat.rightOperand();
1125 }
1127 //*************************************************************************************************
1128 
1129 
1130 //*************************************************************************************************
1146 template< typename MT // Type of the sparse matrix of the left-hand side expression
1147  , typename ST1 // Type of the scalar of the left-hand side expression
1148  , bool SO // Storage order of the left-hand side expression
1149  , typename VT // Type of the dense vector of the right-hand side expression
1150  , typename ST2 > // Type of the scalar of the right-hand side expression
1151 inline decltype(auto)
1153 {
1155 
1156  return ( mat.leftOperand() * vec.leftOperand() ) * ( mat.rightOperand() * vec.rightOperand() );
1157 }
1159 //*************************************************************************************************
1160 
1161 
1162 //*************************************************************************************************
1178 template< typename VT // Type of the dense vector of the left-hand side expression
1179  , typename ST1 // Type of the scalar of the left-hand side expression
1180  , typename MT // Type of the sparse matrix of the right-hand side expression
1181  , typename ST2 // Type of the scalar of the right-hand side expression
1182  , bool SO > // Storage order of the right-hand side expression
1183 inline decltype(auto)
1185 {
1187 
1188  return ( vec.leftOperand() * mat.leftOperand() ) * ( vec.rightOperand() * mat.rightOperand() );
1189 }
1191 //*************************************************************************************************
1192 
1193 
1194 //*************************************************************************************************
1208 template< typename MT // Type of the sparse matrix of the left-hand side expression
1209  , typename ST // Type of the scalar of the left-hand side expression
1210  , bool SO // Storage order of the left-hand side expression
1211  , typename VT > // Type of the right-hand side sparse vector
1212 inline decltype(auto)
1214 {
1216 
1217  return ( mat.leftOperand() * (~vec) ) * mat.rightOperand();
1218 }
1220 //*************************************************************************************************
1221 
1222 
1223 //*************************************************************************************************
1237 template< typename VT // Type of the left-hand side sparse vector
1238  , typename MT // Type of the sparse matrix of the right-hand side expression
1239  , typename ST // Type of the scalar of the right-hand side expression
1240  , bool SO > // Storage order of the right-hand side expression
1241 inline decltype(auto)
1243 {
1245 
1246  return ( (~vec) * mat.leftOperand() ) * mat.rightOperand();
1247 }
1249 //*************************************************************************************************
1250 
1251 
1252 //*************************************************************************************************
1268 template< typename MT // Type of the sparse matrix of the left-hand side expression
1269  , typename ST1 // Type of the scalar of the left-hand side expression
1270  , bool SO // Storage order of the left-hand side expression
1271  , typename VT // Type of the sparse vector of the right-hand side expression
1272  , typename ST2 > // Type of the scalar of the right-hand side expression
1273 inline decltype(auto)
1275 {
1277 
1278  return ( mat.leftOperand() * vec.leftOperand() ) * ( mat.rightOperand() * vec.rightOperand() );
1279 }
1281 //*************************************************************************************************
1282 
1283 
1284 //*************************************************************************************************
1300 template< typename VT // Type of the sparse vector of the left-hand side expression
1301  , typename ST1 // Type of the scalar of the left-hand side expression
1302  , typename MT // Type of the sparse matrix of the right-hand side expression
1303  , typename ST2 // Type of the scalar of the right-hand side expression
1304  , bool SO > // Storage order of the right-hand side expression
1305 inline decltype(auto)
1307 {
1309 
1310  return ( vec.leftOperand() * mat.leftOperand() ) * ( vec.rightOperand() * mat.rightOperand() );
1311 }
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1330 template< typename MT1 // Type of the sparse matrix of the left-hand side expression
1331  , typename ST // Type of the scalar of the left-hand side expression
1332  , bool SO1 // Storage order of the left-hand side expression
1333  , typename MT2 // Type of the right-hand side dense matrix
1334  , bool SO2 > // Storage order of the right-hand side dense matrix
1335 inline decltype(auto)
1337 {
1339 
1340  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1341 }
1343 //*************************************************************************************************
1344 
1345 
1346 //*************************************************************************************************
1360 template< typename MT1 // Type of the left-hand side dense matrix
1361  , bool SO1 // Storage order of the left-hand side dense matrix
1362  , typename MT2 // Type of the sparse matrix of the right-hand side expression
1363  , typename ST // Type of the scalar of the right-hand side expression
1364  , bool SO2 > // Storage order of the right-hand side expression
1365 inline decltype(auto)
1367 {
1369 
1370  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1371 }
1373 //*************************************************************************************************
1374 
1375 
1376 //*************************************************************************************************
1390 template< typename MT1 // Type of the sparse matrix of the left-hand side expression
1391  , typename ST // Type of the scalar of the left-hand side expression
1392  , bool SO1 // Storage order of the left-hand side expression
1393  , typename MT2 // Type of the right-hand side sparse matrix
1394  , bool SO2 > // Storage order of the right-hand side sparse matrix
1395 inline decltype(auto)
1397 {
1399 
1400  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1401 }
1403 //*************************************************************************************************
1404 
1405 
1406 //*************************************************************************************************
1420 template< typename MT1 // Type of the left-hand side sparse matrix
1421  , bool SO1 // Storage order of the left-hand side sparse matrix
1422  , typename MT2 // Type of the sparse matrix of the right-hand side expression
1423  , typename ST // Type of the scalar of the right-hand side expression
1424  , bool SO2 > // Storage order of the right-hand side expression
1425 inline decltype(auto)
1427 {
1429 
1430  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1450 template< typename MT1 // Type of the sparse matrix of the left-hand side expression
1451  , typename ST1 // Type of the scalar of the left-hand side expression
1452  , bool SO1 // Storage order of the left-hand side expression
1453  , typename MT2 // Type of the right-hand side sparse matrix
1454  , typename ST2 // Type of the scalar of the right-hand side expression
1455  , bool SO2 > // Storage order of the right-hand side expression
1456 inline decltype(auto)
1458 {
1460 
1461  return ( lhs.leftOperand() * rhs.leftOperand() ) * ( lhs.rightOperand() * rhs.rightOperand() );
1462 }
1464 //*************************************************************************************************
1465 
1466 
1467 
1468 
1469 //=================================================================================================
1470 //
1471 // SIZE SPECIALIZATIONS
1472 //
1473 //=================================================================================================
1474 
1475 //*************************************************************************************************
1477 template< typename MT, typename ST, bool SO >
1478 struct Size< SMatScalarMultExpr<MT,ST,SO>, 0UL >
1479  : public Size<MT,0UL>
1480 {};
1481 
1482 template< typename MT, typename ST, bool SO >
1483 struct Size< SMatScalarMultExpr<MT,ST,SO>, 1UL >
1484  : public Size<MT,1UL>
1485 {};
1487 //*************************************************************************************************
1488 
1489 
1490 
1491 
1492 //=================================================================================================
1493 //
1494 // ISSYMMETRIC SPECIALIZATIONS
1495 //
1496 //=================================================================================================
1497 
1498 //*************************************************************************************************
1500 template< typename MT, typename ST, bool SO >
1501 struct IsSymmetric< SMatScalarMultExpr<MT,ST,SO> >
1502  : public IsSymmetric<MT>
1503 {};
1505 //*************************************************************************************************
1506 
1507 
1508 
1509 
1510 //=================================================================================================
1511 //
1512 // ISHERMITIAN SPECIALIZATIONS
1513 //
1514 //=================================================================================================
1515 
1516 //*************************************************************************************************
1518 template< typename MT, typename ST, bool SO >
1519 struct IsHermitian< SMatScalarMultExpr<MT,ST,SO> >
1520  : public IsHermitian<MT>
1521 {};
1523 //*************************************************************************************************
1524 
1525 
1526 
1527 
1528 //=================================================================================================
1529 //
1530 // ISLOWER SPECIALIZATIONS
1531 //
1532 //=================================================================================================
1533 
1534 //*************************************************************************************************
1536 template< typename MT, typename ST, bool SO >
1537 struct IsLower< SMatScalarMultExpr<MT,ST,SO> >
1538  : public IsLower<MT>
1539 {};
1541 //*************************************************************************************************
1542 
1543 
1544 
1545 
1546 //=================================================================================================
1547 //
1548 // ISSTRICTLYLOWER SPECIALIZATIONS
1549 //
1550 //=================================================================================================
1551 
1552 //*************************************************************************************************
1554 template< typename MT, typename ST, bool SO >
1555 struct IsStrictlyLower< SMatScalarMultExpr<MT,ST,SO> >
1556  : public IsStrictlyLower<MT>
1557 {};
1559 //*************************************************************************************************
1560 
1561 
1562 
1563 
1564 //=================================================================================================
1565 //
1566 // ISUPPER SPECIALIZATIONS
1567 //
1568 //=================================================================================================
1569 
1570 //*************************************************************************************************
1572 template< typename MT, typename ST, bool SO >
1573 struct IsUpper< SMatScalarMultExpr<MT,ST,SO> >
1574  : public IsUpper<MT>
1575 {};
1577 //*************************************************************************************************
1578 
1579 
1580 
1581 
1582 //=================================================================================================
1583 //
1584 // ISSTRICTLYUPPER SPECIALIZATIONS
1585 //
1586 //=================================================================================================
1587 
1588 //*************************************************************************************************
1590 template< typename MT, typename ST, bool SO >
1591 struct IsStrictlyUpper< SMatScalarMultExpr<MT,ST,SO> >
1592  : public IsStrictlyUpper<MT>
1593 {};
1595 //*************************************************************************************************
1596 
1597 } // namespace blaze
1598 
1599 #endif
RightOperand rightOperand() const noexcept
Returns the right-hand side scalar operand.
Definition: SVecScalarMultExpr.h:437
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: SMatScalarMultExpr.h:364
Pointer difference type of the Blaze library.
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecScalarMultExpr.h:529
Header file for auxiliary alias declarations.
Data type constraint.
Constraint on the data type.
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SMatScalarMultExpr.h:193
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
RightOperand rightOperand() const noexcept
Returns the right-hand side scalar operand.
Definition: SMatScalarMultExpr.h:475
Header file for basic type definitions.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatScalarMultExpr.h:416
ReturnType value() const
Access to the current value of the sparse element.
Definition: SMatScalarMultExpr.h:252
RightOperand rightOperand() const noexcept
Returns the right-hand side scalar operand.
Definition: DVecScalarMultExpr.h:539
decltype(auto) operator/(const DenseMatrix< MT, SO > &mat, ST scalar)
Division operator for the division of a dense matrix by a scalar value ( ).
Definition: DMatScalarDivExpr.h:1070
RightOperand scalar_
Right-hand side scalar of the multiplication expression.
Definition: SMatScalarMultExpr.h:507
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.
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
RightOperand scalar_
Right-hand side scalar of the multiplication expression.
Definition: SMatScalarMultExpr.h:303
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatScalarMultExpr.h:465
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatScalarMultExpr.h:164
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
MultExprTrait_< RN, ST > ExprReturnType
Expression return type for the subscript operator.
Definition: SMatScalarMultExpr.h:122
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:291
Header file for the Computation base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
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:733
Header file for the RequiresEvaluation type trait.
LeftOperand matrix_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatScalarMultExpr.h:506
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatScalarMultExpr.h:347
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two expression iterators.
Definition: SMatScalarMultExpr.h:295
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
typename UnderlyingBuiltin< T >::Type UnderlyingBuiltin_
Auxiliary alias declaration for the UnderlyingBuiltin type trait.The UnderlyingBuiltin_ alias declara...
Definition: UnderlyingBuiltin.h:133
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
Header file for the SparseMatrix base class.
Constraint on the data type.
typename MultExprTrait< T1, T2 >::Type MultExprTrait_
Auxiliary alias declaration for the MultExprTrait class template.The MultExprTrait_ alias declaration...
Definition: MultExprTrait.h:112
Header file for the MultExprTrait class template.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:71
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
ConstIterator upperBound(size_t i, size_t j) const
Returns an iterator to the first index greater then the given index.
Definition: SMatScalarMultExpr.h:454
Header file for the ValueIndexPair class.
SMatScalarMultExpr(const MT &matrix, ST scalar) noexcept
Constructor for the SMatScalarMultExpr class.
Definition: SMatScalarMultExpr.h:319
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
IfTrue_< useAssign, const ResultType, const SMatScalarMultExpr &> CompositeType
Data type for composite expression templates.
Definition: SMatScalarMultExpr.h:171
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
ConstIterator & operator++()
Pre-increment operator.
Definition: SMatScalarMultExpr.h:221
Header file for the UnderlyingBuiltin type trait.
Header file for the Or class template.
ST RightOperand
Composite type of the right-hand side scalar value.
Definition: SMatScalarMultExpr.h:177
#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
const ConstIterator * operator->() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SMatScalarMultExpr.h:242
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatScalarMultExpr.h:487
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
#define BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE(A, B)
Data type constraint.In case the two types A and B are not the same (ignoring all cv-qualifiers of bo...
Definition: SameType.h:71
Header file for the IsLower type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatScalarMultExpr.h:395
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatScalarMultExpr.h:165
Constraints on the storage order of matrix types.
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
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
ConstIterator lowerBound(size_t i, size_t j) const
Returns an iterator to the first index not less then the given index.
Definition: SMatScalarMultExpr.h:441
Constraint on the data type.
Expression object for sparse matrix-scalar multiplications.The SMatScalarMult class represents the co...
Definition: Forward.h:114
Header file for all forward declarations for expression class templates.
MultTrait_< RT, ST > ResultType
Result type for expression template evaluations.
Definition: SMatScalarMultExpr.h:162
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatScalarMultExpr.h:499
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row i.
Definition: SMatScalarMultExpr.h:375
const Element operator*() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SMatScalarMultExpr.h:232
Header file for the IsNumeric type trait.
Header file for the MatScalarMultExpr base class.
Header file for run time assertion macros.
ConstIterator(IteratorType matrix, RightOperand scalar)
Constructor for the ConstIterator class.
Definition: SMatScalarMultExpr.h:210
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
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: SMatScalarMultExpr.h:284
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
#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
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatScalarMultExpr.h:405
If_< IsExpression< MT >, const MT, const MT &> LeftOperand
Composite data type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:174
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsInvertible.h:82
ConstIterator_< RemoveReference_< LeftOperand > > IteratorType
Iterator type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:191
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
Iterator over the elements of the sparse matrix/scalar multiplication expression. ...
Definition: SMatScalarMultExpr.h:183
Header file for the RemoveReference type trait.
Header file for the IsInvertible 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
IteratorCategory iterator_category
The iterator category.
Definition: SMatScalarMultExpr.h:200
CompositeType_< MT > CT
Composite type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:109
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
IteratorType matrix_
Iterator over the elements of the left-hand side sparse matrix expression.
Definition: SMatScalarMultExpr.h:302
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:73
Header file for the IsComputation type trait class.
Expression object for dense vector-scalar multiplications.The DVecScalarMultExpr class represents the...
Definition: DVecScalarMultExpr.h:104
Expression object for sparse vector-scalar multiplications.The SVecScalarMultExpr class represents th...
Definition: Forward.h:139
Compile time logical &#39;or&#39; evaluation.The Or alias declaration performs at compile time a logical &#39;or&#39;...
Definition: Or.h:76
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:130
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatScalarMultExpr.h:385
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.
ReturnType_< MT > RN
Return type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:108
ConstIterator find(size_t i, size_t j) const
Searches for a specific matrix element.
Definition: SMatScalarMultExpr.h:428
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatScalarMultExpr.h:163
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatScalarMultExpr.h:168
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatScalarMultExpr.h:332
Header file for the IsHermitian type trait.
Header file for the Size type trait.
size_t index() const
Access to the current index of the sparse element.
Definition: SMatScalarMultExpr.h:262
#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
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: SMatScalarMultExpr.h:273
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecScalarMultExpr.h:427
ResultType_< MT > RT
Result type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:107
#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.