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 
54 #include <blaze/math/shims/Reset.h>
65 #include <blaze/util/Assert.h>
67 #include <blaze/util/DisableIf.h>
68 #include <blaze/util/EnableIf.h>
69 #include <blaze/util/Exception.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  //**At function*********************************************************************************
255  inline ReturnType at( size_t index ) const {
256  if( index >= mat_.columns() ) {
257  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
258  }
259  return (*this)[index];
260  }
261  //**********************************************************************************************
262 
263  //**Size function*******************************************************************************
268  inline size_t size() const {
269  return mat_.columns();
270  }
271  //**********************************************************************************************
272 
273  //**NonZeros function***************************************************************************
278  inline size_t nonZeros() const {
279  return mat_.columns();
280  }
281  //**********************************************************************************************
282 
283  //**Left operand access*************************************************************************
288  inline LeftOperand leftOperand() const {
289  return vec_;
290  }
291  //**********************************************************************************************
292 
293  //**Right operand access************************************************************************
298  inline RightOperand rightOperand() const {
299  return mat_;
300  }
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
309  template< typename T >
310  inline bool canAlias( const T* alias ) const {
311  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
312  }
313  //**********************************************************************************************
314 
315  //**********************************************************************************************
321  template< typename T >
322  inline bool isAliased( const T* alias ) const {
323  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
324  }
325  //**********************************************************************************************
326 
327  //**********************************************************************************************
332  inline bool canSMPAssign() const {
333  return ( size() > SMP_TSVECSMATMULT_THRESHOLD );
334  }
335  //**********************************************************************************************
336 
337  private:
338  //**Member variables****************************************************************************
339  LeftOperand vec_;
340  RightOperand mat_;
341  //**********************************************************************************************
342 
343  //**Assignment to dense vectors*****************************************************************
356  template< typename VT1 > // Type of the target dense vector
357  friend inline void assign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
358  {
360 
361  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
362 
363  // Resetting the left-hand side target dense vector
364  reset( ~lhs );
365 
366  // Evaluation of the left-hand side sparse vector operand
367  LT x( serial( rhs.vec_ ) );
368  if( x.nonZeros() == 0UL ) return;
369 
370  // Evaluation of the right-hand side sparse matrix operand
371  RT A( serial( rhs.mat_ ) );
372 
373  // Checking the evaluated operands
374  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
375  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
376  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
377  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
378 
379  // Performing the sparse vector-sparse matrix multiplication
380  TSVecTSMatMultExpr::selectAssignKernel( ~lhs, x, A );
381  }
383  //**********************************************************************************************
384 
385  //**Default assignment to dense vectors*********************************************************
399  template< typename VT1 // Type of the left-hand side target vector
400  , typename VT2 // Type of the left-hand side vector operand
401  , typename MT1 > // Type of the right-hand side matrix operand
402  static inline void selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
403  {
404  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
405  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
406 
407  const VectorIterator vend( x.end() );
408 
409  for( size_t j=0UL; j<A.columns(); ++j )
410  {
411  const MatrixIterator mend ( A.end(j) );
412  MatrixIterator melem( A.begin(j) );
413 
414  if( melem == mend ) continue;
415 
416  VectorIterator velem( x.begin() );
417 
418  while( true ) {
419  if( velem->index() < melem->index() ) {
420  ++velem;
421  if( velem == vend ) break;
422  }
423  else if( melem->index() < velem->index() ) {
424  ++melem;
425  if( melem == mend ) break;
426  }
427  else {
428  y[j] = velem->value() * melem->value();
429  ++velem;
430  ++melem;
431  break;
432  }
433  }
434 
435  if( velem != vend && melem != mend )
436  {
437  while( true ) {
438  if( velem->index() < melem->index() ) {
439  ++velem;
440  if( velem == vend ) break;
441  }
442  else if( melem->index() < velem->index() ) {
443  ++melem;
444  if( melem == mend ) break;
445  }
446  else {
447  y[j] += velem->value() * melem->value();
448  ++velem;
449  if( velem == vend ) break;
450  ++melem;
451  if( melem == mend ) break;
452  }
453  }
454  }
455  }
456  }
458  //**********************************************************************************************
459 
460  //**Assignment to sparse vectors****************************************************************
473  template< typename VT1 > // Type of the target sparse vector
474  friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
475  {
477 
478  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
479 
480  typedef typename RemoveReference<LT>::Type::ConstIterator VectorIterator;
481  typedef typename RemoveReference<RT>::Type::ConstIterator MatrixIterator;
482 
483  // Evaluation of the left-hand side sparse vector operand
484  LT x( serial( rhs.vec_ ) );
485  if( x.nonZeros() == 0UL ) return;
486 
487  // Evaluation of the right-hand side sparse matrix operand
488  RT A( serial( rhs.mat_ ) );
489 
490  // Checking the evaluated operands
491  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
492  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
493  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
494  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
495 
496  // Performing the sparse vector-sparse matrix multiplication
497  ElementType accu;
498  const VectorIterator vend( x.end() );
499 
500  for( size_t j=0UL; j<A.columns(); ++j )
501  {
502  const MatrixIterator mend ( A.end(j) );
503  MatrixIterator melem( A.begin(j) );
504 
505  if( melem == mend ) continue;
506 
507  VectorIterator velem( x.begin() );
508 
509  reset( accu );
510 
511  while( true ) {
512  if( velem->index() < melem->index() ) {
513  ++velem;
514  if( velem == vend ) break;
515  }
516  else if( melem->index() < velem->index() ) {
517  ++melem;
518  if( melem == mend ) break;
519  }
520  else {
521  accu = velem->value() * melem->value();
522  ++velem;
523  ++melem;
524  break;
525  }
526  }
527 
528  if( velem != vend && melem != mend )
529  {
530  while( true ) {
531  if( velem->index() < melem->index() ) {
532  ++velem;
533  if( velem == vend ) break;
534  }
535  else if( melem->index() < velem->index() ) {
536  ++melem;
537  if( melem == mend ) break;
538  }
539  else {
540  accu += velem->value() * melem->value();
541  ++velem;
542  if( velem == vend ) break;
543  ++melem;
544  if( melem == mend ) break;
545  }
546  }
547  }
548 
549  if( !isDefault( accu ) )
550  (~lhs).insert( j, accu );
551  }
552  }
554  //**********************************************************************************************
555 
556  //**Addition assignment to dense vectors********************************************************
569  template< typename VT1 > // Type of the target dense vector
570  friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
571  {
573 
574  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
575 
576  // Evaluation of the left-hand side sparse vector operand
577  LT x( serial( rhs.vec_ ) );
578  if( x.nonZeros() == 0UL ) return;
579 
580  // Evaluation of the right-hand side sparse matrix operand
581  RT A( serial( rhs.mat_ ) );
582 
583  // Checking the evaluated operands
584  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
585  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
586  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
587  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
588 
589  // Performing the sparse matrix-sparse vector multiplication
590  TSVecTSMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
591  }
593  //**********************************************************************************************
594 
595  //**Default addition assignment to dense vectors************************************************
609  template< typename VT1 // Type of the left-hand side target vector
610  , typename VT2 // Type of the left-hand side vector operand
611  , typename MT1 > // Type of the right-hand side matrix operand
612  static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
613  {
614  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
615  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
616 
617  const VectorIterator vend( x.end() );
618 
619  for( size_t j=0UL; j<A.columns(); ++j )
620  {
621  const MatrixIterator mend ( A.end(j) );
622  MatrixIterator melem( A.begin(j) );
623 
624  if( melem == mend ) continue;
625 
626  VectorIterator velem( x.begin() );
627 
628  while( true ) {
629  if( velem->index() < melem->index() ) {
630  ++velem;
631  if( velem == vend ) break;
632  }
633  else if( melem->index() < velem->index() ) {
634  ++melem;
635  if( melem == mend ) break;
636  }
637  else {
638  y[j] += velem->value() * melem->value();
639  ++velem;
640  if( velem == vend ) break;
641  ++melem;
642  if( melem == mend ) break;
643  }
644  }
645  }
646  }
648  //**********************************************************************************************
649 
650  //**Addition assignment to sparse vectors*******************************************************
651  // No special implementation for the addition assignment to sparse vectors.
652  //**********************************************************************************************
653 
654  //**Subtraction assignment to dense vectors*****************************************************
667  template< typename VT1 > // Type of the target dense vector
668  friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
669  {
671 
672  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
673 
674  // Evaluation of the left-hand side sparse vector operand
675  LT x( serial( rhs.vec_ ) );
676  if( x.nonZeros() == 0UL ) return;
677 
678  // Evaluation of the right-hand side sparse matrix operand
679  RT A( serial( rhs.mat_ ) );
680 
681  // Checking the evaluated operands
682  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
683  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
684  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
685  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
686 
687  // Performing the sparse matrix-sparse vector multiplication
688  TSVecTSMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
689  }
691  //**********************************************************************************************
692 
693  //**Default subtraction assignment to dense vectors*********************************************
707  template< typename VT1 // Type of the left-hand side target vector
708  , typename VT2 // Type of the left-hand side vector operand
709  , typename MT1 > // Type of the right-hand side matrix operand
710  static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
711  {
712  typedef typename RemoveReference<VT2>::Type::ConstIterator VectorIterator;
713  typedef typename RemoveReference<MT1>::Type::ConstIterator MatrixIterator;
714 
715  const VectorIterator vend( x.end() );
716 
717  for( size_t j=0UL; j<A.columns(); ++j )
718  {
719  const MatrixIterator mend ( A.end(j) );
720  MatrixIterator melem( A.begin(j) );
721 
722  if( melem == mend ) continue;
723 
724  VectorIterator velem( x.begin() );
725 
726  while( true ) {
727  if( velem->index() < melem->index() ) {
728  ++velem;
729  if( velem == vend ) break;
730  }
731  else if( melem->index() < velem->index() ) {
732  ++melem;
733  if( melem == mend ) break;
734  }
735  else {
736  y[j] -= velem->value() * melem->value();
737  ++velem;
738  if( velem == vend ) break;
739  ++melem;
740  if( melem == mend ) break;
741  }
742  }
743  }
744  }
746  //**********************************************************************************************
747 
748  //**Subtraction assignment to sparse vectors****************************************************
749  // No special implementation for the subtraction assignment to sparse vectors.
750  //**********************************************************************************************
751 
752  //**Multiplication assignment to dense vectors**************************************************
765  template< typename VT1 > // Type of the target dense vector
766  friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
767  {
769 
773 
774  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
775 
776  const ResultType tmp( serial( rhs ) );
777  multAssign( ~lhs, tmp );
778  }
780  //**********************************************************************************************
781 
782  //**Multiplication assignment to sparse vectors*************************************************
783  // No special implementation for the multiplication assignment to sparse vectors.
784  //**********************************************************************************************
785 
786  //**SMP assignment to dense vectors*************************************************************
801  template< typename VT1 > // Type of the target dense vector
802  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
803  smpAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
804  {
806 
807  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
808 
809  // Resetting the left-hand side target dense vector
810  reset( ~lhs );
811 
812  // Evaluation of the left-hand side sparse vector operand
813  LT x( rhs.vec_ );
814  if( x.nonZeros() == 0UL ) return;
815 
816  // Evaluation of the right-hand side sparse matrix operand
817  RT A( rhs.mat_ );
818 
819  // Checking the evaluated operands
820  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
821  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
822  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
823  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
824 
825  // Performing the sparse vector-sparse matrix multiplication
826  smpAssign( ~lhs, x * A );
827  }
829  //**********************************************************************************************
830 
831  //**SMP assignment to sparse vectors************************************************************
832  // No special implementation for the SMP assignment to sparse vectors.
833  //**********************************************************************************************
834 
835  //**SMP addition assignment to dense vectors****************************************************
850  template< typename VT1 > // Type of the target dense vector
851  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
852  smpAddAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
853  {
855 
856  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
857 
858  // Evaluation of the left-hand side sparse vector operand
859  LT x( rhs.vec_ );
860  if( x.nonZeros() == 0UL ) return;
861 
862  // Evaluation of the right-hand side sparse matrix operand
863  RT A( rhs.mat_ );
864 
865  // Checking the evaluated operands
866  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
867  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
868  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
869  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
870 
871  // Performing the sparse matrix-sparse vector multiplication
872  smpAddAssign( ~lhs, x * A );
873  }
875  //**********************************************************************************************
876 
877  //**SMP addition assignment to sparse vectors***************************************************
878  // No special implementation for the SMP addition assignment to sparse vectors.
879  //**********************************************************************************************
880 
881  //**SMP subtraction assignment to dense vectors*************************************************
896  template< typename VT1 > // Type of the target dense vector
897  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
898  smpSubAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
899  {
901 
902  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
903 
904  // Evaluation of the left-hand side sparse vector operand
905  LT x( rhs.vec_ );
906  if( x.nonZeros() == 0UL ) return;
907 
908  // Evaluation of the right-hand side sparse matrix operand
909  RT A( rhs.mat_ );
910 
911  // Checking the evaluated operands
912  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
913  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
914  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
915  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
916 
917  // Performing the sparse matrix-sparse vector multiplication
918  smpSubAssign( ~lhs, x * A );
919  }
921  //**********************************************************************************************
922 
923  //**SMP subtraction assignment to sparse vectors************************************************
924  // No special implementation for the SMP subtraction assignment to sparse vectors.
925  //**********************************************************************************************
926 
927  //**SMP multiplication assignment to dense vectors**********************************************
942  template< typename VT1 > // Type of the target dense vector
943  friend inline typename EnableIf< UseSMPAssign<VT1> >::Type
944  smpMultAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
945  {
947 
951 
952  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
953 
954  const ResultType tmp( rhs );
955  smpMultAssign( ~lhs, tmp );
956  }
958  //**********************************************************************************************
959 
960  //**SMP multiplication assignment to sparse vectors*********************************************
961  // No special implementation for the SMP multiplication assignment to sparse vectors.
962  //**********************************************************************************************
963 
964  //**Compile time checks*************************************************************************
973  //**********************************************************************************************
974 };
975 //*************************************************************************************************
976 
977 
978 
979 
980 //=================================================================================================
981 //
982 // GLOBAL BINARY ARITHMETIC OPERATORS
983 //
984 //=================================================================================================
985 
986 //*************************************************************************************************
1017 template< typename T1 // Type of the left-hand side sparse vector
1018  , typename T2 > // Type of the right-hand side sparse matrix
1019 inline const typename DisableIf< Or< IsSymmetric<T2>, IsMatMatMultExpr<T2> >
1020  , TSVecTSMatMultExpr<T1,T2> >::Type
1022 {
1024 
1025  if( (~vec).size() != (~mat).rows() ) {
1026  BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
1027  }
1028 
1029  return TSVecTSMatMultExpr<T1,T2>( ~vec, ~mat );
1030 }
1031 //*************************************************************************************************
1032 
1033 
1034 
1035 
1036 //=================================================================================================
1037 //
1038 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
1039 //
1040 //=================================================================================================
1041 
1042 //*************************************************************************************************
1057 template< typename T1 // Type of the left-hand side sparse vector
1058  , typename T2 > // Type of the right-hand side sparse matrix
1059 inline const typename EnableIf< IsSymmetric<T2>, typename MultExprTrait<T1,T2>::Type >::Type
1060  operator*( const SparseVector<T1,true>& vec, const SparseMatrix<T2,true>& mat )
1061 {
1063 
1065 
1066  if( (~vec).size() != (~mat).rows() ) {
1067  BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
1068  }
1069 
1070  return (~vec) * trans( ~mat );
1071 }
1073 //*************************************************************************************************
1074 
1075 
1076 
1077 
1078 //=================================================================================================
1079 //
1080 // SIZE SPECIALIZATIONS
1081 //
1082 //=================================================================================================
1083 
1084 //*************************************************************************************************
1086 template< typename VT, typename MT >
1087 struct Size< TSVecTSMatMultExpr<VT,MT> > : public Columns<MT>
1088 {};
1090 //*************************************************************************************************
1091 
1092 
1093 
1094 
1095 //=================================================================================================
1096 //
1097 // EXPRESSION TRAIT SPECIALIZATIONS
1098 //
1099 //=================================================================================================
1100 
1101 //*************************************************************************************************
1103 template< typename VT, typename MT, bool AF >
1104 struct SubvectorExprTrait< TSVecTSMatMultExpr<VT,MT>, AF >
1105 {
1106  public:
1107  //**********************************************************************************************
1108  typedef typename MultExprTrait< typename SubvectorExprTrait<const VT,AF>::Type
1109  , typename SubmatrixExprTrait<const MT,AF>::Type >::Type Type;
1110  //**********************************************************************************************
1111 };
1113 //*************************************************************************************************
1114 
1115 } // namespace blaze
1116 
1117 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:310
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
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:7820
Header file for basic type definitions.
MT::CompositeType MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:103
Header file for the SparseVector base class.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:332
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:133
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:135
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
ResultType::ElementType ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:134
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:259
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
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:278
Header file for the RequiresEvaluation type trait.
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
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
MT::ResultType MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:101
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:261
TSVecTSMatMultExpr(const VT &vec, const MT &mat)
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:163
RightOperand mat_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:340
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.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#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:79
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
Expression object for sparse vector-sparse matrix multiplications.The TSVecTSMatMultExpr class repres...
Definition: Forward.h:163
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 exceptionThis macro encapsulates the default way of Bla...
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:339
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
MultTrait< VRT, MRT >::Type ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:132
#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
SelectType< evaluateMatrix, const MRT, MCT >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:148
#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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecTSMatMultExpr.h:136
Header file for the SelectType class template.
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:131
Header file for the EnableIf class template.
Header file for the serial shim.
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
#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:116
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:138
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TSVecTSMatMultExpr.h:322
Header file for the reset shim.
Constraint on the data type.
SelectType< IsExpression< MT >::value, const MT, const MT & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:142
Header file for the isDefault shim.
Header file for the TVecMatMultExpr base class.
Constraints on the storage order of matrix types.
Header file for the RemoveReference type trait.
SelectType< evaluateVector, const VRT, VCT >::Type LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:145
#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
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:288
VT::CompositeType VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:102
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
Header file for the IsComputation type trait class.
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
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:118
#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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
#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:79
Header file for exception macros.
SelectType< IsExpression< VT >::value, const VT, const VT & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:139
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.
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: TSVecTSMatMultExpr.h:255
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:79
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:177
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
size_t size() const
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:268
Header file for the FunctionTrace class.
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:298
VT::ResultType VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:100