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>
50 #include <blaze/math/Exception.h>
56 #include <blaze/math/shims/Reset.h>
67 #include <blaze/util/Assert.h>
69 #include <blaze/util/DisableIf.h>
70 #include <blaze/util/EnableIf.h>
72 #include <blaze/util/mpl/If.h>
73 #include <blaze/util/mpl/Or.h>
74 #include <blaze/util/Types.h>
76 
77 
78 namespace blaze {
79 
80 //=================================================================================================
81 //
82 // CLASS TSVECTSMATMULTEXPR
83 //
84 //=================================================================================================
85 
86 //*************************************************************************************************
93 template< typename VT // Type of the left-hand side sparse vector
94  , typename MT > // Type of the right-hand side sparse matrix
95 class TSVecTSMatMultExpr : public SparseVector< TSVecTSMatMultExpr<VT,MT>, true >
96  , private TVecMatMultExpr
97  , private Computation
98 {
99  private:
100  //**Type definitions****************************************************************************
105  //**********************************************************************************************
106 
107  //**********************************************************************************************
109  enum : bool { evaluateVector = IsComputation<VT>::value };
110  //**********************************************************************************************
111 
112  //**********************************************************************************************
114  enum : bool { evaluateMatrix = RequiresEvaluation<MT>::value };
115  //**********************************************************************************************
116 
117  //**********************************************************************************************
119 
123  template< typename T1 >
124  struct UseSMPAssign {
125  enum : bool { value = ( evaluateVector || evaluateMatrix ) };
126  };
128  //**********************************************************************************************
129 
130  public:
131  //**Type definitions****************************************************************************
136  typedef const ElementType ReturnType;
137  typedef const ResultType CompositeType;
138 
140  typedef If_< IsExpression<VT>, const VT, const VT& > LeftOperand;
141 
143  typedef If_< IsExpression<MT>, const MT, const MT& > RightOperand;
144 
147 
150  //**********************************************************************************************
151 
152  //**Compilation flags***************************************************************************
154  enum : bool { smpAssignable = !evaluateVector && VT::smpAssignable &&
155  !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 );
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****************************************************************************
275  LeftOperand vec_;
276  RightOperand mat_;
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  typedef ConstIterator_< RemoveReference_<VT2> > VectorIterator;
341  typedef ConstIterator_< RemoveReference_<MT1> > MatrixIterator;
342 
343  const VectorIterator vend( x.end() );
344 
345  for( size_t j=0UL; j<A.columns(); ++j )
346  {
347  const MatrixIterator mend ( A.end(j) );
348  MatrixIterator melem( A.begin(j) );
349 
350  if( melem == mend ) continue;
351 
352  VectorIterator velem( x.begin() );
353 
354  while( true ) {
355  if( velem->index() < melem->index() ) {
356  ++velem;
357  if( velem == vend ) break;
358  }
359  else if( melem->index() < velem->index() ) {
360  ++melem;
361  if( melem == mend ) break;
362  }
363  else {
364  y[j] = velem->value() * melem->value();
365  ++velem;
366  ++melem;
367  break;
368  }
369  }
370 
371  if( velem != vend && melem != mend )
372  {
373  while( true ) {
374  if( velem->index() < melem->index() ) {
375  ++velem;
376  if( velem == vend ) break;
377  }
378  else if( melem->index() < velem->index() ) {
379  ++melem;
380  if( melem == mend ) break;
381  }
382  else {
383  y[j] += velem->value() * melem->value();
384  ++velem;
385  if( velem == vend ) break;
386  ++melem;
387  if( melem == mend ) break;
388  }
389  }
390  }
391  }
392  }
394  //**********************************************************************************************
395 
396  //**Assignment to sparse vectors****************************************************************
409  template< typename VT1 > // Type of the target sparse vector
410  friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
411  {
413 
414  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
415 
416  typedef ConstIterator_< RemoveReference_<LT> > VectorIterator;
417  typedef ConstIterator_< RemoveReference_<RT> > MatrixIterator;
418 
419  // Evaluation of the left-hand side sparse vector operand
420  LT x( serial( rhs.vec_ ) );
421  if( x.nonZeros() == 0UL ) return;
422 
423  // Evaluation of the right-hand side sparse matrix operand
424  RT A( serial( rhs.mat_ ) );
425 
426  // Checking the evaluated operands
427  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
428  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
429  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
430  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
431 
432  // Performing the sparse vector-sparse matrix multiplication
433  ElementType accu;
434  const VectorIterator vend( x.end() );
435 
436  for( size_t j=0UL; j<A.columns(); ++j )
437  {
438  const MatrixIterator mend ( A.end(j) );
439  MatrixIterator melem( A.begin(j) );
440 
441  if( melem == mend ) continue;
442 
443  VectorIterator velem( x.begin() );
444 
445  reset( accu );
446 
447  while( true ) {
448  if( velem->index() < melem->index() ) {
449  ++velem;
450  if( velem == vend ) break;
451  }
452  else if( melem->index() < velem->index() ) {
453  ++melem;
454  if( melem == mend ) break;
455  }
456  else {
457  accu = velem->value() * melem->value();
458  ++velem;
459  ++melem;
460  break;
461  }
462  }
463 
464  if( velem != vend && melem != mend )
465  {
466  while( true ) {
467  if( velem->index() < melem->index() ) {
468  ++velem;
469  if( velem == vend ) break;
470  }
471  else if( melem->index() < velem->index() ) {
472  ++melem;
473  if( melem == mend ) break;
474  }
475  else {
476  accu += velem->value() * melem->value();
477  ++velem;
478  if( velem == vend ) break;
479  ++melem;
480  if( melem == mend ) break;
481  }
482  }
483  }
484 
485  if( !isDefault( accu ) )
486  (~lhs).insert( j, accu );
487  }
488  }
490  //**********************************************************************************************
491 
492  //**Addition assignment to dense vectors********************************************************
505  template< typename VT1 > // Type of the target dense vector
506  friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
507  {
509 
510  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
511 
512  // Evaluation of the left-hand side sparse vector operand
513  LT x( serial( rhs.vec_ ) );
514  if( x.nonZeros() == 0UL ) return;
515 
516  // Evaluation of the right-hand side sparse matrix operand
517  RT A( serial( rhs.mat_ ) );
518 
519  // Checking the evaluated operands
520  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
521  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
522  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
523  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
524 
525  // Performing the sparse matrix-sparse vector multiplication
526  TSVecTSMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
527  }
529  //**********************************************************************************************
530 
531  //**Default addition assignment to dense vectors************************************************
545  template< typename VT1 // Type of the left-hand side target vector
546  , typename VT2 // Type of the left-hand side vector operand
547  , typename MT1 > // Type of the right-hand side matrix operand
548  static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
549  {
550  typedef ConstIterator_< RemoveReference_<VT2> > VectorIterator;
551  typedef ConstIterator_< RemoveReference_<MT1> > MatrixIterator;
552 
553  const VectorIterator vend( x.end() );
554 
555  for( size_t j=0UL; j<A.columns(); ++j )
556  {
557  const MatrixIterator mend ( A.end(j) );
558  MatrixIterator melem( A.begin(j) );
559 
560  if( melem == mend ) continue;
561 
562  VectorIterator velem( x.begin() );
563 
564  while( true ) {
565  if( velem->index() < melem->index() ) {
566  ++velem;
567  if( velem == vend ) break;
568  }
569  else if( melem->index() < velem->index() ) {
570  ++melem;
571  if( melem == mend ) break;
572  }
573  else {
574  y[j] += velem->value() * melem->value();
575  ++velem;
576  if( velem == vend ) break;
577  ++melem;
578  if( melem == mend ) break;
579  }
580  }
581  }
582  }
584  //**********************************************************************************************
585 
586  //**Addition assignment to sparse vectors*******************************************************
587  // No special implementation for the addition assignment to sparse vectors.
588  //**********************************************************************************************
589 
590  //**Subtraction assignment to dense vectors*****************************************************
603  template< typename VT1 > // Type of the target dense vector
604  friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
605  {
607 
608  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
609 
610  // Evaluation of the left-hand side sparse vector operand
611  LT x( serial( rhs.vec_ ) );
612  if( x.nonZeros() == 0UL ) return;
613 
614  // Evaluation of the right-hand side sparse matrix operand
615  RT A( serial( rhs.mat_ ) );
616 
617  // Checking the evaluated operands
618  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
619  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
620  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
621  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
622 
623  // Performing the sparse matrix-sparse vector multiplication
624  TSVecTSMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
625  }
627  //**********************************************************************************************
628 
629  //**Default subtraction assignment to dense vectors*********************************************
643  template< typename VT1 // Type of the left-hand side target vector
644  , typename VT2 // Type of the left-hand side vector operand
645  , typename MT1 > // Type of the right-hand side matrix operand
646  static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
647  {
648  typedef ConstIterator_< RemoveReference_<VT2> > VectorIterator;
649  typedef ConstIterator_< RemoveReference_<MT1> > MatrixIterator;
650 
651  const VectorIterator vend( x.end() );
652 
653  for( size_t j=0UL; j<A.columns(); ++j )
654  {
655  const MatrixIterator mend ( A.end(j) );
656  MatrixIterator melem( A.begin(j) );
657 
658  if( melem == mend ) continue;
659 
660  VectorIterator velem( x.begin() );
661 
662  while( true ) {
663  if( velem->index() < melem->index() ) {
664  ++velem;
665  if( velem == vend ) break;
666  }
667  else if( melem->index() < velem->index() ) {
668  ++melem;
669  if( melem == mend ) break;
670  }
671  else {
672  y[j] -= velem->value() * melem->value();
673  ++velem;
674  if( velem == vend ) break;
675  ++melem;
676  if( melem == mend ) break;
677  }
678  }
679  }
680  }
682  //**********************************************************************************************
683 
684  //**Subtraction assignment to sparse vectors****************************************************
685  // No special implementation for the subtraction assignment to sparse vectors.
686  //**********************************************************************************************
687 
688  //**Multiplication assignment to dense vectors**************************************************
701  template< typename VT1 > // Type of the target dense vector
702  friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
703  {
705 
708  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( CompositeType_<ResultType> );
709 
710  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
711 
712  const ResultType tmp( serial( rhs ) );
713  multAssign( ~lhs, tmp );
714  }
716  //**********************************************************************************************
717 
718  //**Multiplication assignment to sparse vectors*************************************************
719  // No special implementation for the multiplication assignment to sparse vectors.
720  //**********************************************************************************************
721 
722  //**SMP assignment to dense vectors*************************************************************
737  template< typename VT1 > // Type of the target dense vector
738  friend inline EnableIf_< UseSMPAssign<VT1> >
739  smpAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
740  {
742 
743  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
744 
745  // Resetting the left-hand side target dense vector
746  reset( ~lhs );
747 
748  // Evaluation of the left-hand side sparse vector operand
749  LT x( rhs.vec_ );
750  if( x.nonZeros() == 0UL ) return;
751 
752  // Evaluation of the right-hand side sparse matrix operand
753  RT A( rhs.mat_ );
754 
755  // Checking the evaluated operands
756  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
757  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
758  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
759  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
760 
761  // Performing the sparse vector-sparse matrix multiplication
762  smpAssign( ~lhs, x * A );
763  }
765  //**********************************************************************************************
766 
767  //**SMP assignment to sparse vectors************************************************************
768  // No special implementation for the SMP assignment to sparse vectors.
769  //**********************************************************************************************
770 
771  //**SMP addition assignment to dense vectors****************************************************
786  template< typename VT1 > // Type of the target dense vector
787  friend inline EnableIf_< UseSMPAssign<VT1> >
788  smpAddAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
789  {
791 
792  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
793 
794  // Evaluation of the left-hand side sparse vector operand
795  LT x( rhs.vec_ );
796  if( x.nonZeros() == 0UL ) return;
797 
798  // Evaluation of the right-hand side sparse matrix operand
799  RT A( rhs.mat_ );
800 
801  // Checking the evaluated operands
802  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
803  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
804  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
805  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
806 
807  // Performing the sparse matrix-sparse vector multiplication
808  smpAddAssign( ~lhs, x * A );
809  }
811  //**********************************************************************************************
812 
813  //**SMP addition assignment to sparse vectors***************************************************
814  // No special implementation for the SMP addition assignment to sparse vectors.
815  //**********************************************************************************************
816 
817  //**SMP subtraction assignment to dense vectors*************************************************
832  template< typename VT1 > // Type of the target dense vector
833  friend inline EnableIf_< UseSMPAssign<VT1> >
834  smpSubAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
835  {
837 
838  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
839 
840  // Evaluation of the left-hand side sparse vector operand
841  LT x( rhs.vec_ );
842  if( x.nonZeros() == 0UL ) return;
843 
844  // Evaluation of the right-hand side sparse matrix operand
845  RT A( rhs.mat_ );
846 
847  // Checking the evaluated operands
848  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
849  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
850  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
851  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
852 
853  // Performing the sparse matrix-sparse vector multiplication
854  smpSubAssign( ~lhs, x * A );
855  }
857  //**********************************************************************************************
858 
859  //**SMP subtraction assignment to sparse vectors************************************************
860  // No special implementation for the SMP subtraction assignment to sparse vectors.
861  //**********************************************************************************************
862 
863  //**SMP multiplication assignment to dense vectors**********************************************
878  template< typename VT1 > // Type of the target dense vector
879  friend inline EnableIf_< UseSMPAssign<VT1> >
880  smpMultAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
881  {
883 
886  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( CompositeType_<ResultType> );
887 
888  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
889 
890  const ResultType tmp( rhs );
891  smpMultAssign( ~lhs, tmp );
892  }
894  //**********************************************************************************************
895 
896  //**SMP multiplication assignment to sparse vectors*********************************************
897  // No special implementation for the SMP multiplication assignment to sparse vectors.
898  //**********************************************************************************************
899 
900  //**Compile time checks*************************************************************************
909  //**********************************************************************************************
910 };
911 //*************************************************************************************************
912 
913 
914 
915 
916 //=================================================================================================
917 //
918 // GLOBAL BINARY ARITHMETIC OPERATORS
919 //
920 //=================================================================================================
921 
922 //*************************************************************************************************
953 template< typename T1 // Type of the left-hand side sparse vector
954  , typename T2 > // Type of the right-hand side sparse matrix
955 inline const DisableIf_< Or< IsSymmetric<T2>, IsMatMatMultExpr<T2> >, TSVecTSMatMultExpr<T1,T2> >
957 {
959 
960  if( (~vec).size() != (~mat).rows() ) {
961  BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
962  }
963 
964  return TSVecTSMatMultExpr<T1,T2>( ~vec, ~mat );
965 }
966 //*************************************************************************************************
967 
968 
969 
970 
971 //=================================================================================================
972 //
973 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
974 //
975 //=================================================================================================
976 
977 //*************************************************************************************************
992 template< typename T1 // Type of the left-hand side sparse vector
993  , typename T2 > // Type of the right-hand side sparse matrix
994 inline const EnableIf_< IsSymmetric<T2>, MultExprTrait_<T1,T2> >
995  operator*( const SparseVector<T1,true>& vec, const SparseMatrix<T2,true>& mat )
996 {
998 
1000 
1001  if( (~vec).size() != (~mat).rows() ) {
1002  BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
1003  }
1004 
1005  return (~vec) * trans( ~mat );
1006 }
1008 //*************************************************************************************************
1009 
1010 
1011 
1012 
1013 //=================================================================================================
1014 //
1015 // SIZE SPECIALIZATIONS
1016 //
1017 //=================================================================================================
1018 
1019 //*************************************************************************************************
1021 template< typename VT, typename MT >
1022 struct Size< TSVecTSMatMultExpr<VT,MT> > : public Columns<MT>
1023 {};
1025 //*************************************************************************************************
1026 
1027 
1028 
1029 
1030 //=================================================================================================
1031 //
1032 // EXPRESSION TRAIT SPECIALIZATIONS
1033 //
1034 //=================================================================================================
1035 
1036 //*************************************************************************************************
1038 template< typename VT, typename MT, bool AF >
1039 struct SubvectorExprTrait< TSVecTSMatMultExpr<VT,MT>, AF >
1040 {
1041  public:
1042  //**********************************************************************************************
1043  using Type = MultExprTrait_< SubvectorExprTrait_<const VT,AF>
1044  , SubmatrixExprTrait_<const MT,AF> >;
1045  //**********************************************************************************************
1046 };
1048 //*************************************************************************************************
1049 
1050 } // namespace blaze
1051 
1052 #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.
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:246
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7800
Header file for basic type definitions.
Header file for the SparseVector base class.
ResultType_< MT > MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:102
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the serial shim.
CompositeType_< VT > VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:103
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:136
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
MultTrait_< VRT, MRT > ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:133
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:245
Header file for the Computation base class.
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 the RequiresEvaluation type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
ResultType_< VT > VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:101
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:126
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Constraint on the data type.
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
Constraint on the data type.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
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.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:234
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
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
CompositeType_< MT > MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:104
Expression object for sparse vector-sparse matrix multiplications.The TSVecTSMatMultExpr class repres...
Definition: Forward.h:153
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Header file for the Or class template.
Header file for the IsMatMatMultExpr type trait class.
#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
Header file for the Columns type trait.
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:275
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
#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:89
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:60
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:268
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecTSMatMultExpr.h:137
Header file for the exception macros of the math module.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
TSVecTSMatMultExpr< VT, MT > This
Type of this TSVecTSMatMultExpr instance.
Definition: TSVecTSMatMultExpr.h:132
Header file for the EnableIf class template.
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:134
ElementType_< ResultType > ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:135
#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
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:224
If_< IsExpression< MT >, const MT, const MT & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:143
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:204
Header file for run time assertion macros.
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:160
Header file for the reset shim.
Constraint on the data type.
Header file for the isDefault shim.
Header file for the TVecMatMultExpr base class.
Constraints on the storage order of matrix types.
If_< IsExpression< VT >, const VT, const VT & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:140
IfTrue_< 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 RemoveReference type trait.
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
#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:110
IfTrue_< evaluateVector, const VRT, VCT > LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:146
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
Header file for the IsComputation type trait class.
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:110
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
#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
TSVecTSMatMultExpr(const VT &vec, const MT &mat) noexcept
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:164
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:403
Constraint on the data type.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSVecTSMatMultExpr.h:258
Header file for the Size type trait.
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: TSVecTSMatMultExpr.h:191
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
#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 operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:178
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.