All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 <stdexcept>
53 #include <blaze/math/shims/Reset.h>
61 #include <blaze/util/Assert.h>
63 #include <blaze/util/DisableIf.h>
65 #include <blaze/util/SelectType.h>
66 #include <blaze/util/Types.h>
68 
69 
70 namespace blaze {
71 
72 //=================================================================================================
73 //
74 // CLASS TSVECTSMATMULTEXPR
75 //
76 //=================================================================================================
77 
78 //*************************************************************************************************
85 template< typename VT // Type of the left-hand side sparse vector
86  , typename MT > // Type of the right-hand side sparse matrix
87 class TSVecTSMatMultExpr : public SparseVector< TSVecTSMatMultExpr<VT,MT>, true >
88  , private TVecMatMultExpr
89  , private Computation
90 {
91  private:
92  //**Type definitions****************************************************************************
93  typedef typename VT::ResultType VRT;
94  typedef typename MT::ResultType MRT;
95  typedef typename VT::CompositeType VCT;
96  typedef typename MT::CompositeType MCT;
97  //**********************************************************************************************
98 
99  //**********************************************************************************************
101  enum { evaluateVector = IsComputation<VT>::value };
102  //**********************************************************************************************
103 
104  //**********************************************************************************************
106  enum { evaluateMatrix = RequiresEvaluation<MT>::value };
107  //**********************************************************************************************
108 
109  //**********************************************************************************************
111 
115  template< typename T1 >
116  struct UseSMPAssign {
117  enum { value = ( evaluateVector || evaluateMatrix ) };
118  };
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
128  typedef const ElementType ReturnType;
129  typedef const ResultType CompositeType;
130 
132  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
133 
135  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type RightOperand;
136 
139 
142  //**********************************************************************************************
143 
144  //**Compilation flags***************************************************************************
146  enum { smpAssignable = !evaluateVector && VT::smpAssignable &&
147  !evaluateMatrix && MT::smpAssignable };
148  //**********************************************************************************************
149 
150  //**Constructor*********************************************************************************
156  explicit inline TSVecTSMatMultExpr( const VT& vec, const MT& mat )
157  : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
158  , mat_( mat ) // Right-hand side sparse matrix of the multiplication expression
159  {
160  BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
161  }
162  //**********************************************************************************************
163 
164  //**Subscript operator**************************************************************************
170  inline ReturnType operator[]( size_t index ) const {
171  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
172 
173  typedef typename RemoveReference<VCT>::Type::ConstIterator VectorIterator;
174  typedef typename RemoveReference<MCT>::Type::ConstIterator MatrixIterator;
175 
176  VCT x( vec_ ); // Evaluation of the left-hand side sparse vector operand
177  MCT A( mat_ ); // Evaluation of the right-hand side sparse matrix operand
178 
179  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size() , "Invalid vector size" );
180  BLAZE_INTERNAL_ASSERT( A.rows() == mat_.rows() , "Invalid number of rows" );
181  BLAZE_INTERNAL_ASSERT( A.columns() == mat_.columns(), "Invalid number of columns" );
182 
183  ElementType res = ElementType();
184 
185  VectorIterator velem( x.begin() );
186  const VectorIterator vend( x.end() );
187  if( velem == vend ) {
188  reset( res );
189  return res;
190  }
191 
192  MatrixIterator melem( A.begin(index) );
193  const MatrixIterator mend( A.end(index) );
194  if( melem == mend ) {
195  reset( res );
196  return res;
197  }
198 
199  while( true ) {
200  if( velem->index() < melem->index() ) {
201  ++velem;
202  if( velem == vend ) break;
203  }
204  else if( melem->index() < velem->index() ) {
205  ++melem;
206  if( melem == mend ) break;
207  }
208  else {
209  res = velem->value() * melem->value();
210  ++velem;
211  ++melem;
212  break;
213  }
214  }
215 
216  if( melem != mend && velem != vend )
217  {
218  while( true ) {
219  if( velem->index() < melem->index() ) {
220  ++velem;
221  if( velem == vend ) break;
222  }
223  else if( melem->index() < velem->index() ) {
224  ++melem;
225  if( melem == mend ) break;
226  }
227  else {
228  res += velem->value() * melem->value();
229  ++velem;
230  if( velem == vend ) break;
231  ++melem;
232  if( melem == mend ) break;
233  }
234  }
235  }
236 
237  return res;
238  }
239  //**********************************************************************************************
240 
241  //**Size function*******************************************************************************
246  inline size_t size() const {
247  return mat_.columns();
248  }
249  //**********************************************************************************************
250 
251  //**NonZeros function***************************************************************************
256  inline size_t nonZeros() const {
257  return mat_.columns();
258  }
259  //**********************************************************************************************
260 
261  //**Left operand access*************************************************************************
266  inline LeftOperand leftOperand() const {
267  return vec_;
268  }
269  //**********************************************************************************************
270 
271  //**Right operand access************************************************************************
276  inline RightOperand rightOperand() const {
277  return mat_;
278  }
279  //**********************************************************************************************
280 
281  //**********************************************************************************************
287  template< typename T >
288  inline bool canAlias( const T* alias ) const {
289  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
290  }
291  //**********************************************************************************************
292 
293  //**********************************************************************************************
299  template< typename T >
300  inline bool isAliased( const T* alias ) const {
301  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
302  }
303  //**********************************************************************************************
304 
305  //**********************************************************************************************
310  inline bool canSMPAssign() const {
311  return ( size() > SMP_TSVECSMATMULT_THRESHOLD );
312  }
313  //**********************************************************************************************
314 
315  private:
316  //**Member variables****************************************************************************
319  //**********************************************************************************************
320 
321  //**Assignment to dense vectors*****************************************************************
334  template< typename VT1 > // Type of the target dense vector
335  friend inline void assign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
336  {
338 
339  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
340 
341  // Resetting the left-hand side target dense vector
342  reset( ~lhs );
343 
344  // Evaluation of the left-hand side sparse vector operand
345  LT x( serial( rhs.vec_ ) );
346  if( x.nonZeros() == 0UL ) return;
347 
348  // Evaluation of the right-hand side sparse matrix operand
349  RT A( serial( rhs.mat_ ) );
350 
351  // Checking the evaluated operands
352  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
353  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
354  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
355  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
356 
357  // Performing the sparse vector-sparse matrix multiplication
358  TSVecTSMatMultExpr::selectAssignKernel( ~lhs, x, A );
359  }
361  //**********************************************************************************************
362 
363  //**Default assignment to dense vectors*********************************************************
377  template< typename VT1 // Type of the left-hand side target vector
378  , typename VT2 // Type of the left-hand side vector operand
379  , typename MT1 > // Type of the right-hand side matrix operand
380  static inline void selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
381  {
382  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
383  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
384 
385  const VectorIterator vend( x.end() );
386 
387  for( size_t j=0UL; j<A.columns(); ++j )
388  {
389  const MatrixIterator mend ( A.end(j) );
390  MatrixIterator melem( A.begin(j) );
391 
392  if( melem == mend ) continue;
393 
394  VectorIterator velem( x.begin() );
395 
396  while( true ) {
397  if( velem->index() < melem->index() ) {
398  ++velem;
399  if( velem == vend ) break;
400  }
401  else if( melem->index() < velem->index() ) {
402  ++melem;
403  if( melem == mend ) break;
404  }
405  else {
406  y[j] = velem->value() * melem->value();
407  ++velem;
408  ++melem;
409  break;
410  }
411  }
412 
413  if( velem != vend && melem != mend )
414  {
415  while( true ) {
416  if( velem->index() < melem->index() ) {
417  ++velem;
418  if( velem == vend ) break;
419  }
420  else if( melem->index() < velem->index() ) {
421  ++melem;
422  if( melem == mend ) break;
423  }
424  else {
425  y[j] += velem->value() * melem->value();
426  ++velem;
427  if( velem == vend ) break;
428  ++melem;
429  if( melem == mend ) break;
430  }
431  }
432  }
433  }
434  }
436  //**********************************************************************************************
437 
438  //**Assignment to sparse vectors****************************************************************
451  template< typename VT1 > // Type of the target sparse vector
452  friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
453  {
455 
456  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
457 
458  typedef typename RemoveReference<LT>::Type::ConstIterator VectorIterator;
459  typedef typename RemoveReference<RT>::Type::ConstIterator MatrixIterator;
460 
461  // Evaluation of the left-hand side sparse vector operand
462  LT x( serial( rhs.vec_ ) );
463  if( x.nonZeros() == 0UL ) return;
464 
465  // Evaluation of the right-hand side sparse matrix operand
466  RT A( serial( rhs.mat_ ) );
467 
468  // Checking the evaluated operands
469  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
470  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
471  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
472  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
473 
474  // Performing the sparse vector-sparse matrix multiplication
475  ElementType accu;
476  const VectorIterator vend( x.end() );
477 
478  for( size_t j=0UL; j<A.columns(); ++j )
479  {
480  const MatrixIterator mend ( A.end(j) );
481  MatrixIterator melem( A.begin(j) );
482 
483  if( melem == mend ) continue;
484 
485  VectorIterator velem( x.begin() );
486 
487  reset( accu );
488 
489  while( true ) {
490  if( velem->index() < melem->index() ) {
491  ++velem;
492  if( velem == vend ) break;
493  }
494  else if( melem->index() < velem->index() ) {
495  ++melem;
496  if( melem == mend ) break;
497  }
498  else {
499  accu = velem->value() * melem->value();
500  ++velem;
501  ++melem;
502  break;
503  }
504  }
505 
506  if( velem != vend && melem != mend )
507  {
508  while( true ) {
509  if( velem->index() < melem->index() ) {
510  ++velem;
511  if( velem == vend ) break;
512  }
513  else if( melem->index() < velem->index() ) {
514  ++melem;
515  if( melem == mend ) break;
516  }
517  else {
518  accu += velem->value() * melem->value();
519  ++velem;
520  if( velem == vend ) break;
521  ++melem;
522  if( melem == mend ) break;
523  }
524  }
525  }
526 
527  if( !isDefault( accu ) )
528  (~lhs).insert( j, accu );
529  }
530  }
532  //**********************************************************************************************
533 
534  //**Addition assignment to dense vectors********************************************************
547  template< typename VT1 > // Type of the target dense vector
548  friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
549  {
551 
552  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
553 
554  // Evaluation of the left-hand side sparse vector operand
555  LT x( serial( rhs.vec_ ) );
556  if( x.nonZeros() == 0UL ) return;
557 
558  // Evaluation of the right-hand side sparse matrix operand
559  RT A( serial( rhs.mat_ ) );
560 
561  // Checking the evaluated operands
562  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
563  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
564  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
565  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
566 
567  // Performing the sparse matrix-sparse vector multiplication
568  TSVecTSMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
569  }
571  //**********************************************************************************************
572 
573  //**Default addition assignment to dense vectors************************************************
587  template< typename VT1 // Type of the left-hand side target vector
588  , typename VT2 // Type of the left-hand side vector operand
589  , typename MT1 > // Type of the right-hand side matrix operand
590  static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
591  {
592  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
593  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
594 
595  const VectorIterator vend( x.end() );
596 
597  for( size_t j=0UL; j<A.columns(); ++j )
598  {
599  const MatrixIterator mend ( A.end(j) );
600  MatrixIterator melem( A.begin(j) );
601 
602  if( melem == mend ) continue;
603 
604  VectorIterator velem( x.begin() );
605 
606  while( true ) {
607  if( velem->index() < melem->index() ) {
608  ++velem;
609  if( velem == vend ) break;
610  }
611  else if( melem->index() < velem->index() ) {
612  ++melem;
613  if( melem == mend ) break;
614  }
615  else {
616  y[j] += velem->value() * melem->value();
617  ++velem;
618  if( velem == vend ) break;
619  ++melem;
620  if( melem == mend ) break;
621  }
622  }
623  }
624  }
626  //**********************************************************************************************
627 
628  //**Addition assignment to sparse vectors*******************************************************
629  // No special implementation for the addition assignment to sparse vectors.
630  //**********************************************************************************************
631 
632  //**Subtraction assignment to dense vectors*****************************************************
645  template< typename VT1 > // Type of the target dense vector
646  friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
647  {
649 
650  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
651 
652  // Evaluation of the left-hand side sparse vector operand
653  LT x( serial( rhs.vec_ ) );
654  if( x.nonZeros() == 0UL ) return;
655 
656  // Evaluation of the right-hand side sparse matrix operand
657  RT A( serial( rhs.mat_ ) );
658 
659  // Checking the evaluated operands
660  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
661  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
662  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
663  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
664 
665  // Performing the sparse matrix-sparse vector multiplication
666  TSVecTSMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
667  }
669  //**********************************************************************************************
670 
671  //**Default subtraction assignment to dense vectors*********************************************
685  template< typename VT1 // Type of the left-hand side target vector
686  , typename VT2 // Type of the left-hand side vector operand
687  , typename MT1 > // Type of the right-hand side matrix operand
688  static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
689  {
690  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
691  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
692 
693  const VectorIterator vend( x.end() );
694 
695  for( size_t j=0UL; j<A.columns(); ++j )
696  {
697  const MatrixIterator mend ( A.end(j) );
698  MatrixIterator melem( A.begin(j) );
699 
700  if( melem == mend ) continue;
701 
702  VectorIterator velem( x.begin() );
703 
704  while( true ) {
705  if( velem->index() < melem->index() ) {
706  ++velem;
707  if( velem == vend ) break;
708  }
709  else if( melem->index() < velem->index() ) {
710  ++melem;
711  if( melem == mend ) break;
712  }
713  else {
714  y[j] -= velem->value() * melem->value();
715  ++velem;
716  if( velem == vend ) break;
717  ++melem;
718  if( melem == mend ) break;
719  }
720  }
721  }
722  }
724  //**********************************************************************************************
725 
726  //**Subtraction assignment to sparse vectors****************************************************
727  // No special implementation for the subtraction assignment to sparse vectors.
728  //**********************************************************************************************
729 
730  //**Multiplication assignment to dense vectors**************************************************
743  template< typename VT1 > // Type of the target dense vector
744  friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
745  {
747 
751 
752  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
753 
754  const ResultType tmp( serial( rhs ) );
755  multAssign( ~lhs, tmp );
756  }
758  //**********************************************************************************************
759 
760  //**Multiplication assignment to sparse vectors*************************************************
761  // No special implementation for the multiplication assignment to sparse vectors.
762  //**********************************************************************************************
763 
764  //**SMP assignment to dense vectors*************************************************************
779  template< typename VT1 > // Type of the target dense vector
780  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
781  smpAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
782  {
784 
785  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
786 
787  // Resetting the left-hand side target dense vector
788  reset( ~lhs );
789 
790  // Evaluation of the left-hand side sparse vector operand
791  LT x( rhs.vec_ );
792  if( x.nonZeros() == 0UL ) return;
793 
794  // Evaluation of the right-hand side sparse matrix operand
795  RT A( rhs.mat_ );
796 
797  // Checking the evaluated operands
798  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
799  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
800  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
801  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
802 
803  // Performing the sparse vector-sparse matrix multiplication
804  smpAssign( ~lhs, x * A );
805  }
807  //**********************************************************************************************
808 
809  //**SMP assignment to sparse vectors************************************************************
810  // No special implementation for the SMP assignment to sparse vectors.
811  //**********************************************************************************************
812 
813  //**SMP addition assignment to dense vectors****************************************************
828  template< typename VT1 > // Type of the target dense vector
829  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
830  smpAddAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
831  {
833 
834  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
835 
836  // Evaluation of the left-hand side sparse vector operand
837  LT x( rhs.vec_ );
838  if( x.nonZeros() == 0UL ) return;
839 
840  // Evaluation of the right-hand side sparse matrix operand
841  RT A( rhs.mat_ );
842 
843  // Checking the evaluated operands
844  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
845  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
846  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
847  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
848 
849  // Performing the sparse matrix-sparse vector multiplication
850  smpAddAssign( ~lhs, x * A );
851  }
853  //**********************************************************************************************
854 
855  //**SMP addition assignment to sparse vectors***************************************************
856  // No special implementation for the SMP addition assignment to sparse vectors.
857  //**********************************************************************************************
858 
859  //**SMP subtraction assignment to dense vectors*************************************************
874  template< typename VT1 > // Type of the target dense vector
875  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
876  smpSubAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
877  {
879 
880  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
881 
882  // Evaluation of the left-hand side sparse vector operand
883  LT x( rhs.vec_ );
884  if( x.nonZeros() == 0UL ) return;
885 
886  // Evaluation of the right-hand side sparse matrix operand
887  RT A( rhs.mat_ );
888 
889  // Checking the evaluated operands
890  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
891  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
892  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
893  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
894 
895  // Performing the sparse matrix-sparse vector multiplication
896  smpSubAssign( ~lhs, x * A );
897  }
899  //**********************************************************************************************
900 
901  //**SMP subtraction assignment to sparse vectors************************************************
902  // No special implementation for the SMP subtraction assignment to sparse vectors.
903  //**********************************************************************************************
904 
905  //**SMP multiplication assignment to dense vectors**********************************************
920  template< typename VT1 > // Type of the target dense vector
921  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
922  smpMultAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
923  {
925 
929 
930  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
931 
932  const ResultType tmp( rhs );
933  smpMultAssign( ~lhs, tmp );
934  }
936  //**********************************************************************************************
937 
938  //**SMP multiplication assignment to sparse vectors*********************************************
939  // No special implementation for the SMP multiplication assignment to sparse vectors.
940  //**********************************************************************************************
941 
942  //**Compile time checks*************************************************************************
949  //**********************************************************************************************
950 };
951 //*************************************************************************************************
952 
953 
954 
955 
956 //=================================================================================================
957 //
958 // GLOBAL BINARY ARITHMETIC OPERATORS
959 //
960 //=================================================================================================
961 
962 //*************************************************************************************************
993 template< typename T1 // Type of the left-hand side sparse vector
994  , typename T2 > // Type of the right-hand side sparse matrix
995 inline const typename DisableIf< IsMatMatMultExpr<T2>, TSVecTSMatMultExpr<T1,T2> >::Type
997 {
999 
1000  if( (~vec).size() != (~mat).rows() )
1001  throw std::invalid_argument( "Vector and matrix sizes do not match" );
1002 
1003  return TSVecTSMatMultExpr<T1,T2>( ~vec, ~mat );
1004 }
1005 //*************************************************************************************************
1006 
1007 
1008 
1009 
1010 //=================================================================================================
1011 //
1012 // EXPRESSION TRAIT SPECIALIZATIONS
1013 //
1014 //=================================================================================================
1015 
1016 //*************************************************************************************************
1018 template< typename VT, typename MT, bool AF >
1019 struct SubvectorExprTrait< TSVecTSMatMultExpr<VT,MT>, AF >
1020 {
1021  public:
1022  //**********************************************************************************************
1023  typedef typename MultExprTrait< VT, typename SubmatrixExprTrait<const MT,AF>::Type >::Type Type;
1024  //**********************************************************************************************
1025 };
1027 //*************************************************************************************************
1028 
1029 } // namespace blaze
1030 
1031 #endif
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
SelectType< evaluateMatrix, const MRT, MCT >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:141
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4599
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:4329
size_t size() const
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:246
Header file for the SparseVector base class.
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:152
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4642
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:199
void smpMultAssign(DenseVector< 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:179
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2408
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:251
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:690
Header file for the Computation base class.
TSVecTSMatMultExpr< VT, MT > This
Type of this TSVecTSMatMultExpr instance.
Definition: TSVecTSMatMultExpr.h:124
Header file for the RequiresEvaluation type trait.
MT::CompositeType MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:96
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:266
TSVecTSMatMultExpr(const VT &vec, const MT &mat)
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:156
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:317
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
Constraint on the data type.
Constraint on the data type.
void smpAddAssign(DenseMatrix< 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:122
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:253
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
Header file for the multiplication trait.
#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: StorageOrder.h:161
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2412
Expression object for sparse vector-sparse matrix multiplications.The TSVecTSMatMultExpr class repres...
Definition: Forward.h:150
Header file for the IsMatMatMultExpr type trait class.
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:271
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:79
Constraint on the data type.
#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:78
size_t nonZeros() const
Returns an estimation for the number of non-zero elements in the sparse vector.
Definition: TSVecTSMatMultExpr.h:256
Constraints on the storage order of matrix types.
MultTrait< VRT, MRT >::Type ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:125
void multAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the multiplication assignment of a matrix to a matrix.
Definition: Matrix.h:361
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the serial shim.
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:135
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:92
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecTSMatMultExpr.h:129
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:126
MT::ResultType MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:94
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Header file for run time assertion macros.
Base template for the MultTrait class.
Definition: MultTrait.h:141
SelectType< evaluateVector, const VRT, VCT >::Type LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:138
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:301
VT::CompositeType VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:95
Header file for the reset shim.
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:331
ResultType::ElementType ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:127
Header file for the isDefault shim.
Header file for the TVecMatMultExpr base class.
Header file for the RemoveReference type trait.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSVecTSMatMultExpr.h:300
const size_t SMP_TSVECSMATMULT_THRESHOLD
SMP sparse vector/row-major sparse matrix multiplication threshold.This threshold specifies when a sp...
Definition: Thresholds.h:644
Header file for the IsComputation type trait class.
RightOperand mat_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:318
VT::ResultType VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:93
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:128
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:170
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:108
#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
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:132
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2403
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:288
Header file for basic type definitions.
#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: TransposeFlag.h:81
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:154
#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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:310
#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:79
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:276