SMatSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
53 #include <blaze/math/Exception.h>
59 #include <blaze/math/shims/Reset.h>
68 #include <blaze/math/views/Check.h>
70 #include <blaze/util/Assert.h>
71 #include <blaze/util/DisableIf.h>
72 #include <blaze/util/EnableIf.h>
74 #include <blaze/util/mpl/If.h>
75 #include <blaze/util/Types.h>
76 #include <blaze/util/Unused.h>
77 
78 
79 namespace blaze {
80 
81 //=================================================================================================
82 //
83 // CLASS SMATDVECMULTEXPR
84 //
85 //=================================================================================================
86 
87 //*************************************************************************************************
94 template< typename MT // Type of the left-hand side sparse matrix
95  , typename VT > // Type of the right-hand side sparse vector
96 class SMatSVecMultExpr
97  : public MatVecMultExpr< SparseVector< SMatSVecMultExpr<MT,VT>, false > >
98  , private Computation
99 {
100  private:
101  //**Type definitions****************************************************************************
106  //**********************************************************************************************
107 
108  //**********************************************************************************************
110  static constexpr bool evaluateMatrix = RequiresEvaluation_v<MT>;
111  //**********************************************************************************************
112 
113  //**********************************************************************************************
115  static constexpr bool evaluateVector = ( RequiresEvaluation_v<VT> || IsComputation_v<VT> );
116  //**********************************************************************************************
117 
118  //**********************************************************************************************
120 
124  template< typename T1 >
125  static constexpr bool UseSMPAssign_v = ( evaluateMatrix || evaluateVector );
127  //**********************************************************************************************
128 
129  public:
130  //**Type definitions****************************************************************************
136  using ReturnType = const ElementType;
137 
139  using CompositeType = const ResultType;
140 
142  using LeftOperand = If_t< IsExpression_v<MT>, const MT, const MT& >;
143 
145  using RightOperand = If_t< IsExpression_v<VT>, const VT, const VT& >;
146 
149 
152  //**********************************************************************************************
153 
154  //**Compilation flags***************************************************************************
156  static constexpr bool smpAssignable =
158  //**********************************************************************************************
159 
160  //**Constructor*********************************************************************************
166  explicit inline SMatSVecMultExpr( const MT& mat, const VT& vec ) noexcept
167  : mat_( mat ) // Left-hand side sparse matrix of the multiplication expression
168  , vec_( vec ) // Right-hand side sparse vector of the multiplication expression
169  {
170  BLAZE_INTERNAL_ASSERT( mat_.columns() == vec_.size(), "Invalid matrix and vector sizes" );
171  }
172  //**********************************************************************************************
173 
174  //**Subscript operator**************************************************************************
180  inline ReturnType operator[]( size_t index ) const {
181  BLAZE_INTERNAL_ASSERT( index < mat_.rows(), "Invalid vector access index" );
182  return row( mat_, index, unchecked ) * vec_;
183  }
184  //**********************************************************************************************
185 
186  //**At function*********************************************************************************
193  inline ReturnType at( size_t index ) const {
194  if( index >= mat_.rows() ) {
195  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
196  }
197  return (*this)[index];
198  }
199  //**********************************************************************************************
200 
201  //**Size function*******************************************************************************
206  inline size_t size() const noexcept {
207  return mat_.rows();
208  }
209  //**********************************************************************************************
210 
211  //**NonZeros function***************************************************************************
216  inline size_t nonZeros() const {
217  return mat_.rows();
218  }
219  //**********************************************************************************************
220 
221  //**Left operand access*************************************************************************
226  inline LeftOperand leftOperand() const noexcept {
227  return mat_;
228  }
229  //**********************************************************************************************
230 
231  //**Right operand access************************************************************************
236  inline RightOperand rightOperand() const noexcept {
237  return vec_;
238  }
239  //**********************************************************************************************
240 
241  //**********************************************************************************************
247  template< typename T >
248  inline bool canAlias( const T* alias ) const noexcept {
249  return ( mat_.isAliased( alias ) || vec_.isAliased( alias ) );
250  }
251  //**********************************************************************************************
252 
253  //**********************************************************************************************
259  template< typename T >
260  inline bool isAliased( const T* alias ) const noexcept {
261  return ( mat_.isAliased( alias ) || vec_.isAliased( alias ) );
262  }
263  //**********************************************************************************************
264 
265  //**********************************************************************************************
270  inline bool canSMPAssign() const noexcept {
271  return ( size() > SMP_SMATSVECMULT_THRESHOLD );
272  }
273  //**********************************************************************************************
274 
275  private:
276  //**Member variables****************************************************************************
279  //**********************************************************************************************
280 
281  //**Assignment to dense vectors*****************************************************************
293  template< typename VT1 > // Type of the target dense vector
294  friend inline void assign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
295  {
297 
298  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
299 
300  // Resetting the left-hand side target dense vector
301  reset( ~lhs );
302 
303  // Evaluation of the right-hand side sparse vector operand
304  RT x( serial( rhs.vec_ ) );
305  if( x.nonZeros() == 0UL ) return;
306 
307  // Evaluation of the left-hand side sparse matrix operand
308  LT A( serial( rhs.mat_ ) );
309 
310  // Checking the evaluated operators
311  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
312  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
313  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
314  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
315 
316  // Performing the sparse matrix-sparse vector multiplication
317  SMatSVecMultExpr::selectAssignKernel( ~lhs, A, x );
318  }
320  //**********************************************************************************************
321 
322  //**Default assignment to dense vectors*********************************************************
336  template< typename VT1 // Type of the left-hand side target vector
337  , typename MT1 // Type of the left-hand side matrix operand
338  , typename VT2 > // Type of the right-hand side vector operand
339  static inline void selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
340  {
341  const auto vend( x.end() );
342 
343  for( size_t i=0UL; i<y.size(); ++i )
344  {
345  const auto mend ( A.end(i) );
346  auto melem( A.begin(i) );
347 
348  if( melem == mend ) continue;
349 
350  auto velem( x.begin() );
351 
352  while( true ) {
353  if( melem->index() < velem->index() ) {
354  ++melem;
355  if( melem == mend ) break;
356  }
357  else if( velem->index() < melem->index() ) {
358  ++velem;
359  if( velem == vend ) break;
360  }
361  else {
362  y[i] = melem->value() * velem->value();
363  ++melem;
364  ++velem;
365  break;
366  }
367  }
368 
369  if( melem != mend && velem != vend )
370  {
371  while( true ) {
372  if( melem->index() < velem->index() ) {
373  ++melem;
374  if( melem == mend ) break;
375  }
376  else if( velem->index() < melem->index() ) {
377  ++velem;
378  if( velem == vend ) break;
379  }
380  else {
381  y[i] += melem->value() * velem->value();
382  ++melem;
383  if( melem == mend ) break;
384  ++velem;
385  if( velem == vend ) break;
386  }
387  }
388  }
389  }
390  }
392  //**********************************************************************************************
393 
394  //**Assignment to sparse vectors****************************************************************
406  template< typename VT1 > // Type of the target sparse vector
407  friend inline void assign( SparseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
408  {
410 
411  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
412 
413  RT x( rhs.vec_ ); // Evaluation of the right-hand side sparse vector operand
414  if( x.nonZeros() == 0UL ) return;
415 
416  LT A( rhs.mat_ ); // Evaluation of the left-hand side sparse matrix operand
417 
418  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
419  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
420  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
421  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
422 
423  ElementType accu;
424  const auto vend( x.end() );
425 
426  for( size_t i=0UL; i<(~lhs).size(); ++i )
427  {
428  const auto mend ( A.end(i) );
429  auto melem( A.begin(i) );
430 
431  if( melem == mend ) continue;
432 
433  auto velem( x.begin() );
434 
435  reset( accu );
436 
437  while( true ) {
438  if( melem->index() < velem->index() ) {
439  ++melem;
440  if( melem == mend ) break;
441  }
442  else if( velem->index() < melem->index() ) {
443  ++velem;
444  if( velem == vend ) break;
445  }
446  else {
447  accu = melem->value() * velem->value();
448  ++melem;
449  ++velem;
450  break;
451  }
452  }
453 
454  if( melem != mend && velem != vend )
455  {
456  while( true ) {
457  if( melem->index() < velem->index() ) {
458  ++melem;
459  if( melem == mend ) break;
460  }
461  else if( velem->index() < melem->index() ) {
462  ++velem;
463  if( velem == vend ) break;
464  }
465  else {
466  accu += melem->value() * velem->value();
467  ++melem;
468  if( melem == mend ) break;
469  ++velem;
470  if( velem == vend ) break;
471  }
472  }
473  }
474 
475  if( !isDefault( accu ) )
476  (~lhs).insert( i, accu );
477  }
478  }
480  //**********************************************************************************************
481 
482  //**Addition assignment to dense vectors********************************************************
494  template< typename VT1 > // Type of the target dense vector
495  friend inline void addAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
496  {
498 
499  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
500 
501  // Evaluation of the right-hand side sparse vector operand
502  RT x( serial( rhs.vec_ ) );
503  if( x.nonZeros() == 0UL ) return;
504 
505  // Evaluation of the left-hand side sparse matrix operand
506  LT A( serial( rhs.mat_ ) );
507 
508  // Checking the evaluated operators
509  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
510  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
511  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
512  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
513 
514  // Performing the sparse matrix-sparse vector multiplication
515  SMatSVecMultExpr::selectAddAssignKernel( ~lhs, A, x );
516  }
518  //**********************************************************************************************
519 
520  //**Default addition assignment to dense vectors************************************************
534  template< typename VT1 // Type of the left-hand side target vector
535  , typename MT1 // Type of the left-hand side matrix operand
536  , typename VT2 > // Type of the right-hand side vector operand
537  static inline void selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
538  {
539  const auto vend( x.end() );
540 
541  for( size_t i=0UL; i<y.size(); ++i )
542  {
543  const auto mend ( A.end(i) );
544  auto melem( A.begin(i) );
545 
546  if( melem == mend ) continue;
547 
548  auto velem( x.begin() );
549 
550  while( true ) {
551  if( melem->index() < velem->index() ) {
552  ++melem;
553  if( melem == mend ) break;
554  }
555  else if( velem->index() < melem->index() ) {
556  ++velem;
557  if( velem == vend ) break;
558  }
559  else {
560  y[i] += melem->value() * velem->value();
561  ++melem;
562  if( melem == mend ) break;
563  ++velem;
564  if( velem == vend ) break;
565  }
566  }
567  }
568  }
570  //**********************************************************************************************
571 
572  //**Addition assignment to sparse vectors*******************************************************
573  // No special implementation for the addition assignment to sparse vectors.
574  //**********************************************************************************************
575 
576  //**Subtraction assignment to dense vectors*****************************************************
588  template< typename VT1 > // Type of the target dense vector
589  friend inline void subAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
590  {
592 
593  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
594 
595  // Evaluation of the right-hand side sparse vector operand
596  RT x( serial( rhs.vec_ ) );
597  if( x.nonZeros() == 0UL ) return;
598 
599  // Evaluation of the left-hand side sparse matrix operand
600  LT A( serial( rhs.mat_ ) );
601 
602  // Checking the evaluated operators
603  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
604  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
605  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
606  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
607 
608  // Performing the sparse matrix-sparse vector multiplication
609  SMatSVecMultExpr::selectSubAssignKernel( ~lhs, A, x );
610  }
612  //**********************************************************************************************
613 
614  //**Default subtraction assignment to dense vectors*********************************************
628  template< typename VT1 // Type of the left-hand side target vector
629  , typename MT1 // Type of the left-hand side matrix operand
630  , typename VT2 > // Type of the right-hand side vector operand
631  static inline void selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
632  {
633  const auto vend( x.end() );
634 
635  for( size_t i=0UL; i<y.size(); ++i )
636  {
637  const auto mend ( A.end(i) );
638  auto melem( A.begin(i) );
639 
640  if( melem == mend ) continue;
641 
642  auto velem( x.begin() );
643 
644  while( true ) {
645  if( melem->index() < velem->index() ) {
646  ++melem;
647  if( melem == mend ) break;
648  }
649  else if( velem->index() < melem->index() ) {
650  ++velem;
651  if( velem == vend ) break;
652  }
653  else {
654  y[i] -= melem->value() * velem->value();
655  ++melem;
656  if( melem == mend ) break;
657  ++velem;
658  if( velem == vend ) break;
659  }
660  }
661  }
662  }
664  //**********************************************************************************************
665 
666  //**Subtraction assignment to sparse vectors****************************************************
667  // No special implementation for the subtraction assignment to sparse vectors.
668  //**********************************************************************************************
669 
670  //**Multiplication assignment to dense vectors**************************************************
682  template< typename VT1 > // Type of the target dense vector
683  friend inline void multAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
684  {
686 
690 
691  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
692 
693  const ResultType tmp( serial( rhs ) );
694  multAssign( ~lhs, tmp );
695  }
697  //**********************************************************************************************
698 
699  //**Multiplication assignment to sparse vectors*************************************************
700  // No special implementation for the multiplication assignment to sparse vectors.
701  //**********************************************************************************************
702 
703  //**SMP assignment to dense vectors*************************************************************
717  template< typename VT1 > // Type of the target dense vector
718  friend inline auto smpAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
719  -> EnableIf_t< UseSMPAssign_v<VT1> >
720  {
722 
723  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
724 
725  // Resetting the left-hand side target dense vector
726  reset( ~lhs );
727 
728  // Evaluation of the right-hand side sparse vector operand
729  RT x( rhs.vec_ );
730  if( x.nonZeros() == 0UL ) return;
731 
732  // Evaluation of the left-hand side sparse matrix operand
733  LT A( rhs.mat_ );
734 
735  // Checking the evaluated operators
736  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
737  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
738  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
739  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
740 
741  // Performing the sparse matrix-sparse vector multiplication
742  smpAssign( ~lhs, A * x );
743  }
745  //**********************************************************************************************
746 
747  //**SMP assignment to sparse vectors************************************************************
748  // No special implementation for the SMP assignment to sparse vectors.
749  //**********************************************************************************************
750 
751  //**SMP addition assignment to dense vectors****************************************************
766  template< typename VT1 > // Type of the target dense vector
767  friend inline auto smpAddAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
768  -> EnableIf_t< UseSMPAssign_v<VT1> >
769  {
771 
772  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
773 
774  // Evaluation of the right-hand side sparse vector operand
775  RT x( rhs.vec_ );
776  if( x.nonZeros() == 0UL ) return;
777 
778  // Evaluation of the left-hand side sparse matrix operand
779  LT A( rhs.mat_ );
780 
781  // Checking the evaluated operators
782  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
783  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
784  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
785  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
786 
787  // Performing the sparse matrix-sparse vector multiplication
788  smpAddAssign( ~lhs, A * x );
789  }
791  //**********************************************************************************************
792 
793  //**SMP addition assignment to sparse vectors***************************************************
794  // No special implementation for the SMP addition assignment to sparse vectors.
795  //**********************************************************************************************
796 
797  //**SMP subtraction assignment to dense vectors*************************************************
812  template< typename VT1 > // Type of the target dense vector
813  friend inline auto smpSubAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
814  -> EnableIf_t< UseSMPAssign_v<VT1> >
815  {
817 
818  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
819 
820  // Evaluation of the right-hand side sparse vector operand
821  RT x( rhs.vec_ );
822  if( x.nonZeros() == 0UL ) return;
823 
824  // Evaluation of the left-hand side sparse matrix operand
825  LT A( rhs.mat_ );
826 
827  // Checking the evaluated operators
828  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
829  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
830  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
831  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).size() , "Invalid vector size" );
832 
833  // Performing the sparse matrix-sparse vector multiplication
834  smpSubAssign( ~lhs, A * x );
835  }
837  //**********************************************************************************************
838 
839  //**SMP subtraction assignment to sparse vectors************************************************
840  // No special implementation for the SMP subtraction assignment to sparse vectors.
841  //**********************************************************************************************
842 
843  //**SMP multiplication assignment to dense vectors**********************************************
858  template< typename VT1 > // Type of the target dense vector
859  friend inline auto smpMultAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
860  -> EnableIf_t< UseSMPAssign_v<VT1> >
861  {
863 
867 
868  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
869 
870  const ResultType tmp( rhs );
871  smpMultAssign( ~lhs, tmp );
872  }
874  //**********************************************************************************************
875 
876  //**SMP multiplication assignment to sparse vectors*********************************************
877  // No special implementation for the SMP multiplication assignment to sparse vectors.
878  //**********************************************************************************************
879 
880  //**Compile time checks*************************************************************************
891  //**********************************************************************************************
892 };
893 //*************************************************************************************************
894 
895 
896 
897 
898 //=================================================================================================
899 //
900 // GLOBAL BINARY ARITHMETIC OPERATORS
901 //
902 //=================================================================================================
903 
904 //*************************************************************************************************
917 template< typename MT // Type of the left-hand side sparse matrix
918  , typename VT // Type of the right-hand side sparse vector
919  , DisableIf_t< IsSymmetric_v<MT> ||
920  ( IsIdentity_v<MT> &&
921  IsSame_v< ElementType_t<MT>, ElementType_t<VT> > ) ||
922  ( IsZero_v<MT> || IsZero_v<VT> ) >* = nullptr >
923 inline const SMatSVecMultExpr<MT,VT>
924  smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
925 {
927 
928  BLAZE_INTERNAL_ASSERT( (~mat).columns() == (~vec).size(), "Invalid matrix and vector sizes" );
929 
930  return SMatSVecMultExpr<MT,VT>( ~mat, ~vec );
931 }
933 //*************************************************************************************************
934 
935 
936 //*************************************************************************************************
950 template< typename MT // Type of the left-hand side sparse matrix
951  , typename VT // Type of the right-hand side sparse vector
952  , EnableIf_t< IsSymmetric_v<MT> &&
953  !( IsIdentity_v<MT> &&
954  IsSame_v< ElementType_t<MT>, ElementType_t<VT> > ) &&
955  !( IsZero_v<MT> || IsZero_v<VT> ) >* = nullptr >
956 inline decltype(auto)
957  smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
958 {
960 
961  BLAZE_INTERNAL_ASSERT( (~mat).columns() == (~vec).size(), "Invalid matrix and vector sizes" );
962 
963  return trans( ~mat ) * (~vec);
964 }
966 //*************************************************************************************************
967 
968 
969 //*************************************************************************************************
983 template< typename MT // Type of the left-hand side sparse matrix
984  , typename VT // Type of the right-hand side sparse vector
985  , EnableIf_t< ( IsIdentity_v<MT> &&
986  IsSame_v< ElementType_t<MT>, ElementType_t<VT> > ) &&
987  !IsZero_v<VT> >* = nullptr >
988 inline const VT&
989  smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
990 {
992 
993  UNUSED_PARAMETER( mat );
994 
995  BLAZE_INTERNAL_ASSERT( (~mat).columns() == (~vec).size(), "Invalid matrix and vector sizes" );
996 
997  return (~vec);
998 }
1000 //*************************************************************************************************
1001 
1002 
1003 //*************************************************************************************************
1016 template< typename MT // Type of the left-hand side sparse matrix
1017  , typename VT // Type of the right-hand side sparse vector
1018  , EnableIf_t< IsZero_v<MT> || IsZero_v<VT> >* = nullptr >
1019 inline decltype(auto)
1020  smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
1021 {
1023 
1024  UNUSED_PARAMETER( vec );
1025 
1026  BLAZE_INTERNAL_ASSERT( (~mat).columns() == (~vec).size(), "Invalid matrix and vector sizes" );
1027 
1028  using ReturnType = const MultTrait_t< ResultType_t<MT>, ResultType_t<VT> >;
1029 
1032 
1033  return ReturnType( (~mat).rows() );
1034 }
1036 //*************************************************************************************************
1037 
1038 
1039 //*************************************************************************************************
1070 template< typename MT // Type of the left-hand side sparse matrix
1071  , typename VT > // Type of the right-hand side sparse vector
1072 inline decltype(auto)
1073  operator*( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
1074 {
1076 
1078 
1079  if( (~mat).columns() != (~vec).size() ) {
1080  BLAZE_THROW_INVALID_ARGUMENT( "Matrix and vector sizes do not match" );
1081  }
1082 
1083  return smatsvecmult( ~mat, ~vec );
1084 }
1085 //*************************************************************************************************
1086 
1087 } // namespace blaze
1088 
1089 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Header file for the blaze::checked and blaze::unchecked instances.
LeftOperand mat_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatSVecMultExpr.h:277
Header file for the UNUSED_PARAMETER function template.
Header file for basic type definitions.
Header file for the SparseVector base class.
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
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatSVecMultExpr.h:156
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:61
Header file for the serial shim.
size_t nonZeros() const
Returns an estimation for the number of non-zero elements in the sparse vector.
Definition: SMatSVecMultExpr.h:216
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: SMatSVecMultExpr.h:193
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
Constraint on the data type.
Header file for the IsIdentity type trait.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSVecMultExpr.h:260
Header file for the Computation base class.
Header file for the reset shim.
CompositeType_t< MT > MCT
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:104
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
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 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
Constraint on the transpose flag of vector types.
Constraint on the data type.
ResultType_t< VT > VRT
Result type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:103
Header file for the DisableIf class template.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatSVecMultExpr.h:136
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
If_t< IsExpression_v< MT >, const MT, const MT &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:142
Expression object for sparse matrix-sparse vector multiplications.The SMatSVecMultExpr class represen...
Definition: Forward.h:128
Header file for the If class template.
#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
#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
CompositeType_t< VT > VCT
Composite type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:105
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatSVecMultExpr.h:135
MultTrait_t< MRT, VRT > ResultType
Result type for expression template evaluations.
Definition: SMatSVecMultExpr.h:133
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_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
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatSVecMultExpr.h:270
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SMatSVecMultExpr.h:180
#define BLAZE_CONSTRAINT_MUST_NOT_BE_MATMATMULTEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a matrix/matrix multiplication expressio...
Definition: MatMatMultExpr.h:83
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_MATVECMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid matrix/vector ...
Definition: MatVecMultExpr.h:104
Header file for the exception macros of the math module.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSVecMultExpr.h:139
ResultType_t< MT > MRT
Result type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:102
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the EnableIf class template.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSVecMultExpr.h:226
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
If_t< IsExpression_v< VT >, const VT, const VT &> RightOperand
Composite type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:145
RightOperand vec_
Right-hand side sparse vector of the multiplication expression.
Definition: SMatSVecMultExpr.h:278
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
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
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
If_t< evaluateMatrix, const MRT, MCT > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatSVecMultExpr.h:148
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: SMatSVecMultExpr.h:206
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
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSVecMultExpr.h:134
Header file for the isDefault shim.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraint on the data type.
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse vector operand.
Definition: SMatSVecMultExpr.h:236
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSVecMultExpr.h:248
#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
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
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
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:138
Constraint on the data type.
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
static constexpr bool evaluateMatrix
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:110
If_t< evaluateVector, const VRT, VCT > RT
Type for the assignment of the right-hand side sparse vector operand.
Definition: SMatSVecMultExpr.h:151
SMatSVecMultExpr(const MT &mat, const VT &vec) noexcept
Constructor for the SMatSVecMultExpr class.
Definition: SMatSVecMultExpr.h:166
Header file for the MatVecMultExpr base class.
Constraint on the data type.
#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
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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
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
static constexpr bool evaluateVector
Compilation switch for the composite type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:115
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
Header file for the IsExpression type trait class.
Header file for the function trace functionality.