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 <utility>
45 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
65 #include <blaze/util/Assert.h>
68 #include <blaze/util/DisableIf.h>
69 #include <blaze/util/EnableIf.h>
71 #include <blaze/util/mpl/If.h>
72 #include <blaze/util/Types.h>
75 #include <blaze/util/Unused.h>
76 
77 
78 namespace blaze {
79 
80 //=================================================================================================
81 //
82 // CLASS SMATSCALARMULTEXPR
83 //
84 //=================================================================================================
85 
86 //*************************************************************************************************
93 template< typename MT // Type of the left-hand side sparse matrix
94  , typename ST // Type of the right-hand side scalar value
95  , bool SO > // Storage order
96 class SMatScalarMultExpr
97  : public MatScalarMultExpr< SparseMatrix< SMatScalarMultExpr<MT,ST,SO>, SO > >
98  , private Computation
99 {
100  private:
101  //**Type definitions****************************************************************************
105  //**********************************************************************************************
106 
107  //**Return type evaluation**********************************************************************
109 
114  static constexpr bool returnExpr = !IsTemporary_v<RN>;
115 
117  using ExprReturnType = decltype( std::declval<RN>() * std::declval<ST>() );
118  //**********************************************************************************************
119 
120  //**Serial evaluation strategy******************************************************************
122 
128  static constexpr bool useAssign = RequiresEvaluation_v<MT>;
129 
131  template< typename MT2 >
133  static constexpr bool UseAssign_v = useAssign;
135  //**********************************************************************************************
136 
137  //**Parallel evaluation strategy****************************************************************
139 
145  template< typename MT2 >
146  static constexpr bool UseSMPAssign_v =
149  //**********************************************************************************************
150 
151  public:
152  //**Type definitions****************************************************************************
159 
162 
165 
167  using LeftOperand = If_t< IsExpression_v<MT>, const MT, const MT& >;
168 
170  using RightOperand = ST;
171  //**********************************************************************************************
172 
173  //**ConstIterator class definition**************************************************************
177  {
178  public:
179  //**Type definitions*************************************************************************
182 
185 
186  using IteratorCategory = std::forward_iterator_tag;
187  using ValueType = Element;
191 
192  // STL iterator requirements
198  //*******************************************************************************************
199 
200  //**Constructor******************************************************************************
203  inline ConstIterator( IteratorType matrix, RightOperand scalar )
204  : matrix_( matrix ) // Iterator over the elements of the left-hand side sparse matrix expression
205  , scalar_( scalar ) // Right-hand side scalar of the multiplication expression
206  {}
207  //*******************************************************************************************
208 
209  //**Prefix increment operator****************************************************************
215  ++matrix_;
216  return *this;
217  }
218  //*******************************************************************************************
219 
220  //**Element access operator******************************************************************
225  inline const Element operator*() const {
226  return Element( matrix_->value() * scalar_, matrix_->index() );
227  }
228  //*******************************************************************************************
229 
230  //**Element access operator******************************************************************
235  inline const ConstIterator* operator->() const {
236  return this;
237  }
238  //*******************************************************************************************
239 
240  //**Value function***************************************************************************
245  inline ReturnType value() const {
246  return matrix_->value() * scalar_;
247  }
248  //*******************************************************************************************
249 
250  //**Index function***************************************************************************
255  inline size_t index() const {
256  return matrix_->index();
257  }
258  //*******************************************************************************************
259 
260  //**Equality operator************************************************************************
266  inline bool operator==( const ConstIterator& rhs ) const {
267  return matrix_ == rhs.matrix_;
268  }
269  //*******************************************************************************************
270 
271  //**Inequality operator**********************************************************************
277  inline bool operator!=( const ConstIterator& rhs ) const {
278  return matrix_ != rhs.matrix_;
279  }
280  //*******************************************************************************************
281 
282  //**Subtraction operator*********************************************************************
288  inline DifferenceType operator-( const ConstIterator& rhs ) const {
289  return matrix_ - rhs.matrix_;
290  }
291  //*******************************************************************************************
292 
293  private:
294  //**Member variables*************************************************************************
297  //*******************************************************************************************
298  };
299  //**********************************************************************************************
300 
301  //**Compilation flags***************************************************************************
303  static constexpr bool smpAssignable = false;
304  //**********************************************************************************************
305 
306  //**Constructor*********************************************************************************
312  explicit inline SMatScalarMultExpr( const MT& matrix, ST scalar ) noexcept
313  : matrix_( matrix ) // Left-hand side sparse matrix of the multiplication expression
314  , scalar_( scalar ) // Right-hand side scalar of the multiplication expression
315  {}
316  //**********************************************************************************************
317 
318  //**Access operator*****************************************************************************
325  inline ReturnType operator()( size_t i, size_t j ) const {
326  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
327  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
328  return matrix_(i,j) * scalar_;
329  }
330  //**********************************************************************************************
331 
332  //**At function*********************************************************************************
340  inline ReturnType at( size_t i, size_t j ) const {
341  if( i >= matrix_.rows() ) {
342  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
343  }
344  if( j >= matrix_.columns() ) {
345  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
346  }
347  return (*this)(i,j);
348  }
349  //**********************************************************************************************
350 
351  //**Begin function******************************************************************************
357  inline ConstIterator begin( size_t i ) const {
358  return ConstIterator( matrix_.begin(i), scalar_ );
359  }
360  //**********************************************************************************************
361 
362  //**End function********************************************************************************
368  inline ConstIterator end( size_t i ) const {
369  return ConstIterator( matrix_.end(i), scalar_ );
370  }
371  //**********************************************************************************************
372 
373  //**Rows function*******************************************************************************
378  inline size_t rows() const noexcept {
379  return matrix_.rows();
380  }
381  //**********************************************************************************************
382 
383  //**Columns function****************************************************************************
388  inline size_t columns() const noexcept {
389  return matrix_.columns();
390  }
391  //**********************************************************************************************
392 
393  //**NonZeros function***************************************************************************
398  inline size_t nonZeros() const {
399  return matrix_.nonZeros();
400  }
401  //**********************************************************************************************
402 
403  //**NonZeros function***************************************************************************
409  inline size_t nonZeros( size_t i ) const {
410  return matrix_.nonZeros(i);
411  }
412  //**********************************************************************************************
413 
414  //**Find function*******************************************************************************
421  inline ConstIterator find( size_t i, size_t j ) const {
423  return ConstIterator( matrix_.find( i, j ), scalar_ );
424  }
425  //**********************************************************************************************
426 
427  //**LowerBound function*************************************************************************
434  inline ConstIterator lowerBound( size_t i, size_t j ) const {
436  return ConstIterator( matrix_.lowerBound( i, j ), scalar_ );
437  }
438  //**********************************************************************************************
439 
440  //**UpperBound function*************************************************************************
447  inline ConstIterator upperBound( size_t i, size_t j ) const {
449  return ConstIterator( matrix_.upperBound( i, j ), scalar_ );
450  }
451  //**********************************************************************************************
452 
453  //**Left operand access*************************************************************************
458  inline LeftOperand leftOperand() const noexcept {
459  return matrix_;
460  }
461  //**********************************************************************************************
462 
463  //**Right operand access************************************************************************
468  inline RightOperand rightOperand() const noexcept {
469  return scalar_;
470  }
471  //**********************************************************************************************
472 
473  //**********************************************************************************************
479  template< typename T >
480  inline bool canAlias( const T* alias ) const noexcept {
481  return matrix_.canAlias( alias );
482  }
483  //**********************************************************************************************
484 
485  //**********************************************************************************************
491  template< typename T >
492  inline bool isAliased( const T* alias ) const noexcept {
493  return matrix_.isAliased( alias );
494  }
495  //**********************************************************************************************
496 
497  private:
498  //**Member variables****************************************************************************
501  //**********************************************************************************************
502 
503  //**Assignment to dense matrices****************************************************************
517  template< typename MT2 // Type of the target dense matrix
518  , bool SO2 > // Storage order of the target dense matrix
519  friend inline auto assign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
521  {
523 
524  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
525  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
526 
527  assign( ~lhs, rhs.matrix_ );
528  (~lhs) *= rhs.scalar_;
529  }
531  //**********************************************************************************************
532 
533  //**Assignment to sparse matrices***************************************************************
547  template< typename MT2 // Type of the target sparse matrix
548  , bool SO2 > // Storage order of the target sparse matrix
549  friend inline auto assign( SparseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
551  {
553 
554  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
555  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
556 
557  assign( ~lhs, rhs.matrix_ );
558  (~lhs) *= rhs.scalar_;
559  }
561  //**********************************************************************************************
562 
563  //**Addition assignment to dense matrices*******************************************************
577  template< typename MT2 // Type of the target dense matrix
578  , bool SO2 > // Storage order of the target dense matrix
579  friend inline auto addAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
580  -> EnableIf_t< UseAssign_v<MT2> >
581  {
583 
586 
587  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
588  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
589 
590  const ResultType tmp( serial( rhs ) );
591  addAssign( ~lhs, tmp );
592  }
594  //**********************************************************************************************
595 
596  //**Addition assignment to sparse matrices******************************************************
597  // No special implementation for the addition assignment to sparse matrices.
598  //**********************************************************************************************
599 
600  //**Subtraction assignment to dense matrices****************************************************
614  template< typename MT2 // Type of the target dense matrix
615  , bool SO2 > // Storage order of the target dense matrix
616  friend inline auto subAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
617  -> EnableIf_t< UseAssign_v<MT2> >
618  {
620 
623 
624  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
625  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
626 
627  const ResultType tmp( serial( rhs ) );
628  subAssign( ~lhs, tmp );
629  }
631  //**********************************************************************************************
632 
633  //**Subtraction assignment to sparse matrices***************************************************
634  // No special implementation for the subtraction assignment to sparse matrices.
635  //**********************************************************************************************
636 
637  //**Schur product assignment to dense matrices**************************************************
651  template< typename MT2 // Type of the target dense matrix
652  , bool SO2 > // Storage order of the target dense matrix
653  friend inline auto schurAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
654  -> EnableIf_t< UseAssign_v<MT2> >
655  {
657 
660 
661  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
662  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
663 
664  const ResultType tmp( serial( rhs ) );
665  schurAssign( ~lhs, tmp );
666  }
668  //**********************************************************************************************
669 
670  //**Schur product assignment to sparse matrices*************************************************
671  // No special implementation for the Schur product assignment to sparse matrices.
672  //**********************************************************************************************
673 
674  //**Multiplication assignment to dense matrices*************************************************
675  // No special implementation for the multiplication assignment to dense matrices.
676  //**********************************************************************************************
677 
678  //**Multiplication assignment to sparse matrices************************************************
679  // No special implementation for the multiplication assignment to sparse matrices.
680  //**********************************************************************************************
681 
682  //**SMP assignment to dense matrices************************************************************
683  // No special implementation for the SMP assignment to dense matrices.
684  //**********************************************************************************************
685 
686  //**SMP assignment to sparse matrices***********************************************************
687  // No special implementation for the SMP assignment to sparse matrices.
688  //**********************************************************************************************
689 
690  //**SMP addition assignment to dense matrices***************************************************
704  template< typename MT2 // Type of the target dense matrix
705  , bool SO2 > // Storage order of the target dense matrix
706  friend inline auto smpAddAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
707  -> EnableIf_t< UseSMPAssign_v<MT2> >
708  {
710 
713 
714  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
715  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
716 
717  const ResultType tmp( rhs );
718  smpAddAssign( ~lhs, tmp );
719  }
721  //**********************************************************************************************
722 
723  //**SMP addition assignment to sparse matrices**************************************************
724  // No special implementation for the SMP addition assignment to sparse matrices.
725  //**********************************************************************************************
726 
727  //**SMP Schur product assignment to dense matrices**********************************************
741  template< typename MT2 // Type of the target dense matrix
742  , bool SO2 > // Storage order of the target dense matrix
743  friend inline auto smpSchurAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
744  -> EnableIf_t< UseSMPAssign_v<MT2> >
745  {
747 
750 
751  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
752  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
753 
754  const ResultType tmp( rhs );
755  smpSchurAssign( ~lhs, tmp );
756  }
758  //**********************************************************************************************
759 
760  //**SMP Schur product assignment to sparse matrices*********************************************
761  // No special implementation for the SMP Schur product assignment to sparse matrices.
762  //**********************************************************************************************
763 
764  //**SMP subtraction assignment to dense matrices************************************************
778  template< typename MT2 // Type of the target dense matrix
779  , bool SO2 > // Storage order of the target dense matrix
780  friend inline auto smpSubAssign( DenseMatrix<MT2,SO2>& lhs, const SMatScalarMultExpr& rhs )
781  -> EnableIf_t< UseSMPAssign_v<MT2> >
782  {
784 
787 
788  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
789  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
790 
791  const ResultType tmp( rhs );
792  smpSubAssign( ~lhs, tmp );
793  }
795  //**********************************************************************************************
796 
797  //**SMP subtraction assignment to sparse matrices***********************************************
798  // No special implementation for the SMP subtraction assignment to sparse matrices.
799  //**********************************************************************************************
800 
801  //**SMP multiplication assignment to dense matrices*********************************************
802  // No special implementation for the SMP multiplication assignment to dense matrices.
803  //**********************************************************************************************
804 
805  //**SMP multiplication assignment to sparse matrices********************************************
806  // No special implementation for the SMP multiplication assignment to sparse matrices.
807  //**********************************************************************************************
808 
809  //**Compile time checks*************************************************************************
817  //**********************************************************************************************
818 };
819 //*************************************************************************************************
820 
821 
822 
823 
824 //=================================================================================================
825 //
826 // GLOBAL UNARY ARITHMETIC OPERATORS
827 //
828 //=================================================================================================
829 
830 //*************************************************************************************************
847 template< typename MT // Data type of the sparse matrix
848  , bool SO > // Storage order
849 inline decltype(auto) operator-( const SparseMatrix<MT,SO>& sm )
850 {
852 
853  using ScalarType = UnderlyingBuiltin_t<MT>;
855  return ReturnType( ~sm, ScalarType(-1) );
856 }
857 //*************************************************************************************************
858 
859 
860 
861 
862 //=================================================================================================
863 //
864 // GLOBAL BINARY ARITHMETIC OPERATORS
865 //
866 //=================================================================================================
867 
868 //*************************************************************************************************
881 template< typename MT // Type of the left-hand side sparse matrix
882  , bool SO // Storage order of the left-hand side sparse matrix
883  , typename ST // Type of the right-hand side scalar
884  , DisableIf_t< IsZero_v<MT> >* = nullptr >
885 inline const SMatScalarMultExpr< MT, MultTrait_t< UnderlyingBuiltin_t<MT>, ST >, SO >
886  smatscalarmult( const SparseMatrix<MT,SO>& mat, ST scalar )
887 {
889 
890  using ScalarType = MultTrait_t< UnderlyingBuiltin_t<MT>, ST >;
891  using ReturnType = const SMatScalarMultExpr<MT,ScalarType,SO>;
892  return ReturnType( ~mat, scalar );
893 }
895 //*************************************************************************************************
896 
897 
898 //*************************************************************************************************
911 template< typename MT // Type of the left-hand side sparse matrix
912  , bool SO // Storage order of the left-hand side zero matrix
913  , typename ST // Type of the right-hand side scalar
914  , EnableIf_t< IsZero_v<MT> >* = nullptr >
915 inline decltype(auto)
916  smatscalarmult( const SparseMatrix<MT,SO>& mat, ST scalar )
917 {
919 
920  UNUSED_PARAMETER( scalar );
921 
922  using ReturnType = const MultTrait_t< ResultType_t<MT>, ST >;
923 
926 
927  return ReturnType( (~mat).rows(), (~mat).columns() );
928 }
930 //*************************************************************************************************
931 
932 
933 //*************************************************************************************************
954 template< typename MT // Type of the left-hand side sparse matrix
955  , bool SO // Storage order of the left-hand side sparse matrix
956  , typename ST // Type of the right-hand side scalar
957  , EnableIf_t< IsNumeric_v<ST> >* = nullptr >
958 inline decltype(auto) operator*( const SparseMatrix<MT,SO>& mat, ST scalar )
959 {
961 
962  return smatscalarmult( ~mat, scalar );
963 }
964 //*************************************************************************************************
965 
966 
967 //*************************************************************************************************
988 template< typename ST // Type of the left-hand side scalar
989  , typename MT // Type of the right-hand side sparse matrix
990  , bool SO // Storage order of the right-hand side sparse matrix
991  , EnableIf_t< IsNumeric_v<ST> >* = nullptr >
992 inline decltype(auto) operator*( ST scalar, const SparseMatrix<MT,SO>& mat )
993 {
995 
996  return smatscalarmult( ~mat, scalar );
997 }
998 //*************************************************************************************************
999 
1000 
1001 
1002 
1003 //=================================================================================================
1004 //
1005 // GLOBAL RESTRUCTURING UNARY ARITHMETIC OPERATORS
1006 //
1007 //=================================================================================================
1008 
1009 //*************************************************************************************************
1021 template< typename MT // Type of the sparse matrix
1022  , typename ST // Type of the scalar
1023  , bool SO > // Storage order
1024 inline decltype(auto) operator-( const SMatScalarMultExpr<MT,ST,SO>& sm )
1025 {
1027 
1028  using ReturnType = const SMatScalarMultExpr<MT,ST,SO>;
1029  return ReturnType( sm.leftOperand(), -sm.rightOperand() );
1030 }
1032 //*************************************************************************************************
1033 
1034 
1035 
1036 
1037 //=================================================================================================
1038 //
1039 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1040 //
1041 //=================================================================================================
1042 
1043 //*************************************************************************************************
1056 template< typename MT // Type of the sparse matrix
1057  , typename ST1 // Type of the first scalar
1058  , bool SO // Storage order of the sparse matrix
1059  , typename ST2 // Type of the second scalar
1060  , EnableIf_t< IsNumeric_v<ST2> >* = nullptr >
1061 inline decltype(auto) operator*( const SMatScalarMultExpr<MT,ST1,SO>& mat, ST2 scalar )
1062 {
1064 
1065  return mat.leftOperand() * ( mat.rightOperand() * scalar );
1066 }
1068 //*************************************************************************************************
1069 
1070 
1071 //*************************************************************************************************
1084 template< typename ST1 // Type of the first scalar
1085  , typename MT // Type of the sparse matrix
1086  , typename ST2 // Type of the second scalar
1087  , bool SO // Storage order of the sparse matrix
1088  , EnableIf_t< IsNumeric_v<ST1> >* = nullptr >
1089 inline decltype(auto) operator*( ST1 scalar, const SMatScalarMultExpr<MT,ST2,SO>& mat )
1090 {
1092 
1093  return mat.leftOperand() * ( scalar * mat.rightOperand() );
1094 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1112 template< typename MT // Type of the sparse matrix
1113  , typename ST1 // Type of the first scalar
1114  , bool SO // Storage order of the sparse matrix
1115  , typename ST2 // Type of the second scalar
1116  , EnableIf_t< IsNumeric_v<ST2> && ( IsInvertible_v<ST1> || IsInvertible_v<ST2> ) >* = nullptr >
1117 inline decltype(auto) operator/( const SMatScalarMultExpr<MT,ST1,SO>& mat, ST2 scalar )
1118 {
1120 
1121  return mat.leftOperand() * ( mat.rightOperand() / scalar );
1122 }
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1141 template< typename MT // Type of the sparse matrix of the left-hand side expression
1142  , typename ST // Type of the scalar of the left-hand side expression
1143  , bool SO // Storage order of the left-hand side expression
1144  , typename VT > // Type of the right-hand side dense vector
1145 inline decltype(auto)
1146  operator*( const SMatScalarMultExpr<MT,ST,SO>& mat, const DenseVector<VT,false>& vec )
1147 {
1149 
1150  return ( mat.leftOperand() * (~vec) ) * mat.rightOperand();
1151 }
1153 //*************************************************************************************************
1154 
1155 
1156 //*************************************************************************************************
1170 template< typename VT // Type of the left-hand side dense vector
1171  , typename MT // Type of the sparse matrix of the right-hand side expression
1172  , typename ST // Type of the scalar of the right-hand side expression
1173  , bool SO > // Storage order of the right-hand side expression
1174 inline decltype(auto)
1175  operator*( const DenseVector<VT,true>& vec, const SMatScalarMultExpr<MT,ST,SO>& mat )
1176 {
1178 
1179  return ( (~vec) * mat.leftOperand() ) * mat.rightOperand();
1180 }
1182 //*************************************************************************************************
1183 
1184 
1185 //*************************************************************************************************
1201 template< typename MT // Type of the sparse matrix of the left-hand side expression
1202  , typename ST1 // Type of the scalar of the left-hand side expression
1203  , bool SO // Storage order of the left-hand side expression
1204  , typename VT // Type of the dense vector of the right-hand side expression
1205  , typename ST2 > // Type of the scalar of the right-hand side expression
1206 inline decltype(auto)
1207  operator*( const SMatScalarMultExpr<MT,ST1,SO>& mat, const DVecScalarMultExpr<VT,ST2,false>& vec )
1208 {
1210 
1211  return ( mat.leftOperand() * vec.leftOperand() ) * ( mat.rightOperand() * vec.rightOperand() );
1212 }
1214 //*************************************************************************************************
1215 
1216 
1217 //*************************************************************************************************
1233 template< typename VT // Type of the dense vector of the left-hand side expression
1234  , typename ST1 // Type of the scalar of the left-hand side expression
1235  , typename MT // Type of the sparse matrix of the right-hand side expression
1236  , typename ST2 // Type of the scalar of the right-hand side expression
1237  , bool SO > // Storage order of the right-hand side expression
1238 inline decltype(auto)
1239  operator*( const DVecScalarMultExpr<VT,ST1,true>& vec, const SMatScalarMultExpr<MT,ST2,SO>& mat )
1240 {
1242 
1243  return ( vec.leftOperand() * mat.leftOperand() ) * ( vec.rightOperand() * mat.rightOperand() );
1244 }
1246 //*************************************************************************************************
1247 
1248 
1249 //*************************************************************************************************
1263 template< typename MT // Type of the sparse matrix of the left-hand side expression
1264  , typename ST // Type of the scalar of the left-hand side expression
1265  , bool SO // Storage order of the left-hand side expression
1266  , typename VT > // Type of the right-hand side sparse vector
1267 inline decltype(auto)
1268  operator*( const SMatScalarMultExpr<MT,ST,SO>& mat, const SparseVector<VT,false>& vec )
1269 {
1271 
1272  return ( mat.leftOperand() * (~vec) ) * mat.rightOperand();
1273 }
1275 //*************************************************************************************************
1276 
1277 
1278 //*************************************************************************************************
1292 template< typename VT // Type of the left-hand side sparse vector
1293  , typename MT // Type of the sparse matrix of the right-hand side expression
1294  , typename ST // Type of the scalar of the right-hand side expression
1295  , bool SO > // Storage order of the right-hand side expression
1296 inline decltype(auto)
1297  operator*( const SparseVector<VT,true>& vec, const SMatScalarMultExpr<MT,ST,SO>& mat )
1298 {
1300 
1301  return ( (~vec) * mat.leftOperand() ) * mat.rightOperand();
1302 }
1304 //*************************************************************************************************
1305 
1306 
1307 //*************************************************************************************************
1323 template< typename MT // Type of the sparse matrix of the left-hand side expression
1324  , typename ST1 // Type of the scalar of the left-hand side expression
1325  , bool SO // Storage order of the left-hand side expression
1326  , typename VT // Type of the sparse vector of the right-hand side expression
1327  , typename ST2 > // Type of the scalar of the right-hand side expression
1328 inline decltype(auto)
1329  operator*( const SMatScalarMultExpr<MT,ST1,SO>& mat, const SVecScalarMultExpr<VT,ST2,false>& vec )
1330 {
1332 
1333  return ( mat.leftOperand() * vec.leftOperand() ) * ( mat.rightOperand() * vec.rightOperand() );
1334 }
1336 //*************************************************************************************************
1337 
1338 
1339 //*************************************************************************************************
1355 template< typename VT // Type of the sparse vector of the left-hand side expression
1356  , typename ST1 // Type of the scalar of the left-hand side expression
1357  , typename MT // Type of the sparse matrix of the right-hand side expression
1358  , typename ST2 // Type of the scalar of the right-hand side expression
1359  , bool SO > // Storage order of the right-hand side expression
1360 inline decltype(auto)
1361  operator*( const SVecScalarMultExpr<VT,ST1,true>& vec, const SMatScalarMultExpr<MT,ST2,SO>& mat )
1362 {
1364 
1365  return ( vec.leftOperand() * mat.leftOperand() ) * ( vec.rightOperand() * mat.rightOperand() );
1366 }
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1385 template< typename MT1 // Type of the sparse matrix of the left-hand side expression
1386  , typename ST // Type of the scalar of the left-hand side expression
1387  , bool SO1 // Storage order of the left-hand side expression
1388  , typename MT2 // Type of the right-hand side dense matrix
1389  , bool SO2 > // Storage order of the right-hand side dense matrix
1390 inline decltype(auto)
1391  operator*( const SMatScalarMultExpr<MT1,ST,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
1392 {
1394 
1395  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1396 }
1398 //*************************************************************************************************
1399 
1400 
1401 //*************************************************************************************************
1415 template< typename MT1 // Type of the left-hand side dense matrix
1416  , bool SO1 // Storage order of the left-hand side dense matrix
1417  , typename MT2 // Type of the sparse matrix of the right-hand side expression
1418  , typename ST // Type of the scalar of the right-hand side expression
1419  , bool SO2 > // Storage order of the right-hand side expression
1420 inline decltype(auto)
1421  operator*( const DenseMatrix<MT1,SO1>& lhs, const SMatScalarMultExpr<MT2,ST,SO2>& rhs )
1422 {
1424 
1425  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1426 }
1428 //*************************************************************************************************
1429 
1430 
1431 //*************************************************************************************************
1445 template< typename MT1 // Type of the sparse matrix of the left-hand side expression
1446  , typename ST // Type of the scalar of the left-hand side expression
1447  , bool SO1 // Storage order of the left-hand side expression
1448  , typename MT2 // Type of the right-hand side sparse matrix
1449  , bool SO2 > // Storage order of the right-hand side sparse matrix
1450 inline decltype(auto)
1451  operator*( const SMatScalarMultExpr<MT1,ST,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
1452 {
1454 
1455  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1456 }
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1475 template< typename MT1 // Type of the left-hand side sparse matrix
1476  , bool SO1 // Storage order of the left-hand side sparse matrix
1477  , typename MT2 // Type of the sparse matrix of the right-hand side expression
1478  , typename ST // Type of the scalar of the right-hand side expression
1479  , bool SO2 > // Storage order of the right-hand side expression
1480 inline decltype(auto)
1481  operator*( const SparseMatrix<MT1,SO1>& lhs, const SMatScalarMultExpr<MT2,ST,SO2>& rhs )
1482 {
1484 
1485  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1486 }
1488 //*************************************************************************************************
1489 
1490 
1491 //*************************************************************************************************
1505 template< typename MT1 // Type of the sparse matrix of the left-hand side expression
1506  , typename ST1 // Type of the scalar of the left-hand side expression
1507  , bool SO1 // Storage order of the left-hand side expression
1508  , typename MT2 // Type of the right-hand side sparse matrix
1509  , typename ST2 // Type of the scalar of the right-hand side expression
1510  , bool SO2 > // Storage order of the right-hand side expression
1511 inline decltype(auto)
1512  operator*( const SMatScalarMultExpr<MT1,ST1,SO1>& lhs, const SMatScalarMultExpr<MT2,ST2,SO2>& rhs )
1513 {
1515 
1516  return ( lhs.leftOperand() * rhs.leftOperand() ) * ( lhs.rightOperand() * rhs.rightOperand() );
1517 }
1519 //*************************************************************************************************
1520 
1521 } // namespace blaze
1522 
1523 #endif
ConstIterator begin(size_t i) const
Returns an iterator to the first non-zero element of row i.
Definition: SMatScalarMultExpr.h:357
Pointer difference type of the Blaze library.
Header file for auxiliary alias declarations.
Data type constraint.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatScalarMultExpr.h:303
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the multiplication expression.
Definition: SMatScalarMultExpr.h:128
Constraint on the data type.
Header file for the UNUSED_PARAMETER function template.
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SMatScalarMultExpr.h:186
ValueIndexPair< ElementType > Element
Element type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:181
RightOperand rightOperand() const noexcept
Returns the right-hand side scalar operand.
Definition: SMatScalarMultExpr.h:468
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:409
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
ReturnType value() const
Access to the current value of the sparse element.
Definition: SMatScalarMultExpr.h:245
RightOperand scalar_
Right-hand side scalar of the multiplication expression.
Definition: SMatScalarMultExpr.h:500
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the serial shim.
#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:296
ValueType * PointerType
Pointer return type.
Definition: SMatScalarMultExpr.h:188
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatScalarMultExpr.h:157
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatScalarMultExpr.h:458
Constraint on the data type.
If_t< IsExpression_v< MT >, const MT, const MT &> LeftOperand
Composite data type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:167
decltype(std::declval< RN >() *std::declval< ST >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatScalarMultExpr.h:117
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatScalarMultExpr.h:158
Header file for the Computation base class.
Element ValueType
Type of the underlying pointers.
Definition: SMatScalarMultExpr.h:187
Header file for the RequiresEvaluation type trait.
LeftOperand matrix_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatScalarMultExpr.h:499
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatScalarMultExpr.h:340
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two expression iterators.
Definition: SMatScalarMultExpr.h:288
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:137
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Header file for the SparseMatrix base class.
Constraint on the data type.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
ConstIterator upperBound(size_t i, size_t j) const
Returns an iterator to the first index greater then the given index.
Definition: SMatScalarMultExpr.h:447
Header file for the ValueIndexPair class.
Header file for the DisableIf class template.
SMatScalarMultExpr(const MT &matrix, ST scalar) noexcept
Constructor for the SMatScalarMultExpr class.
Definition: SMatScalarMultExpr.h:312
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatScalarMultExpr.h:114
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:214
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type...
Definition: Zero.h:61
Header file for the UnderlyingBuiltin type trait.
ST RightOperand
Composite type of the right-hand side scalar value.
Definition: SMatScalarMultExpr.h:170
#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:235
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatScalarMultExpr.h:480
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
#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
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatScalarMultExpr.h:388
MultTrait_t< RT, ST > ResultType
Result type for expression template evaluations.
Definition: SMatScalarMultExpr.h:155
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
ValueType & ReferenceType
Reference return type.
Definition: SMatScalarMultExpr.h:189
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:434
Constraint on the data type.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatScalarMultExpr.h:161
Expression object for sparse matrix-scalar multiplications.The SMatScalarMult class represents the co...
Definition: Forward.h:122
Header file for all forward declarations for expression class templates.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatScalarMultExpr.h:492
typename UnderlyingBuiltin< T >::Type UnderlyingBuiltin_t
Auxiliary alias declaration for the UnderlyingBuiltin type trait.The UnderlyingBuiltin_t alias declar...
Definition: UnderlyingBuiltin.h:133
Header file for the EnableIf class template.
ConstIterator end(size_t i) const
Returns an iterator just past the last non-zero element of row i.
Definition: SMatScalarMultExpr.h:368
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.The MultTrait_t alias declaration provid...
Definition: MultTrait.h:240
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
const Element operator*() const
Direct access to the sparse matrix element at the current iterator position.
Definition: SMatScalarMultExpr.h:225
Header file for the IsNumeric type trait.
ConstIterator_t< RemoveReference_t< LeftOperand > > IteratorType
Iterator type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:184
Header file for the MatScalarMultExpr base class.
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
ConstIterator(IteratorType matrix, RightOperand scalar)
Constructor for the ConstIterator class.
Definition: SMatScalarMultExpr.h:203
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: SMatScalarMultExpr.h:277
#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
Header file for the IsZero type trait.
#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:398
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
Iterator over the elements of the sparse matrix/scalar multiplication expression. ...
Definition: SMatScalarMultExpr.h:176
Header file for the RemoveReference type trait.
Header file for the IsInvertible type trait.
IteratorCategory iterator_category
The iterator category.
Definition: SMatScalarMultExpr.h:193
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatScalarMultExpr.h:156
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
IteratorType matrix_
Iterator over the elements of the left-hand side sparse matrix expression.
Definition: SMatScalarMultExpr.h:295
ResultType_t< MT > RT
Result type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:102
Index-value-pair for sparse vectors and matrices.The ValueIndexPair class represents a single index-v...
Definition: ValueIndexPair.h:73
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SMatScalarMultExpr.h:190
Header file for the IsComputation type trait class.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
ReturnType_t< MT > RN
Return type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:103
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatScalarMultExpr.h:378
If_t< useAssign, const ResultType, const SMatScalarMultExpr &> CompositeType
Data type for composite expression templates.
Definition: SMatScalarMultExpr.h:164
ConstIterator find(size_t i, size_t j) const
Searches for a specific matrix element.
Definition: SMatScalarMultExpr.h:421
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatScalarMultExpr.h:325
size_t index() const
Access to the current index of the sparse element.
Definition: SMatScalarMultExpr.h:255
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type...
Definition: Zero.h:81
#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:266
#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
CompositeType_t< MT > CT
Composite type of the sparse matrix expression.
Definition: SMatScalarMultExpr.h:104
Header file for the IsExpression type trait class.
Header file for the function trace functionality.