Blaze  3.6
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/MaybeUnused.h>
75 #include <blaze/util/mpl/If.h>
76 #include <blaze/util/Types.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 =
155  ( !evaluateVector && VT::smpAssignable && !evaluateMatrix && MT::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  MAYBE_UNUSED( 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  MAYBE_UNUSED( 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 
1037  BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE( ReturnType );
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
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 template for the If class template.The If_t alias template provides a convenient shor...
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:595
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 MAYBE_UNUSED function template.
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 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:145
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.
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
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:197
#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
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
#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.
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,...
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 all forward declarations for expression class templates.
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
#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:146
#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:635
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,...
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.