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>
55 #include <blaze/math/shims/Reset.h>
66 #include <blaze/util/Assert.h>
68 #include <blaze/util/DisableIf.h>
69 #include <blaze/util/EnableIf.h>
71 #include <blaze/util/mpl/Or.h>
72 #include <blaze/util/SelectType.h>
73 #include <blaze/util/Types.h>
75 
76 
77 namespace blaze {
78 
79 //=================================================================================================
80 //
81 // CLASS TSVECTSMATMULTEXPR
82 //
83 //=================================================================================================
84 
85 //*************************************************************************************************
92 template< typename VT // Type of the left-hand side sparse vector
93  , typename MT > // Type of the right-hand side sparse matrix
94 class TSVecTSMatMultExpr : public SparseVector< TSVecTSMatMultExpr<VT,MT>, true >
95  , private TVecMatMultExpr
96  , private Computation
97 {
98  private:
99  //**Type definitions****************************************************************************
100  typedef typename VT::ResultType VRT;
101  typedef typename MT::ResultType MRT;
102  typedef typename VT::CompositeType VCT;
103  typedef typename MT::CompositeType MCT;
104  //**********************************************************************************************
105 
106  //**********************************************************************************************
108  enum { evaluateVector = IsComputation<VT>::value };
109  //**********************************************************************************************
110 
111  //**********************************************************************************************
113  enum { evaluateMatrix = RequiresEvaluation<MT>::value };
114  //**********************************************************************************************
115 
116  //**********************************************************************************************
118 
122  template< typename T1 >
123  struct UseSMPAssign {
124  enum { value = ( evaluateVector || evaluateMatrix ) };
125  };
127  //**********************************************************************************************
128 
129  public:
130  //**Type definitions****************************************************************************
135  typedef const ElementType ReturnType;
136  typedef const ResultType CompositeType;
137 
139  typedef typename SelectType< IsExpression<VT>::value, const VT, const VT& >::Type LeftOperand;
140 
142  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type RightOperand;
143 
146 
149  //**********************************************************************************************
150 
151  //**Compilation flags***************************************************************************
153  enum { smpAssignable = !evaluateVector && VT::smpAssignable &&
154  !evaluateMatrix && MT::smpAssignable };
155  //**********************************************************************************************
156 
157  //**Constructor*********************************************************************************
163  explicit inline TSVecTSMatMultExpr( const VT& vec, const MT& mat )
164  : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
165  , mat_( mat ) // Right-hand side sparse matrix of the multiplication expression
166  {
167  BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
168  }
169  //**********************************************************************************************
170 
171  //**Subscript operator**************************************************************************
177  inline ReturnType operator[]( size_t index ) const {
178  BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
179 
180  typedef typename RemoveReference<VCT>::Type::ConstIterator VectorIterator;
181  typedef typename RemoveReference<MCT>::Type::ConstIterator MatrixIterator;
182 
183  VCT x( vec_ ); // Evaluation of the left-hand side sparse vector operand
184  MCT A( mat_ ); // Evaluation of the right-hand side sparse matrix operand
185 
186  BLAZE_INTERNAL_ASSERT( x.size() == vec_.size() , "Invalid vector size" );
187  BLAZE_INTERNAL_ASSERT( A.rows() == mat_.rows() , "Invalid number of rows" );
188  BLAZE_INTERNAL_ASSERT( A.columns() == mat_.columns(), "Invalid number of columns" );
189 
190  ElementType res = ElementType();
191 
192  VectorIterator velem( x.begin() );
193  const VectorIterator vend( x.end() );
194  if( velem == vend ) {
195  reset( res );
196  return res;
197  }
198 
199  MatrixIterator melem( A.begin(index) );
200  const MatrixIterator mend( A.end(index) );
201  if( melem == mend ) {
202  reset( res );
203  return res;
204  }
205 
206  while( true ) {
207  if( velem->index() < melem->index() ) {
208  ++velem;
209  if( velem == vend ) break;
210  }
211  else if( melem->index() < velem->index() ) {
212  ++melem;
213  if( melem == mend ) break;
214  }
215  else {
216  res = velem->value() * melem->value();
217  ++velem;
218  ++melem;
219  break;
220  }
221  }
222 
223  if( melem != mend && velem != vend )
224  {
225  while( true ) {
226  if( velem->index() < melem->index() ) {
227  ++velem;
228  if( velem == vend ) break;
229  }
230  else if( melem->index() < velem->index() ) {
231  ++melem;
232  if( melem == mend ) break;
233  }
234  else {
235  res += velem->value() * melem->value();
236  ++velem;
237  if( velem == vend ) break;
238  ++melem;
239  if( melem == mend ) break;
240  }
241  }
242  }
243 
244  return res;
245  }
246  //**********************************************************************************************
247 
248  //**Size function*******************************************************************************
253  inline size_t size() const {
254  return mat_.columns();
255  }
256  //**********************************************************************************************
257 
258  //**NonZeros function***************************************************************************
263  inline size_t nonZeros() const {
264  return mat_.columns();
265  }
266  //**********************************************************************************************
267 
268  //**Left operand access*************************************************************************
273  inline LeftOperand leftOperand() const {
274  return vec_;
275  }
276  //**********************************************************************************************
277 
278  //**Right operand access************************************************************************
283  inline RightOperand rightOperand() const {
284  return mat_;
285  }
286  //**********************************************************************************************
287 
288  //**********************************************************************************************
294  template< typename T >
295  inline bool canAlias( const T* alias ) const {
296  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
297  }
298  //**********************************************************************************************
299 
300  //**********************************************************************************************
306  template< typename T >
307  inline bool isAliased( const T* alias ) const {
308  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
309  }
310  //**********************************************************************************************
311 
312  //**********************************************************************************************
317  inline bool canSMPAssign() const {
318  return ( size() > SMP_TSVECSMATMULT_THRESHOLD );
319  }
320  //**********************************************************************************************
321 
322  private:
323  //**Member variables****************************************************************************
326  //**********************************************************************************************
327 
328  //**Assignment to dense vectors*****************************************************************
341  template< typename VT1 > // Type of the target dense vector
342  friend inline void assign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
343  {
345 
346  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
347 
348  // Resetting the left-hand side target dense vector
349  reset( ~lhs );
350 
351  // Evaluation of the left-hand side sparse vector operand
352  LT x( serial( rhs.vec_ ) );
353  if( x.nonZeros() == 0UL ) return;
354 
355  // Evaluation of the right-hand side sparse matrix operand
356  RT A( serial( rhs.mat_ ) );
357 
358  // Checking the evaluated operands
359  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
360  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
361  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
362  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
363 
364  // Performing the sparse vector-sparse matrix multiplication
365  TSVecTSMatMultExpr::selectAssignKernel( ~lhs, x, A );
366  }
368  //**********************************************************************************************
369 
370  //**Default assignment to dense vectors*********************************************************
384  template< typename VT1 // Type of the left-hand side target vector
385  , typename VT2 // Type of the left-hand side vector operand
386  , typename MT1 > // Type of the right-hand side matrix operand
387  static inline void selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
388  {
389  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
390  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
391 
392  const VectorIterator vend( x.end() );
393 
394  for( size_t j=0UL; j<A.columns(); ++j )
395  {
396  const MatrixIterator mend ( A.end(j) );
397  MatrixIterator melem( A.begin(j) );
398 
399  if( melem == mend ) continue;
400 
401  VectorIterator velem( x.begin() );
402 
403  while( true ) {
404  if( velem->index() < melem->index() ) {
405  ++velem;
406  if( velem == vend ) break;
407  }
408  else if( melem->index() < velem->index() ) {
409  ++melem;
410  if( melem == mend ) break;
411  }
412  else {
413  y[j] = velem->value() * melem->value();
414  ++velem;
415  ++melem;
416  break;
417  }
418  }
419 
420  if( velem != vend && melem != mend )
421  {
422  while( true ) {
423  if( velem->index() < melem->index() ) {
424  ++velem;
425  if( velem == vend ) break;
426  }
427  else if( melem->index() < velem->index() ) {
428  ++melem;
429  if( melem == mend ) break;
430  }
431  else {
432  y[j] += velem->value() * melem->value();
433  ++velem;
434  if( velem == vend ) break;
435  ++melem;
436  if( melem == mend ) break;
437  }
438  }
439  }
440  }
441  }
443  //**********************************************************************************************
444 
445  //**Assignment to sparse vectors****************************************************************
458  template< typename VT1 > // Type of the target sparse vector
459  friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
460  {
462 
463  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
464 
465  typedef typename RemoveReference<LT>::Type::ConstIterator VectorIterator;
466  typedef typename RemoveReference<RT>::Type::ConstIterator MatrixIterator;
467 
468  // Evaluation of the left-hand side sparse vector operand
469  LT x( serial( rhs.vec_ ) );
470  if( x.nonZeros() == 0UL ) return;
471 
472  // Evaluation of the right-hand side sparse matrix operand
473  RT A( serial( rhs.mat_ ) );
474 
475  // Checking the evaluated operands
476  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
477  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
478  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
479  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
480 
481  // Performing the sparse vector-sparse matrix multiplication
482  ElementType accu;
483  const VectorIterator vend( x.end() );
484 
485  for( size_t j=0UL; j<A.columns(); ++j )
486  {
487  const MatrixIterator mend ( A.end(j) );
488  MatrixIterator melem( A.begin(j) );
489 
490  if( melem == mend ) continue;
491 
492  VectorIterator velem( x.begin() );
493 
494  reset( accu );
495 
496  while( true ) {
497  if( velem->index() < melem->index() ) {
498  ++velem;
499  if( velem == vend ) break;
500  }
501  else if( melem->index() < velem->index() ) {
502  ++melem;
503  if( melem == mend ) break;
504  }
505  else {
506  accu = velem->value() * melem->value();
507  ++velem;
508  ++melem;
509  break;
510  }
511  }
512 
513  if( velem != vend && melem != mend )
514  {
515  while( true ) {
516  if( velem->index() < melem->index() ) {
517  ++velem;
518  if( velem == vend ) break;
519  }
520  else if( melem->index() < velem->index() ) {
521  ++melem;
522  if( melem == mend ) break;
523  }
524  else {
525  accu += velem->value() * melem->value();
526  ++velem;
527  if( velem == vend ) break;
528  ++melem;
529  if( melem == mend ) break;
530  }
531  }
532  }
533 
534  if( !isDefault( accu ) )
535  (~lhs).insert( j, accu );
536  }
537  }
539  //**********************************************************************************************
540 
541  //**Addition assignment to dense vectors********************************************************
554  template< typename VT1 > // Type of the target dense vector
555  friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
556  {
558 
559  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
560 
561  // Evaluation of the left-hand side sparse vector operand
562  LT x( serial( rhs.vec_ ) );
563  if( x.nonZeros() == 0UL ) return;
564 
565  // Evaluation of the right-hand side sparse matrix operand
566  RT A( serial( rhs.mat_ ) );
567 
568  // Checking the evaluated operands
569  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
570  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
571  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
572  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
573 
574  // Performing the sparse matrix-sparse vector multiplication
575  TSVecTSMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
576  }
578  //**********************************************************************************************
579 
580  //**Default addition assignment to dense vectors************************************************
594  template< typename VT1 // Type of the left-hand side target vector
595  , typename VT2 // Type of the left-hand side vector operand
596  , typename MT1 > // Type of the right-hand side matrix operand
597  static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
598  {
599  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
600  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
601 
602  const VectorIterator vend( x.end() );
603 
604  for( size_t j=0UL; j<A.columns(); ++j )
605  {
606  const MatrixIterator mend ( A.end(j) );
607  MatrixIterator melem( A.begin(j) );
608 
609  if( melem == mend ) continue;
610 
611  VectorIterator velem( x.begin() );
612 
613  while( true ) {
614  if( velem->index() < melem->index() ) {
615  ++velem;
616  if( velem == vend ) break;
617  }
618  else if( melem->index() < velem->index() ) {
619  ++melem;
620  if( melem == mend ) break;
621  }
622  else {
623  y[j] += velem->value() * melem->value();
624  ++velem;
625  if( velem == vend ) break;
626  ++melem;
627  if( melem == mend ) break;
628  }
629  }
630  }
631  }
633  //**********************************************************************************************
634 
635  //**Addition assignment to sparse vectors*******************************************************
636  // No special implementation for the addition assignment to sparse vectors.
637  //**********************************************************************************************
638 
639  //**Subtraction assignment to dense vectors*****************************************************
652  template< typename VT1 > // Type of the target dense vector
653  friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
654  {
656 
657  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
658 
659  // Evaluation of the left-hand side sparse vector operand
660  LT x( serial( rhs.vec_ ) );
661  if( x.nonZeros() == 0UL ) return;
662 
663  // Evaluation of the right-hand side sparse matrix operand
664  RT A( serial( rhs.mat_ ) );
665 
666  // Checking the evaluated operands
667  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
668  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
669  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
670  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
671 
672  // Performing the sparse matrix-sparse vector multiplication
673  TSVecTSMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
674  }
676  //**********************************************************************************************
677 
678  //**Default subtraction assignment to dense vectors*********************************************
692  template< typename VT1 // Type of the left-hand side target vector
693  , typename VT2 // Type of the left-hand side vector operand
694  , typename MT1 > // Type of the right-hand side matrix operand
695  static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
696  {
697  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
698  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
699 
700  const VectorIterator vend( x.end() );
701 
702  for( size_t j=0UL; j<A.columns(); ++j )
703  {
704  const MatrixIterator mend ( A.end(j) );
705  MatrixIterator melem( A.begin(j) );
706 
707  if( melem == mend ) continue;
708 
709  VectorIterator velem( x.begin() );
710 
711  while( true ) {
712  if( velem->index() < melem->index() ) {
713  ++velem;
714  if( velem == vend ) break;
715  }
716  else if( melem->index() < velem->index() ) {
717  ++melem;
718  if( melem == mend ) break;
719  }
720  else {
721  y[j] -= velem->value() * melem->value();
722  ++velem;
723  if( velem == vend ) break;
724  ++melem;
725  if( melem == mend ) break;
726  }
727  }
728  }
729  }
731  //**********************************************************************************************
732 
733  //**Subtraction assignment to sparse vectors****************************************************
734  // No special implementation for the subtraction assignment to sparse vectors.
735  //**********************************************************************************************
736 
737  //**Multiplication assignment to dense vectors**************************************************
750  template< typename VT1 > // Type of the target dense vector
751  friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
752  {
754 
758 
759  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
760 
761  const ResultType tmp( serial( rhs ) );
762  multAssign( ~lhs, tmp );
763  }
765  //**********************************************************************************************
766 
767  //**Multiplication assignment to sparse vectors*************************************************
768  // No special implementation for the multiplication assignment to sparse vectors.
769  //**********************************************************************************************
770 
771  //**SMP assignment to dense vectors*************************************************************
786  template< typename VT1 > // Type of the target dense vector
787  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
788  smpAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
789  {
791 
792  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
793 
794  // Resetting the left-hand side target dense vector
795  reset( ~lhs );
796 
797  // Evaluation of the left-hand side sparse vector operand
798  LT x( rhs.vec_ );
799  if( x.nonZeros() == 0UL ) return;
800 
801  // Evaluation of the right-hand side sparse matrix operand
802  RT A( rhs.mat_ );
803 
804  // Checking the evaluated operands
805  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
806  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
807  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
808  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
809 
810  // Performing the sparse vector-sparse matrix multiplication
811  smpAssign( ~lhs, x * A );
812  }
814  //**********************************************************************************************
815 
816  //**SMP assignment to sparse vectors************************************************************
817  // No special implementation for the SMP assignment to sparse vectors.
818  //**********************************************************************************************
819 
820  //**SMP addition assignment to dense vectors****************************************************
835  template< typename VT1 > // Type of the target dense vector
836  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
837  smpAddAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
838  {
840 
841  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
842 
843  // Evaluation of the left-hand side sparse vector operand
844  LT x( rhs.vec_ );
845  if( x.nonZeros() == 0UL ) return;
846 
847  // Evaluation of the right-hand side sparse matrix operand
848  RT A( rhs.mat_ );
849 
850  // Checking the evaluated operands
851  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
852  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
853  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
854  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
855 
856  // Performing the sparse matrix-sparse vector multiplication
857  smpAddAssign( ~lhs, x * A );
858  }
860  //**********************************************************************************************
861 
862  //**SMP addition assignment to sparse vectors***************************************************
863  // No special implementation for the SMP addition assignment to sparse vectors.
864  //**********************************************************************************************
865 
866  //**SMP subtraction assignment to dense vectors*************************************************
881  template< typename VT1 > // Type of the target dense vector
882  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
883  smpSubAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
884  {
886 
887  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
888 
889  // Evaluation of the left-hand side sparse vector operand
890  LT x( rhs.vec_ );
891  if( x.nonZeros() == 0UL ) return;
892 
893  // Evaluation of the right-hand side sparse matrix operand
894  RT A( rhs.mat_ );
895 
896  // Checking the evaluated operands
897  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
898  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
899  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
900  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
901 
902  // Performing the sparse matrix-sparse vector multiplication
903  smpSubAssign( ~lhs, x * A );
904  }
906  //**********************************************************************************************
907 
908  //**SMP subtraction assignment to sparse vectors************************************************
909  // No special implementation for the SMP subtraction assignment to sparse vectors.
910  //**********************************************************************************************
911 
912  //**SMP multiplication assignment to dense vectors**********************************************
927  template< typename VT1 > // Type of the target dense vector
928  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
929  smpMultAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
930  {
932 
936 
937  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
938 
939  const ResultType tmp( rhs );
940  smpMultAssign( ~lhs, tmp );
941  }
943  //**********************************************************************************************
944 
945  //**SMP multiplication assignment to sparse vectors*********************************************
946  // No special implementation for the SMP multiplication assignment to sparse vectors.
947  //**********************************************************************************************
948 
949  //**Compile time checks*************************************************************************
957  //**********************************************************************************************
958 };
959 //*************************************************************************************************
960 
961 
962 
963 
964 //=================================================================================================
965 //
966 // GLOBAL BINARY ARITHMETIC OPERATORS
967 //
968 //=================================================================================================
969 
970 //*************************************************************************************************
1001 template< typename T1 // Type of the left-hand side sparse vector
1002  , typename T2 > // Type of the right-hand side sparse matrix
1003 inline const typename DisableIf< Or< IsSymmetric<T2>, IsMatMatMultExpr<T2> >
1004  , TSVecTSMatMultExpr<T1,T2> >::Type
1006 {
1008 
1009  if( (~vec).size() != (~mat).rows() )
1010  throw std::invalid_argument( "Vector and matrix sizes do not match" );
1011 
1012  return TSVecTSMatMultExpr<T1,T2>( ~vec, ~mat );
1013 }
1014 //*************************************************************************************************
1015 
1016 
1017 
1018 
1019 //=================================================================================================
1020 //
1021 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1022 //
1023 //=================================================================================================
1024 
1025 //*************************************************************************************************
1040 template< typename T1 // Type of the left-hand side sparse vector
1041  , typename T2 > // Type of the right-hand side sparse matrix
1042 inline const typename EnableIf< IsSymmetric<T2>, typename MultExprTrait<T1,T2>::Type >::Type
1043  operator*( const SparseVector<T1,true>& vec, const SparseMatrix<T2,true>& mat )
1044 {
1046 
1048 
1049  if( (~vec).size() != (~mat).rows() )
1050  throw std::invalid_argument( "Vector and matrix sizes do not match" );
1051 
1052  return (~vec) * trans( ~mat );
1053 }
1055 //*************************************************************************************************
1056 
1057 
1058 
1059 
1060 //=================================================================================================
1061 //
1062 // SIZE SPECIALIZATIONS
1063 //
1064 //=================================================================================================
1065 
1066 //*************************************************************************************************
1068 template< typename MT, typename VT >
1069 struct Size< TSVecTSMatMultExpr<MT,VT> >
1070  : public Columns<MT>
1071 {};
1073 //*************************************************************************************************
1074 
1075 
1076 
1077 
1078 //=================================================================================================
1079 //
1080 // EXPRESSION TRAIT SPECIALIZATIONS
1081 //
1082 //=================================================================================================
1083 
1084 //*************************************************************************************************
1086 template< typename VT, typename MT, bool AF >
1087 struct SubvectorExprTrait< TSVecTSMatMultExpr<VT,MT>, AF >
1088 {
1089  public:
1090  //**********************************************************************************************
1091  typedef typename MultExprTrait< VT, typename SubmatrixExprTrait<const MT,AF>::Type >::Type Type;
1092  //**********************************************************************************************
1093 };
1095 //*************************************************************************************************
1096 
1097 } // namespace blaze
1098 
1099 #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:148
BLAZE_ALWAYS_INLINE 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:879
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:4838
size_t size() const
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:253
Header file for the SparseVector base class.
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:205
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:257
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:695
Header file for the Computation base class.
TSVecTSMatMultExpr< VT, MT > This
Type of this TSVecTSMatMultExpr instance.
Definition: TSVecTSMatMultExpr.h:131
Header file for the RequiresEvaluation type trait.
MT::CompositeType MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:103
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:273
TSVecTSMatMultExpr(const VT &vec, const MT &mat)
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:163
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:324
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.
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:259
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.
Header file for the IsSymmetric type 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:2482
Expression object for sparse vector-sparse matrix multiplications.The TSVecTSMatMultExpr class repres...
Definition: Forward.h:150
Header file for the Or class template.
Header file for the IsMatMatMultExpr type trait class.
BLAZE_ALWAYS_INLINE 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:635
Header file for the Columns type trait.
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_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:126
#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:263
Constraints on the storage order of matrix types.
MultTrait< VRT, MRT >::Type ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:132
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 EnableIf class template.
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:142
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecTSMatMultExpr.h:136
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:133
MT::ResultType MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:101
EnableIf< IsDenseMatrix< MT1 > >::Type 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
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.
EnableIf< IsDenseMatrix< MT1 > >::Type 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
Base template for the MultTrait class.
Definition: MultTrait.h:142
SelectType< evaluateVector, const VRT, VCT >::Type LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:145
BLAZE_ALWAYS_INLINE 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:742
VT::CompositeType VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:102
Header file for the reset shim.
Constraint on the data type.
ResultType::ElementType ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:134
Header file for the isDefault shim.
Header file for the TVecMatMultExpr base class.
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
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:307
#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:166
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
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:932
Header file for the IsComputation type trait class.
RightOperand mat_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:325
VT::ResultType VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:100
EnableIf< IsDenseMatrix< MT1 > >::Type 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
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:135
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:177
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:139
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2473
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:295
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
Constraint on the data type.
EnableIf< IsDenseVector< VT1 > >::Type 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:189
Header file for the Size type trait.
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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:317
#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.
BLAZE_ALWAYS_INLINE 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:849
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:283