TSVecTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSVECTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSVECTSMATMULTEXPR_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 TSVECTSMATMULTEXPR
84 //
85 //=================================================================================================
86 
87 //*************************************************************************************************
94 template< typename VT // Type of the left-hand side sparse vector
95  , typename MT > // Type of the right-hand side sparse matrix
96 class TSVecTSMatMultExpr
97  : public TVecMatMultExpr< SparseVector< TSVecTSMatMultExpr<VT,MT>, true > >
98  , private Computation
99 {
100  private:
101  //**Type definitions****************************************************************************
106  //**********************************************************************************************
107 
108  //**********************************************************************************************
110  static constexpr bool evaluateVector = IsComputation_v<VT>;
111  //**********************************************************************************************
112 
113  //**********************************************************************************************
115  static constexpr bool evaluateMatrix = RequiresEvaluation_v<MT>;
116  //**********************************************************************************************
117 
118  //**********************************************************************************************
120 
124  template< typename T1 >
125  static constexpr bool UseSMPAssign_v = ( evaluateVector || evaluateMatrix );
127  //**********************************************************************************************
128 
129  public:
130  //**Type definitions****************************************************************************
136  using ReturnType = const ElementType;
137  using CompositeType = const ResultType;
138 
140  using LeftOperand = If_t< IsExpression_v<VT>, const VT, const VT& >;
141 
143  using RightOperand = If_t< IsExpression_v<MT>, const MT, const MT& >;
144 
147 
150  //**********************************************************************************************
151 
152  //**Compilation flags***************************************************************************
154  static constexpr bool smpAssignable =
156  //**********************************************************************************************
157 
158  //**Constructor*********************************************************************************
164  explicit inline TSVecTSMatMultExpr( const VT& vec, const MT& mat ) noexcept
165  : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
166  , mat_( mat ) // Right-hand side sparse matrix of the multiplication expression
167  {
168  BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
169  }
170  //**********************************************************************************************
171 
172  //**Subscript operator**************************************************************************
178  inline ReturnType operator[]( size_t index ) const {
179  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
180  return vec_ * column( mat_, index, unchecked );
181  }
182  //**********************************************************************************************
183 
184  //**At function*********************************************************************************
191  inline ReturnType at( size_t index ) const {
192  if( index >= mat_.columns() ) {
193  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
194  }
195  return (*this)[index];
196  }
197  //**********************************************************************************************
198 
199  //**Size function*******************************************************************************
204  inline size_t size() const noexcept {
205  return mat_.columns();
206  }
207  //**********************************************************************************************
208 
209  //**NonZeros function***************************************************************************
214  inline size_t nonZeros() const {
215  return mat_.columns();
216  }
217  //**********************************************************************************************
218 
219  //**Left operand access*************************************************************************
224  inline LeftOperand leftOperand() const noexcept {
225  return vec_;
226  }
227  //**********************************************************************************************
228 
229  //**Right operand access************************************************************************
234  inline RightOperand rightOperand() const noexcept {
235  return mat_;
236  }
237  //**********************************************************************************************
238 
239  //**********************************************************************************************
245  template< typename T >
246  inline bool canAlias( const T* alias ) const noexcept {
247  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
248  }
249  //**********************************************************************************************
250 
251  //**********************************************************************************************
257  template< typename T >
258  inline bool isAliased( const T* alias ) const noexcept {
259  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
260  }
261  //**********************************************************************************************
262 
263  //**********************************************************************************************
268  inline bool canSMPAssign() const noexcept {
269  return ( size() > SMP_TSVECSMATMULT_THRESHOLD );
270  }
271  //**********************************************************************************************
272 
273  private:
274  //**Member variables****************************************************************************
277  //**********************************************************************************************
278 
279  //**Assignment to dense vectors*****************************************************************
292  template< typename VT1 > // Type of the target dense vector
293  friend inline void assign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
294  {
296 
297  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
298 
299  // Resetting the left-hand side target dense vector
300  reset( ~lhs );
301 
302  // Evaluation of the left-hand side sparse vector operand
303  LT x( serial( rhs.vec_ ) );
304  if( x.nonZeros() == 0UL ) return;
305 
306  // Evaluation of the right-hand side sparse matrix operand
307  RT A( serial( rhs.mat_ ) );
308 
309  // Checking the evaluated operands
310  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
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( A.columns() == (~lhs).size() , "Invalid vector size" );
314 
315  // Performing the sparse vector-sparse matrix multiplication
316  TSVecTSMatMultExpr::selectAssignKernel( ~lhs, x, A );
317  }
319  //**********************************************************************************************
320 
321  //**Default assignment to dense vectors*********************************************************
335  template< typename VT1 // Type of the left-hand side target vector
336  , typename VT2 // Type of the left-hand side vector operand
337  , typename MT1 > // Type of the right-hand side matrix operand
338  static inline void selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
339  {
340  const auto vend( x.end() );
341 
342  for( size_t j=0UL; j<A.columns(); ++j )
343  {
344  const auto mend ( A.end(j) );
345  auto melem( A.begin(j) );
346 
347  if( melem == mend ) continue;
348 
349  auto velem( x.begin() );
350 
351  while( true ) {
352  if( velem->index() < melem->index() ) {
353  ++velem;
354  if( velem == vend ) break;
355  }
356  else if( melem->index() < velem->index() ) {
357  ++melem;
358  if( melem == mend ) break;
359  }
360  else {
361  y[j] = velem->value() * melem->value();
362  ++velem;
363  ++melem;
364  break;
365  }
366  }
367 
368  if( velem != vend && melem != mend )
369  {
370  while( true ) {
371  if( velem->index() < melem->index() ) {
372  ++velem;
373  if( velem == vend ) break;
374  }
375  else if( melem->index() < velem->index() ) {
376  ++melem;
377  if( melem == mend ) break;
378  }
379  else {
380  y[j] += velem->value() * melem->value();
381  ++velem;
382  if( velem == vend ) break;
383  ++melem;
384  if( melem == mend ) break;
385  }
386  }
387  }
388  }
389  }
391  //**********************************************************************************************
392 
393  //**Assignment to sparse vectors****************************************************************
406  template< typename VT1 > // Type of the target sparse vector
407  friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
408  {
410 
411  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
412 
413  // Evaluation of the left-hand side sparse vector operand
414  LT x( serial( rhs.vec_ ) );
415  if( x.nonZeros() == 0UL ) return;
416 
417  // Evaluation of the right-hand side sparse matrix operand
418  RT A( serial( rhs.mat_ ) );
419 
420  // Checking the evaluated operands
421  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
422  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
423  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
424  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
425 
426  // Performing the sparse vector-sparse matrix multiplication
427  ElementType accu;
428  const auto vend( x.end() );
429 
430  for( size_t j=0UL; j<A.columns(); ++j )
431  {
432  const auto mend ( A.end(j) );
433  auto melem( A.begin(j) );
434 
435  if( melem == mend ) continue;
436 
437  auto velem( x.begin() );
438 
439  reset( accu );
440 
441  while( true ) {
442  if( velem->index() < melem->index() ) {
443  ++velem;
444  if( velem == vend ) break;
445  }
446  else if( melem->index() < velem->index() ) {
447  ++melem;
448  if( melem == mend ) break;
449  }
450  else {
451  accu = velem->value() * melem->value();
452  ++velem;
453  ++melem;
454  break;
455  }
456  }
457 
458  if( velem != vend && melem != mend )
459  {
460  while( true ) {
461  if( velem->index() < melem->index() ) {
462  ++velem;
463  if( velem == vend ) break;
464  }
465  else if( melem->index() < velem->index() ) {
466  ++melem;
467  if( melem == mend ) break;
468  }
469  else {
470  accu += velem->value() * melem->value();
471  ++velem;
472  if( velem == vend ) break;
473  ++melem;
474  if( melem == mend ) break;
475  }
476  }
477  }
478 
479  if( !isDefault( accu ) )
480  (~lhs).insert( j, accu );
481  }
482  }
484  //**********************************************************************************************
485 
486  //**Addition assignment to dense vectors********************************************************
499  template< typename VT1 > // Type of the target dense vector
500  friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
501  {
503 
504  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
505 
506  // Evaluation of the left-hand side sparse vector operand
507  LT x( serial( rhs.vec_ ) );
508  if( x.nonZeros() == 0UL ) return;
509 
510  // Evaluation of the right-hand side sparse matrix operand
511  RT A( serial( rhs.mat_ ) );
512 
513  // Checking the evaluated operands
514  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
515  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
516  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
517  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
518 
519  // Performing the sparse matrix-sparse vector multiplication
520  TSVecTSMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
521  }
523  //**********************************************************************************************
524 
525  //**Default addition assignment to dense vectors************************************************
539  template< typename VT1 // Type of the left-hand side target vector
540  , typename VT2 // Type of the left-hand side vector operand
541  , typename MT1 > // Type of the right-hand side matrix operand
542  static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
543  {
544  const auto vend( x.end() );
545 
546  for( size_t j=0UL; j<A.columns(); ++j )
547  {
548  const auto mend ( A.end(j) );
549  auto melem( A.begin(j) );
550 
551  if( melem == mend ) continue;
552 
553  auto velem( x.begin() );
554 
555  while( true ) {
556  if( velem->index() < melem->index() ) {
557  ++velem;
558  if( velem == vend ) break;
559  }
560  else if( melem->index() < velem->index() ) {
561  ++melem;
562  if( melem == mend ) break;
563  }
564  else {
565  y[j] += velem->value() * melem->value();
566  ++velem;
567  if( velem == vend ) break;
568  ++melem;
569  if( melem == mend ) break;
570  }
571  }
572  }
573  }
575  //**********************************************************************************************
576 
577  //**Addition assignment to sparse vectors*******************************************************
578  // No special implementation for the addition assignment to sparse vectors.
579  //**********************************************************************************************
580 
581  //**Subtraction assignment to dense vectors*****************************************************
594  template< typename VT1 > // Type of the target dense vector
595  friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
596  {
598 
599  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
600 
601  // Evaluation of the left-hand side sparse vector operand
602  LT x( serial( rhs.vec_ ) );
603  if( x.nonZeros() == 0UL ) return;
604 
605  // Evaluation of the right-hand side sparse matrix operand
606  RT A( serial( rhs.mat_ ) );
607 
608  // Checking the evaluated operands
609  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
610  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
611  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
612  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
613 
614  // Performing the sparse matrix-sparse vector multiplication
615  TSVecTSMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
616  }
618  //**********************************************************************************************
619 
620  //**Default subtraction assignment to dense vectors*********************************************
634  template< typename VT1 // Type of the left-hand side target vector
635  , typename VT2 // Type of the left-hand side vector operand
636  , typename MT1 > // Type of the right-hand side matrix operand
637  static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
638  {
639  const auto vend( x.end() );
640 
641  for( size_t j=0UL; j<A.columns(); ++j )
642  {
643  const auto mend ( A.end(j) );
644  auto melem( A.begin(j) );
645 
646  if( melem == mend ) continue;
647 
648  auto velem( x.begin() );
649 
650  while( true ) {
651  if( velem->index() < melem->index() ) {
652  ++velem;
653  if( velem == vend ) break;
654  }
655  else if( melem->index() < velem->index() ) {
656  ++melem;
657  if( melem == mend ) break;
658  }
659  else {
660  y[j] -= velem->value() * melem->value();
661  ++velem;
662  if( velem == vend ) break;
663  ++melem;
664  if( melem == mend ) break;
665  }
666  }
667  }
668  }
670  //**********************************************************************************************
671 
672  //**Subtraction assignment to sparse vectors****************************************************
673  // No special implementation for the subtraction assignment to sparse vectors.
674  //**********************************************************************************************
675 
676  //**Multiplication assignment to dense vectors**************************************************
689  template< typename VT1 > // Type of the target dense vector
690  friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
691  {
693 
697 
698  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
699 
700  const ResultType tmp( serial( rhs ) );
701  multAssign( ~lhs, tmp );
702  }
704  //**********************************************************************************************
705 
706  //**Multiplication assignment to sparse vectors*************************************************
707  // No special implementation for the multiplication assignment to sparse vectors.
708  //**********************************************************************************************
709 
710  //**SMP assignment to dense vectors*************************************************************
725  template< typename VT1 > // Type of the target dense vector
726  friend inline auto smpAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
727  -> EnableIf_t< UseSMPAssign_v<VT1> >
728  {
730 
731  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
732 
733  // Resetting the left-hand side target dense vector
734  reset( ~lhs );
735 
736  // Evaluation of the left-hand side sparse vector operand
737  LT x( rhs.vec_ );
738  if( x.nonZeros() == 0UL ) return;
739 
740  // Evaluation of the right-hand side sparse matrix operand
741  RT A( rhs.mat_ );
742 
743  // Checking the evaluated operands
744  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
745  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
746  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
747  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
748 
749  // Performing the sparse vector-sparse matrix multiplication
750  smpAssign( ~lhs, x * A );
751  }
753  //**********************************************************************************************
754 
755  //**SMP assignment to sparse vectors************************************************************
756  // No special implementation for the SMP assignment to sparse vectors.
757  //**********************************************************************************************
758 
759  //**SMP addition assignment to dense vectors****************************************************
774  template< typename VT1 > // Type of the target dense vector
775  friend inline auto smpAddAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
776  -> EnableIf_t< UseSMPAssign_v<VT1> >
777  {
779 
780  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
781 
782  // Evaluation of the left-hand side sparse vector operand
783  LT x( rhs.vec_ );
784  if( x.nonZeros() == 0UL ) return;
785 
786  // Evaluation of the right-hand side sparse matrix operand
787  RT A( rhs.mat_ );
788 
789  // Checking the evaluated operands
790  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
791  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
792  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
793  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
794 
795  // Performing the sparse matrix-sparse vector multiplication
796  smpAddAssign( ~lhs, x * A );
797  }
799  //**********************************************************************************************
800 
801  //**SMP addition assignment to sparse vectors***************************************************
802  // No special implementation for the SMP addition assignment to sparse vectors.
803  //**********************************************************************************************
804 
805  //**SMP subtraction assignment to dense vectors*************************************************
820  template< typename VT1 > // Type of the target dense vector
821  friend inline auto smpSubAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
822  -> EnableIf_t< UseSMPAssign_v<VT1> >
823  {
825 
826  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
827 
828  // Evaluation of the left-hand side sparse vector operand
829  LT x( rhs.vec_ );
830  if( x.nonZeros() == 0UL ) return;
831 
832  // Evaluation of the right-hand side sparse matrix operand
833  RT A( rhs.mat_ );
834 
835  // Checking the evaluated operands
836  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
837  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
838  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
839  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
840 
841  // Performing the sparse matrix-sparse vector multiplication
842  smpSubAssign( ~lhs, x * A );
843  }
845  //**********************************************************************************************
846 
847  //**SMP subtraction assignment to sparse vectors************************************************
848  // No special implementation for the SMP subtraction assignment to sparse vectors.
849  //**********************************************************************************************
850 
851  //**SMP multiplication assignment to dense vectors**********************************************
866  template< typename VT1 > // Type of the target dense vector
867  friend inline auto smpMultAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
868  -> EnableIf_t< UseSMPAssign_v<VT1> >
869  {
871 
875 
876  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
877 
878  const ResultType tmp( rhs );
879  smpMultAssign( ~lhs, tmp );
880  }
882  //**********************************************************************************************
883 
884  //**SMP multiplication assignment to sparse vectors*********************************************
885  // No special implementation for the SMP multiplication assignment to sparse vectors.
886  //**********************************************************************************************
887 
888  //**Compile time checks*************************************************************************
899  //**********************************************************************************************
900 };
901 //*************************************************************************************************
902 
903 
904 
905 
906 //=================================================================================================
907 //
908 // GLOBAL BINARY ARITHMETIC OPERATORS
909 //
910 //=================================================================================================
911 
912 //*************************************************************************************************
925 template< typename VT // Type of the left-hand side sparse vector
926  , typename MT // Type of the right-hand side sparse matrix
927  , DisableIf_t< IsSymmetric_v<MT> || IsZero_v<MT> || IsZero_v<VT> >* = nullptr >
928 inline const TSVecTSMatMultExpr<VT,MT>
929  tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
930 {
932 
933  BLAZE_INTERNAL_ASSERT( (~vec).size() == (~mat).rows(), "Invalid vector and matrix sizes" );
934 
935  return TSVecTSMatMultExpr<VT,MT>( ~vec, ~mat );
936 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
955 template< typename VT // Type of the left-hand side sparse vector
956  , typename MT // Type of the right-hand side sparse matrix
957  , EnableIf_t< IsSymmetric_v<MT> &&
958  !( IsIdentity_v<MT> &&
959  IsSame_v< ElementType_t<VT>, ElementType_t<MT> > ) &&
960  !( IsZero_v<MT> || IsZero_v<VT> ) >* = nullptr >
961 inline decltype(auto)
962  tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
963 {
965 
966  BLAZE_INTERNAL_ASSERT( (~vec).size() == (~mat).rows(), "Invalid vector and matrix sizes" );
967 
968  return (~vec) * trans( ~mat );
969 }
971 //*************************************************************************************************
972 
973 
974 //*************************************************************************************************
988 template< typename VT // Type of the left-hand side sparse vector
989  , typename MT // Type of the right-hand side sparse matrix
990  , EnableIf_t< ( IsIdentity_v<MT> &&
991  IsSame_v< ElementType_t<VT>, ElementType_t<MT> > ) &&
992  !IsZero_v<VT> >* = nullptr >
993 inline const VT&
994  tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
995 {
997 
998  UNUSED_PARAMETER( mat );
999 
1000  BLAZE_INTERNAL_ASSERT( (~vec).size() == (~mat).rows(), "Invalid vector and matrix sizes" );
1001 
1002  return (~vec);
1003 }
1005 //*************************************************************************************************
1006 
1007 
1008 //*************************************************************************************************
1022 template< typename VT // Type of the left-hand side sparse vector
1023  , typename MT // Type of the right-hand side sparse matrix
1024  , EnableIf_t< IsZero_v<MT> || IsZero_v<VT> >* = nullptr >
1025 inline decltype(auto)
1026  tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
1027 {
1029 
1030  UNUSED_PARAMETER( vec );
1031 
1032  BLAZE_INTERNAL_ASSERT( (~vec).size() == (~mat).rows(), "Invalid vector and matrix sizes" );
1033 
1034  using ReturnType = const MultTrait_t< ResultType_t<VT>, ResultType_t<MT> >;
1035 
1038 
1039  return ReturnType( (~mat).columns() );
1040 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1076 template< typename VT // Type of the left-hand side sparse vector
1077  , typename MT > // Type of the right-hand side sparse matrix
1078 inline decltype(auto)
1079  operator*( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
1080 {
1082 
1084 
1085  if( (~vec).size() != (~mat).rows() ) {
1086  BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
1087  }
1088 
1089  return tsvectsmatmult( ~vec, ~mat );
1090 }
1091 //*************************************************************************************************
1092 
1093 } // namespace blaze
1094 
1095 #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
size_t nonZeros() const
Returns an estimation for the number of non-zero elements in the sparse vector.
Definition: TSVecTSMatMultExpr.h:214
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Header file for the blaze::checked and blaze::unchecked instances.
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:136
Header file for the UNUSED_PARAMETER function template.
static constexpr bool evaluateMatrix
Compilation switch for the composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:115
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
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.
If_t< IsExpression_v< VT >, const VT, const VT &> LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:140
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:268
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
ResultType_t< MT > MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:103
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:134
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.
Header file for the Computation base class.
Header file for the reset shim.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:234
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
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSVecTSMatMultExpr.h:258
Constraint on the data type.
CompositeType_t< VT > VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:104
RightOperand mat_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:276
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
#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
Expression object for sparse vector-sparse matrix multiplications.The TSVecTSMatMultExpr class repres...
Definition: Forward.h:185
#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
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:275
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
#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
If_t< IsExpression_v< MT >, const MT, const MT &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:143
Header file for the exception macros of the math module.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:246
ResultType_t< VT > VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.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.
If_t< evaluateVector, const VRT, VCT > LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:146
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
#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
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
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSVecTSMatMultExpr.h:154
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecTSMatMultExpr.h:137
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
Header file for the IsZero type trait.
Constraint on the data type.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:224
#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 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
MultTrait_t< VRT, MRT > ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:133
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
Header file for the TVecMatMultExpr base class.
Constraint on the data type.
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:135
Constraints on the storage order of matrix types.
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
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:178
static constexpr bool evaluateVector
Compilation switch for the composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:110
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_TVECMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/matrix ...
Definition: TVecMatMultExpr.h:104
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
If_t< evaluateMatrix, const MRT, MCT > RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:149
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
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:204
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:138
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
TSVecTSMatMultExpr(const VT &vec, const MT &mat) noexcept
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:164
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.
CompositeType_t< MT > MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:105
#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
#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
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: TSVecTSMatMultExpr.h:191
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.