Blaze  3.6
SVecScalarMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECSCALARMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECSCALARMULTEXPR_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>
69 #include <blaze/util/DisableIf.h>
70 #include <blaze/util/EnableIf.h>
72 #include <blaze/util/MaybeUnused.h>
73 #include <blaze/util/mpl/If.h>
74 #include <blaze/util/Types.h>
77 
78 
79 namespace blaze {
80 
81 //=================================================================================================
82 //
83 // CLASS SVECSCALARMULTEXPR
84 //
85 //=================================================================================================
86 
87 //*************************************************************************************************
94 template< typename VT // Type of the left-hand side sparse vector
95  , typename ST // Type of the right-hand side scalar value
96  , bool TF > // Transpose flag
97 class SVecScalarMultExpr
98  : public VecScalarMultExpr< SparseVector< SVecScalarMultExpr<VT,ST,TF>, TF > >
99  , private Computation
100 {
101  private:
102  //**Type definitions****************************************************************************
106  //**********************************************************************************************
107 
108  //**Return type evaluation**********************************************************************
110 
115  static constexpr bool returnExpr = !IsTemporary_v<RN>;
116 
118  using ExprReturnType = decltype( std::declval<RN>() * std::declval<ST>() );
119  //**********************************************************************************************
120 
121  //**Serial evaluation strategy******************************************************************
123 
129  static constexpr bool useAssign = RequiresEvaluation_v<VT>;
130 
132  template< typename VT2 >
134  static constexpr bool UseAssign_v = useAssign;
136  //**********************************************************************************************
137 
138  //**Parallel evaluation strategy****************************************************************
140 
146  template< typename VT2 >
147  static constexpr bool UseSMPAssign_v =
148  ( ( !VT2::smpAssignable || !VT::smpAssignable ) && useAssign );
150  //**********************************************************************************************
151 
152  public:
153  //**Type definitions****************************************************************************
159 
162 
165 
167  using LeftOperand = If_t< IsExpression_v<VT>, const VT, const VT& >;
168 
170  using RightOperand = ST;
171  //**********************************************************************************************
172 
173  //**Compilation flags***************************************************************************
175  static constexpr bool smpAssignable = false;
176  //**********************************************************************************************
177 
178  //**ConstIterator class definition**************************************************************
182  {
183  public:
184  //**Type definitions*************************************************************************
187 
190 
191  using IteratorCategory = std::forward_iterator_tag;
192  using ValueType = Element;
196 
197  // STL iterator requirements
203  //*******************************************************************************************
204 
205  //**Constructor******************************************************************************
208  inline ConstIterator( IteratorType vector, RightOperand scalar )
209  : vector_( vector ) // Iterator over the elements of the left-hand side sparse vector expression
210  , scalar_( scalar ) // Right-hand side scalar of the multiplication expression
211  {}
212  //*******************************************************************************************
213 
214  //**Prefix increment operator****************************************************************
220  ++vector_;
221  return *this;
222  }
223  //*******************************************************************************************
224 
225  //**Element access operator******************************************************************
230  inline const Element operator*() const {
231  return Element( vector_->value() * scalar_, vector_->index() );
232  }
233  //*******************************************************************************************
234 
235  //**Element access operator******************************************************************
240  inline const ConstIterator* operator->() const {
241  return this;
242  }
243  //*******************************************************************************************
244 
245  //**Value function***************************************************************************
250  inline ReturnType value() const {
251  return vector_->value() * scalar_;
252  }
253  //*******************************************************************************************
254 
255  //**Index function***************************************************************************
260  inline size_t index() const {
261  return vector_->index();
262  }
263  //*******************************************************************************************
264 
265  //**Equality operator************************************************************************
271  inline bool operator==( const ConstIterator& rhs ) const {
272  return vector_ == rhs.vector_;
273  }
274  //*******************************************************************************************
275 
276  //**Inequality operator**********************************************************************
282  inline bool operator!=( const ConstIterator& rhs ) const {
283  return vector_ != rhs.vector_;
284  }
285  //*******************************************************************************************
286 
287  //**Subtraction operator*********************************************************************
293  inline DifferenceType operator-( const ConstIterator& rhs ) const {
294  return vector_ - rhs.vector_;
295  }
296  //*******************************************************************************************
297 
298  private:
299  //**Member variables*************************************************************************
302  //*******************************************************************************************
303  };
304  //**********************************************************************************************
305 
306  //**Constructor*********************************************************************************
312  explicit inline SVecScalarMultExpr( const VT& vector, ST scalar ) noexcept
313  : vector_( vector ) // Left-hand side sparse vector of the multiplication expression
314  , scalar_( scalar ) // Right-hand side scalar of the multiplication expression
315  {}
316  //**********************************************************************************************
317 
318  //**Subscript operator**************************************************************************
324  inline ReturnType operator[]( size_t index ) const {
325  BLAZE_INTERNAL_ASSERT( index < vector_.size(), "Invalid vector access index" );
326  return vector_[index] * scalar_;
327  }
328  //**********************************************************************************************
329 
330  //**At function*********************************************************************************
337  inline ReturnType at( size_t index ) const {
338  if( index >= vector_.size() ) {
339  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
340  }
341  return (*this)[index];
342  }
343  //**********************************************************************************************
344 
345  //**Begin function******************************************************************************
350  inline ConstIterator begin() const {
351  return ConstIterator( vector_.begin(), scalar_ );
352  }
353  //**********************************************************************************************
354 
355  //**End function********************************************************************************
360  inline ConstIterator end() const {
361  return ConstIterator( vector_.end(), scalar_ );
362  }
363  //**********************************************************************************************
364 
365  //**Size function*******************************************************************************
370  inline size_t size() const noexcept {
371  return vector_.size();
372  }
373  //**********************************************************************************************
374 
375  //**NonZeros function***************************************************************************
380  inline size_t nonZeros() const {
381  return vector_.nonZeros();
382  }
383  //**********************************************************************************************
384 
385  //**Find function*******************************************************************************
391  inline ConstIterator find( size_t index ) const {
393  return ConstIterator( vector_.find( index ), scalar_ );
394  }
395  //**********************************************************************************************
396 
397  //**LowerBound function*************************************************************************
403  inline ConstIterator lowerBound( size_t index ) const {
405  return ConstIterator( vector_.lowerBound( index ), scalar_ );
406  }
407  //**********************************************************************************************
408 
409  //**UpperBound function*************************************************************************
415  inline ConstIterator upperBound( size_t index ) const {
417  return ConstIterator( vector_.upperBound( index ), scalar_ );
418  }
419  //**********************************************************************************************
420 
421  //**Left operand access*************************************************************************
426  inline LeftOperand leftOperand() const noexcept {
427  return vector_;
428  }
429  //**********************************************************************************************
430 
431  //**Right operand access************************************************************************
436  inline RightOperand rightOperand() const noexcept {
437  return scalar_;
438  }
439  //**********************************************************************************************
440 
441  //**********************************************************************************************
447  template< typename T >
448  inline bool canAlias( const T* alias ) const noexcept {
449  return vector_.canAlias( alias );
450  }
451  //**********************************************************************************************
452 
453  //**********************************************************************************************
459  template< typename T >
460  inline bool isAliased( const T* alias ) const noexcept {
461  return vector_.isAliased( alias );
462  }
463  //**********************************************************************************************
464 
465  private:
466  //**Member variables****************************************************************************
469  //**********************************************************************************************
470 
471  //**Assignment to dense vectors*****************************************************************
485  template< typename VT2 > // Type of the target dense vector
486  friend inline auto assign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
488  {
490 
491  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
492 
493  assign( ~lhs, rhs.vector_ );
494  (~lhs) *= rhs.scalar_;
495  }
497  //**********************************************************************************************
498 
499  //**Assignment to sparse vectors****************************************************************
513  template< typename VT2 > // Type of the target sparse vector
514  friend inline auto assign( SparseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
516  {
518 
519  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
520 
521  assign( ~lhs, rhs.vector_ );
522  (~lhs) *= rhs.scalar_;
523  }
525  //**********************************************************************************************
526 
527  //**Addition assignment to dense vectors********************************************************
541  template< typename VT2 > // Type of the target dense vector
542  friend inline auto addAssign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
543  -> EnableIf_t< UseAssign_v<VT2> >
544  {
546 
550 
551  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
552 
553  const ResultType tmp( serial( rhs ) );
554  addAssign( ~lhs, tmp );
555  }
557  //**********************************************************************************************
558 
559  //**Addition assignment to sparse vectors*******************************************************
560  // No special implementation for the addition assignment to sparse vectors.
561  //**********************************************************************************************
562 
563  //**Subtraction assignment to dense vectors*****************************************************
577  template< typename VT2 > // Type of the target dense vector
578  friend inline auto subAssign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
579  -> EnableIf_t< UseAssign_v<VT2> >
580  {
582 
586 
587  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
588 
589  const ResultType tmp( serial( rhs ) );
590  subAssign( ~lhs, tmp );
591  }
593  //**********************************************************************************************
594 
595  //**Subtraction assignment to sparse vectors****************************************************
596  // No special implementation for the subtraction assignment to sparse vectors.
597  //**********************************************************************************************
598 
599  //**Multiplication assignment to dense vectors**************************************************
613  template< typename VT2 > // Type of the target dense vector
614  friend inline auto multAssign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
615  -> EnableIf_t< UseAssign_v<VT2> >
616  {
618 
622 
623  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
624 
625  const ResultType tmp( serial( rhs ) );
626  multAssign( ~lhs, tmp );
627  }
629  //**********************************************************************************************
630 
631  //**Multiplication assignment to sparse vectors*************************************************
632  // No special implementation for the multiplication assignment to sparse vectors.
633  //**********************************************************************************************
634 
635  //**SMP assignment to dense vectors*************************************************************
636  // No special implementation for the SMP assignment to dense vectors.
637  //**********************************************************************************************
638 
639  //**SMP assignment to sparse vectors************************************************************
640  // No special implementation for the SMP assignment to sparse vectors.
641  //**********************************************************************************************
642 
643  //**SMP addition assignment to dense vectors****************************************************
657  template< typename VT2 > // Type of the target dense vector
658  friend inline auto smpAddAssign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
659  -> EnableIf_t< UseSMPAssign_v<VT2> >
660  {
662 
666 
667  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
668 
669  const ResultType tmp( rhs );
670  smpAddAssign( ~lhs, tmp );
671  }
673  //**********************************************************************************************
674 
675  //**SMP addition assignment to sparse vectors***************************************************
676  // No special implementation for the SMP addition assignment to sparse vectors.
677  //**********************************************************************************************
678 
679  //**SMP subtraction assignment to dense vectors*************************************************
693  template< typename VT2 > // Type of the target dense vector
694  friend inline auto smpSubAssign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
695  -> EnableIf_t< UseSMPAssign_v<VT2> >
696  {
698 
702 
703  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
704 
705  const ResultType tmp( rhs );
706  smpSubAssign( ~lhs, tmp );
707  }
709  //**********************************************************************************************
710 
711  //**SMP subtraction assignment to sparse vectors************************************************
712  // No special implementation for the SMP subtraction assignment to sparse vectors.
713  //**********************************************************************************************
714 
715  //**SMP multiplication assignment to dense vectors**********************************************
729  template< typename VT2 > // Type of the target dense vector
730  friend inline auto smpMultAssign( DenseVector<VT2,TF>& lhs, const SVecScalarMultExpr& rhs )
731  -> EnableIf_t< UseSMPAssign_v<VT2> >
732  {
734 
738 
739  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
740 
741  const ResultType tmp( rhs );
742  smpMultAssign( ~lhs, tmp );
743  }
745  //**********************************************************************************************
746 
747  //**SMP multiplication assignment to sparse vectors*********************************************
748  // No special implementation for the SMP multiplication assignment to sparse vectors.
749  //**********************************************************************************************
750 
751  //**Compile time checks*************************************************************************
759  //**********************************************************************************************
760 };
761 //*************************************************************************************************
762 
763 
764 
765 
766 //=================================================================================================
767 //
768 // GLOBAL UNARY ARITHMETIC OPERATORS
769 //
770 //=================================================================================================
771 
772 //*************************************************************************************************
789 template< typename VT // Type of the sparse vector
790  , bool TF > // Transpose flag
791 inline decltype(auto) operator-( const SparseVector<VT,TF>& sv )
792 {
794 
795  using ScalarType = UnderlyingBuiltin_t<VT>;
796  using ReturnType = const SVecScalarMultExpr<VT,ScalarType,TF>;
797  return ReturnType( ~sv, ScalarType(-1) );
798 }
799 //*************************************************************************************************
800 
801 
802 
803 
804 //=================================================================================================
805 //
806 // GLOBAL BINARY ARITHMETIC OPERATORS
807 //
808 //=================================================================================================
809 
810 //*************************************************************************************************
823 template< typename VT // Type of the left-hand side sparse vector
824  , bool TF // Transpose flag of the left-hand side sparse vector
825  , typename ST // Type of the right-hand side scalar
826  , DisableIf_t< IsZero_v<VT> >* = nullptr >
827 inline const SVecScalarMultExpr< VT, MultTrait_t< UnderlyingBuiltin_t<VT>, ST >, TF >
828  svecscalarmult( const SparseVector<VT,TF>& vec, ST scalar )
829 {
831 
832  using ScalarType = MultTrait_t< UnderlyingBuiltin_t<VT>, ST >;
833  using ReturnType = const SVecScalarMultExpr<VT,ScalarType,TF>;
834  return ReturnType( ~vec, scalar );
835 }
837 //*************************************************************************************************
838 
839 
840 //*************************************************************************************************
853 template< typename VT // Type of the left-hand side sparse vector
854  , bool TF // Transpose flag of the left-hand side sparse vector
855  , typename ST // Type of the right-hand side scalar
856  , EnableIf_t< IsZero_v<VT> >* = nullptr >
857 inline decltype(auto)
858  svecscalarmult( const SparseVector<VT,TF>& vec, ST scalar )
859 {
861 
862  MAYBE_UNUSED( scalar );
863 
864  using ReturnType = const MultTrait_t< ResultType_t<VT>, ST >;
865 
868 
869  return ReturnType( (~vec).size() );
870 }
872 //*************************************************************************************************
873 
874 
875 //*************************************************************************************************
896 template< typename VT // Type of the left-hand side sparse vector
897  , typename ST // Type of the right-hand side scalar
898  , bool TF // Transpose flag
899  , EnableIf_t< IsNumeric_v<ST> >* = nullptr >
900 inline decltype(auto) operator*( const SparseVector<VT,TF>& vec, ST scalar )
901 {
903 
904  return svecscalarmult( ~vec, scalar );
905 }
906 //*************************************************************************************************
907 
908 
909 //*************************************************************************************************
930 template< typename ST // Type of the left-hand side scalar
931  , typename VT // Type of the right-hand side sparse vector
932  , bool TF // Transpose flag
933  , EnableIf_t< IsNumeric_v<ST> >* = nullptr >
934 inline decltype(auto) operator*( ST scalar, const SparseVector<VT,TF>& vec )
935 {
937 
938  return svecscalarmult( ~vec, scalar );
939 }
940 //*************************************************************************************************
941 
942 
943 
944 
945 //=================================================================================================
946 //
947 // GLOBAL FUNCTIONS
948 //
949 //=================================================================================================
950 
951 //*************************************************************************************************
969 template< typename VT // Type of the sparse vector
970  , bool TF > // Transpose flag
971 inline decltype(auto) normalize( const SparseVector<VT,TF>& vec )
972 {
973  using ElementType = ElementType_t<VT>;
974 
976 
977  const ElementType len ( length( ~vec ) );
978  const ElementType ilen( ( len != ElementType(0) )?( ElementType(1) / len ):( 0 ) );
979 
980  using ReturnType = const SVecScalarMultExpr<VT,ElementType,TF>;
981  return ReturnType( ~vec, ilen );
982 }
983 //*************************************************************************************************
984 
985 
986 
987 
988 //=================================================================================================
989 //
990 // GLOBAL RESTRUCTURING UNARY ARITHMETIC OPERATORS
991 //
992 //=================================================================================================
993 
994 //*************************************************************************************************
1006 template< typename VT // Type of the sparse vector
1007  , typename ST // Type of the scalar
1008  , bool TF > // Transpose flag
1009 inline decltype(auto) operator-( const SVecScalarMultExpr<VT,ST,TF>& sv )
1010 {
1012 
1013  using ReturnType = const SVecScalarMultExpr<VT,ST,TF>;
1014  return ReturnType( sv.leftOperand(), -sv.rightOperand() );
1015 }
1017 //*************************************************************************************************
1018 
1019 
1020 
1021 
1022 //=================================================================================================
1023 //
1024 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1025 //
1026 //=================================================================================================
1027 
1028 //*************************************************************************************************
1041 template< typename VT // Type of the sparse vector of the left-hand side expression
1042  , typename ST1 // Type of the scalar of the left-hand side expression
1043  , bool TF // Transpose flag of the sparse vector
1044  , typename ST2 // Type of the right-hand side scalar
1045  , EnableIf_t< IsNumeric_v<ST2> >* = nullptr >
1046 inline decltype(auto) operator*( const SVecScalarMultExpr<VT,ST1,TF>& vec, ST2 scalar )
1047 {
1049 
1050  return vec.leftOperand() * ( vec.rightOperand() * scalar );
1051 }
1053 //*************************************************************************************************
1054 
1055 
1056 //*************************************************************************************************
1069 template< typename ST1 // Type of the left-hand side scalar
1070  , typename VT // Type of the sparse vector of the right-hand side expression
1071  , typename ST2 // Type of the scalar of the right-hand side expression
1072  , bool TF // Transpose flag of the sparse vector
1073  , EnableIf_t< IsNumeric_v<ST1> >* = nullptr >
1074 inline decltype(auto) operator*( ST1 scalar, const SVecScalarMultExpr<VT,ST2,TF>& vec )
1075 {
1077 
1078  return vec.leftOperand() * ( scalar * vec.rightOperand() );
1079 }
1081 //*************************************************************************************************
1082 
1083 
1084 //*************************************************************************************************
1097 template< typename VT // Type of the dense vector of the left-hand side expression
1098  , typename ST1 // Type of the scalar of the left-hand side expression
1099  , bool TF // Transpose flag of the dense vector
1100  , typename ST2 // Type of the right-hand side scalar
1101  , EnableIf_t< IsNumeric_v<ST2> && ( IsInvertible_v<ST1> || IsInvertible_v<ST2> ) >* = nullptr >
1102 inline decltype(auto) operator/( const SVecScalarMultExpr<VT,ST1,TF>& vec, ST2 scalar )
1103 {
1105 
1106  return vec.leftOperand() * ( vec.rightOperand() / scalar );
1107 }
1109 //*************************************************************************************************
1110 
1111 
1112 //*************************************************************************************************
1126 template< typename VT1 // Type of the sparse vector of the left-hand side expression
1127  , typename ST // Type of the scalar of the left-hand side expression
1128  , bool TF // Transpose flag of the dense vectors
1129  , typename VT2 > // Type of the right-hand side dense vector
1130 inline decltype(auto)
1131  operator*( const SVecScalarMultExpr<VT1,ST,TF>& lhs, const DenseVector<VT2,TF>& rhs )
1132 {
1134 
1135  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1136 }
1138 //*************************************************************************************************
1139 
1140 
1141 //*************************************************************************************************
1155 template< typename VT1 // Type of the left-hand side dense vector
1156  , bool TF // Transpose flag of the dense vectors
1157  , typename VT2 // Type of the sparse vector of the right-hand side expression
1158  , typename ST > // Type of the scalar of the right-hand side expression
1159 inline decltype(auto)
1160  operator*( const DenseVector<VT1,TF>& lhs, const SVecScalarMultExpr<VT2,ST,TF>& rhs )
1161 {
1163 
1164  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1165 }
1167 //*************************************************************************************************
1168 
1169 
1170 //*************************************************************************************************
1184 template< typename VT1 // Type of the sparse vector of the left-hand side expression
1185  , typename ST // Type of the scalar of the left-hand side expression
1186  , typename VT2 > // Type of the right-hand side dense vector
1187 inline decltype(auto)
1188  operator*( const SVecScalarMultExpr<VT1,ST,false>& lhs, const DenseVector<VT2,true>& rhs )
1189 {
1191 
1192  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1193 }
1195 //*************************************************************************************************
1196 
1197 
1198 //*************************************************************************************************
1212 template< typename VT1 // Type of the left-hand side dense vector
1213  , typename VT2 // Type of the sparse vector of the right-hand side expression
1214  , typename ST > // Type of the scalar of the right-hand side expression
1215 inline decltype(auto)
1216  operator*( const DenseVector<VT1,false>& lhs, const SVecScalarMultExpr<VT2,ST,true>& rhs )
1217 {
1219 
1220  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1221 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1240 template< typename VT1 // Type of the sparse vector of the left-hand side expression
1241  , typename ST // Type of the scalar of the left-hand side expression
1242  , bool TF // Transpose flag of the vectors
1243  , typename VT2 > // Type of the right-hand side sparse vector
1244 inline decltype(auto)
1245  operator*( const SVecScalarMultExpr<VT1,ST,TF>& lhs, const SparseVector<VT2,TF>& rhs )
1246 {
1248 
1249  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1250 }
1252 //*************************************************************************************************
1253 
1254 
1255 //*************************************************************************************************
1269 template< typename VT1 // Type of the left-hand side sparse vector
1270  , bool TF // Transpose flag of the vectors
1271  , typename VT2 // Type of the sparse vector of the right-hand side expression
1272  , typename ST > // Type of the scalar of the right-hand side expression
1273 inline decltype(auto)
1274  operator*( const SparseVector<VT1,TF>& lhs, const SVecScalarMultExpr<VT2,ST,TF>& rhs )
1275 {
1277 
1278  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1279 }
1281 //*************************************************************************************************
1282 
1283 
1284 //*************************************************************************************************
1298 template< typename VT1 // Type of the sparse vector of the left-hand side expression
1299  , typename ST1 // Type of the scalar of the left-hand side expression
1300  , bool TF // Transpose flag of the sparse vectors
1301  , typename VT2 // Type of the sparse vector of the right-hand side expression
1302  , typename ST2 > // Type of the scalar of the right-hand side expression
1303 inline decltype(auto)
1304  operator*( const SVecScalarMultExpr<VT1,ST1,TF>& lhs, const SVecScalarMultExpr<VT2,ST2,TF>& rhs )
1305 {
1307 
1308  return ( lhs.leftOperand() * rhs.leftOperand() ) * ( lhs.rightOperand() * rhs.rightOperand() );
1309 }
1311 //*************************************************************************************************
1312 
1313 
1314 //*************************************************************************************************
1328 template< typename VT1 // Type of the sparse vector of the left-hand side expression
1329  , typename ST // Type of the scalar of the left-hand side expression
1330  , typename VT2 > // Type of the right-hand side sparse vector
1331 inline decltype(auto)
1332  operator*( const SVecScalarMultExpr<VT1,ST,false>& lhs, const SparseVector<VT2,true>& rhs )
1333 {
1335 
1336  return ( lhs.leftOperand() * (~rhs) ) * lhs.rightOperand();
1337 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1356 template< typename VT1 // Type of the left-hand side sparse vector
1357  , typename VT2 // Type of the sparse vector of the right-hand side expression
1358  , typename ST > // Type of the scalar of the right-hand side expression
1359 inline decltype(auto)
1360  operator*( const SparseVector<VT1,false>& lhs, const SVecScalarMultExpr<VT2,ST,true>& rhs )
1361 {
1363 
1364  return ( (~lhs) * rhs.leftOperand() ) * rhs.rightOperand();
1365 }
1367 //*************************************************************************************************
1368 
1369 
1370 //*************************************************************************************************
1384 template< typename VT1 // Type of the sparse vector of the left-hand side expression
1385  , typename ST1 // Type of the scalar of the left-hand side expression
1386  , typename VT2 // Type of the sparse vector of the right-hand side expression
1387  , typename ST2 > // Type of the scalar of the right-hand side expression
1388 inline decltype(auto)
1389  operator*( const SVecScalarMultExpr<VT1,ST1,false>& lhs, const SVecScalarMultExpr<VT2,ST2,true>& rhs )
1390 {
1392 
1393  return ( lhs.leftOperand() * rhs.leftOperand() ) * ( lhs.rightOperand() * rhs.rightOperand() );
1394 }
1396 //*************************************************************************************************
1397 
1398 
1399 //*************************************************************************************************
1413 template< typename MT // Type of the left-hand side dense matrix
1414  , bool SO // Storage order of the left-hand side dense matrix
1415  , typename VT // Type of the sparse vector of the right-hand side expression
1416  , typename ST > // Type of the scalar of the right-hand side expression
1417 inline decltype(auto)
1418  operator*( const DenseMatrix<MT,SO>& mat, const SVecScalarMultExpr<VT,ST,false>& vec )
1419 {
1421 
1422  return ( (~mat) * vec.leftOperand() ) * vec.rightOperand();
1423 }
1425 //*************************************************************************************************
1426 
1427 
1428 //*************************************************************************************************
1442 template< typename VT // Type of the sparse vector of the left-hand side expression
1443  , typename ST // Type of the scalar of the left-hand side expression
1444  , typename MT // Type of the right-hand side dense matrix
1445  , bool SO > // Storage order of the right-hand side dense matrix
1446 inline decltype(auto)
1447  operator*( const SVecScalarMultExpr<VT,ST,true>& vec, const DenseMatrix<MT,SO>& mat )
1448 {
1450 
1451  return ( vec.leftOperand() * (~mat) ) * vec.rightOperand();
1452 }
1454 //*************************************************************************************************
1455 
1456 
1457 //*************************************************************************************************
1471 template< typename MT // Type of the left-hand side sparse matrix
1472  , bool SO // Storage order of the left-hand side sparse matrix
1473  , typename VT // Type of the sparse vector of the right-hand side expression
1474  , typename ST > // Type of the scalar of the right-hand side expression
1475 inline decltype(auto)
1476  operator*( const SparseMatrix<MT,SO>& mat, const SVecScalarMultExpr<VT,ST,false>& vec )
1477 {
1479 
1480  return ( (~mat) * vec.leftOperand() ) * vec.rightOperand();
1481 }
1483 //*************************************************************************************************
1484 
1485 
1486 //*************************************************************************************************
1500 template< typename VT // Type of the sparse vector of the left-hand side expression
1501  , typename ST // Type of the scalar of the left-hand side expression
1502  , typename MT // Type of the right-hand side sparse matrix
1503  , bool SO > // Storage order of the right-hand side sparse matrix
1504 inline decltype(auto)
1505  operator*( const SVecScalarMultExpr<VT,ST,true>& vec, const SparseMatrix<MT,SO>& mat )
1506 {
1508 
1509  return ( vec.leftOperand() * (~mat) ) * vec.rightOperand();
1510 }
1512 //*************************************************************************************************
1513 
1514 } // namespace blaze
1515 
1516 #endif
RightOperand rightOperand() const noexcept
Returns the right-hand side scalar operand.
Definition: SVecScalarMultExpr.h:436
Pointer difference type of the Blaze library.
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SVecScalarMultExpr.h:158
size_t nonZeros() const
Returns the number of non-zero elements in the sparse vector.
Definition: SVecScalarMultExpr.h:380
bool operator==(const ConstIterator &rhs) const
Equality comparison between two ConstIterator objects.
Definition: SVecScalarMultExpr.h:271
Header file for auxiliary alias declarations.
Data type constraint.
Constraint on the data type.
Header file for basic type definitions.
Header file for the SparseVector base class.
bool operator!=(const ConstIterator &rhs) const
Inequality comparison between two ConstIterator objects.
Definition: SVecScalarMultExpr.h:282
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
ConstIterator_t< RemoveReference_t< LeftOperand > > IteratorType
Iterator type of the sparse vector expression.
Definition: SVecScalarMultExpr.h:189
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.
const Element operator *() const
Direct access to the sparse vector element at the current iterator position.
Definition: SVecScalarMultExpr.h:230
IteratorCategory iterator_category
The iterator category.
Definition: SVecScalarMultExpr.h:198
DifferenceType operator-(const ConstIterator &rhs) const
Calculating the number of elements between two expression iterators.
Definition: SVecScalarMultExpr.h:293
ConstIterator begin() const
Returns an iterator to the first non-zero element of the sparse vector.
Definition: SVecScalarMultExpr.h:350
Constraint on the data type.
Header file for the MAYBE_UNUSED function template.
Iterator over the elements of the sparse vector/scalar multiplication expression.
Definition: SVecScalarMultExpr.h:181
MultTrait_t< RT, ST > ResultType
Result type for expression template evaluations.
Definition: SVecScalarMultExpr.h:156
Header file for the Computation base class.
Header file for the RequiresEvaluation type trait.
ValueType & ReferenceType
Reference return type.
Definition: SVecScalarMultExpr.h:194
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
Header file for the VecScalarMultExpr base class.
ValueIndexPair< ElementType > Element
Element type of the sparse vector expression.
Definition: SVecScalarMultExpr.h:186
std::forward_iterator_tag IteratorCategory
The iterator category.
Definition: SVecScalarMultExpr.h:191
ConstIterator & operator++()
Pre-increment operator.
Definition: SVecScalarMultExpr.h:219
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
ReturnType_t< VT > RN
Return type of the sparse vector expression.
Definition: SVecScalarMultExpr.h:104
RightOperand scalar_
Right-hand side scalar of the multiplication expression.
Definition: SVecScalarMultExpr.h:468
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
Header file for the ValueIndexPair class.
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
Element ValueType
Type of the underlying pointers.
Definition: SVecScalarMultExpr.h:192
#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
RightOperand scalar_
Right-hand side scalar of the multiplication expression.
Definition: SVecScalarMultExpr.h:301
Header file for the UnderlyingBuiltin type trait.
#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
decltype(auto) normalize(const DenseVector< VT, TF > &vec)
Normalization of the dense vector ( ).
Definition: DVecScalarMultExpr.h:1149
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecScalarMultExpr.h:460
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
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type,...
Definition: SparseVector.h:61
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the multiplication expression.
Definition: SVecScalarMultExpr.h:129
Constraint on the data type.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecScalarMultExpr.h:161
ResultType_t< VT > RT
Result type of the sparse vector expression.
Definition: SVecScalarMultExpr.h:103
Header file for the exception macros of the math module.
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SVecScalarMultExpr.h:175
ValueType * PointerType
Pointer return type.
Definition: SVecScalarMultExpr.h:193
If_t< IsExpression_v< VT >, const VT, const VT & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecScalarMultExpr.h:167
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SVecScalarMultExpr.h:324
Constraint on the data type.
Constraint on the data type.
const ConstIterator * operator->() const
Direct access to the sparse vector element at the current iterator position.
Definition: SVecScalarMultExpr.h:240
Header file for the EnableIf class template.
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
Header file for the IsNumeric type trait.
decltype(auto) length(const DenseVector< VT, TF > &dv)
Calculation of the length (magnitude) of the dense vector .
Definition: DVecNormExpr.h:596
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
If_t< useAssign, const ResultType, const SVecScalarMultExpr & > CompositeType
Data type for composite expression templates.
Definition: SVecScalarMultExpr.h:164
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
IteratorType vector_
Iterator over the elements of the left-hand side sparse vector expression.
Definition: SVecScalarMultExpr.h:300
ConstIterator lowerBound(size_t index) const
Returns an iterator to the first index not less then the given index.
Definition: SVecScalarMultExpr.h:403
ConstIterator end() const
Returns an iterator just past the last non-zero element of the sparse vector.
Definition: SVecScalarMultExpr.h:360
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecScalarMultExpr.h:448
typename UnderlyingBuiltin< T >::Type UnderlyingBuiltin_t
Auxiliary alias declaration for the UnderlyingBuiltin type trait.The UnderlyingBuiltin_t alias declar...
Definition: UnderlyingBuiltin.h:116
Constraint on the data type.
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: SVecScalarMultExpr.h:370
#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
Header file for all forward declarations for expression class templates.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
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
Header file for the RemoveReference type trait.
Header file for the IsInvertible type trait.
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SVecScalarMultExpr.h:115
ConstIterator find(size_t index) const
Searches for a specific vector element.
Definition: SVecScalarMultExpr.h:391
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
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.
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
Expression object for sparse vector-scalar multiplications.The SVecScalarMultExpr class represents th...
Definition: Forward.h:157
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:146
size_t index() const
Access to the current index of the sparse element.
Definition: SVecScalarMultExpr.h:260
SVecScalarMultExpr(const VT &vector, ST scalar) noexcept
Constructor for the SVecScalarMultExpr class.
Definition: SVecScalarMultExpr.h:312
ConstIterator upperBound(size_t index) const
Returns an iterator to the first index greater then the given index.
Definition: SVecScalarMultExpr.h:415
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecScalarMultExpr.h:157
ptrdiff_t DifferenceType
Difference between two iterators.
Definition: SVecScalarMultExpr.h:195
LeftOperand vector_
Left-hand side sparse vector of the multiplication expression.
Definition: SVecScalarMultExpr.h:467
CompositeType_t< VT > CT
Composite type of the sparse vector expression.
Definition: SVecScalarMultExpr.h:105
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: SVecScalarMultExpr.h:337
ReturnType value() const
Access to the current value of the sparse element.
Definition: SVecScalarMultExpr.h:250
#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_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
decltype(std::declval< RN >() *std::declval< ST >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SVecScalarMultExpr.h:118
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecScalarMultExpr.h:426
ST RightOperand
Composite type of the right-hand side scalar value.
Definition: SVecScalarMultExpr.h:170
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:191
#define BLAZE_CONSTRAINT_MUST_BE_FLOATING_POINT_TYPE(T)
Constraint on the data type.In case the given data type T is not a floating point data type,...
Definition: FloatingPoint.h:61
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
ConstIterator(IteratorType vector, RightOperand scalar)
Constructor for the ConstIterator class.
Definition: SVecScalarMultExpr.h:208