TSVecTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSVECTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSVECTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
58 #include <blaze/math/shims/Reset.h>
68 #include <blaze/util/Assert.h>
69 #include <blaze/util/DisableIf.h>
70 #include <blaze/util/EnableIf.h>
72 #include <blaze/util/mpl/If.h>
73 #include <blaze/util/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
95  : public TVecMatMultExpr< SparseVector< TSVecTSMatMultExpr<VT,MT>, true > >
96  , private Computation
97 {
98  private:
99  //**Type definitions****************************************************************************
104  //**********************************************************************************************
105 
106  //**********************************************************************************************
108  enum : bool { evaluateVector = IsComputation<VT>::value };
109  //**********************************************************************************************
110 
111  //**********************************************************************************************
113  enum : bool { evaluateMatrix = RequiresEvaluation<MT>::value };
114  //**********************************************************************************************
115 
116  //**********************************************************************************************
118 
122  template< typename T1 >
123  struct UseSMPAssign {
124  enum : bool { value = ( evaluateVector || evaluateMatrix ) };
125  };
127  //**********************************************************************************************
128 
129  public:
130  //**Type definitions****************************************************************************
135  using ReturnType = const ElementType;
136  using CompositeType = const ResultType;
137 
139  using LeftOperand = If_< IsExpression<VT>, const VT, const VT& >;
140 
142  using RightOperand = If_< IsExpression<MT>, const MT, const MT& >;
143 
146 
149  //**********************************************************************************************
150 
151  //**Compilation flags***************************************************************************
153  enum : bool { smpAssignable = !evaluateVector && VT::smpAssignable &&
154  !evaluateMatrix && MT::smpAssignable };
155  //**********************************************************************************************
156 
157  //**Constructor*********************************************************************************
163  explicit inline TSVecTSMatMultExpr( const VT& vec, const MT& mat ) noexcept
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  return vec_ * column( mat_, index );
180  }
181  //**********************************************************************************************
182 
183  //**At function*********************************************************************************
190  inline ReturnType at( size_t index ) const {
191  if( index >= mat_.columns() ) {
192  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
193  }
194  return (*this)[index];
195  }
196  //**********************************************************************************************
197 
198  //**Size function*******************************************************************************
203  inline size_t size() const noexcept {
204  return mat_.columns();
205  }
206  //**********************************************************************************************
207 
208  //**NonZeros function***************************************************************************
213  inline size_t nonZeros() const {
214  return mat_.columns();
215  }
216  //**********************************************************************************************
217 
218  //**Left operand access*************************************************************************
223  inline LeftOperand leftOperand() const noexcept {
224  return vec_;
225  }
226  //**********************************************************************************************
227 
228  //**Right operand access************************************************************************
233  inline RightOperand rightOperand() const noexcept {
234  return mat_;
235  }
236  //**********************************************************************************************
237 
238  //**********************************************************************************************
244  template< typename T >
245  inline bool canAlias( const T* alias ) const noexcept {
246  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
247  }
248  //**********************************************************************************************
249 
250  //**********************************************************************************************
256  template< typename T >
257  inline bool isAliased( const T* alias ) const noexcept {
258  return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
259  }
260  //**********************************************************************************************
261 
262  //**********************************************************************************************
267  inline bool canSMPAssign() const noexcept {
268  return ( size() > SMP_TSVECSMATMULT_THRESHOLD );
269  }
270  //**********************************************************************************************
271 
272  private:
273  //**Member variables****************************************************************************
276  //**********************************************************************************************
277 
278  //**Assignment to dense vectors*****************************************************************
291  template< typename VT1 > // Type of the target dense vector
292  friend inline void assign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
293  {
295 
296  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
297 
298  // Resetting the left-hand side target dense vector
299  reset( ~lhs );
300 
301  // Evaluation of the left-hand side sparse vector operand
302  LT x( serial( rhs.vec_ ) );
303  if( x.nonZeros() == 0UL ) return;
304 
305  // Evaluation of the right-hand side sparse matrix operand
306  RT A( serial( rhs.mat_ ) );
307 
308  // Checking the evaluated operands
309  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
310  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
311  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
312  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
313 
314  // Performing the sparse vector-sparse matrix multiplication
315  TSVecTSMatMultExpr::selectAssignKernel( ~lhs, x, A );
316  }
318  //**********************************************************************************************
319 
320  //**Default assignment to dense vectors*********************************************************
334  template< typename VT1 // Type of the left-hand side target vector
335  , typename VT2 // Type of the left-hand side vector operand
336  , typename MT1 > // Type of the right-hand side matrix operand
337  static inline void selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
338  {
339  using VectorIterator = ConstIterator_< RemoveReference_<VT2> >;
340  using MatrixIterator = ConstIterator_< RemoveReference_<MT1> >;
341 
342  const VectorIterator vend( x.end() );
343 
344  for( size_t j=0UL; j<A.columns(); ++j )
345  {
346  const MatrixIterator mend ( A.end(j) );
347  MatrixIterator melem( A.begin(j) );
348 
349  if( melem == mend ) continue;
350 
351  VectorIterator velem( x.begin() );
352 
353  while( true ) {
354  if( velem->index() < melem->index() ) {
355  ++velem;
356  if( velem == vend ) break;
357  }
358  else if( melem->index() < velem->index() ) {
359  ++melem;
360  if( melem == mend ) break;
361  }
362  else {
363  y[j] = velem->value() * melem->value();
364  ++velem;
365  ++melem;
366  break;
367  }
368  }
369 
370  if( velem != vend && melem != mend )
371  {
372  while( true ) {
373  if( velem->index() < melem->index() ) {
374  ++velem;
375  if( velem == vend ) break;
376  }
377  else if( melem->index() < velem->index() ) {
378  ++melem;
379  if( melem == mend ) break;
380  }
381  else {
382  y[j] += velem->value() * melem->value();
383  ++velem;
384  if( velem == vend ) break;
385  ++melem;
386  if( melem == mend ) break;
387  }
388  }
389  }
390  }
391  }
393  //**********************************************************************************************
394 
395  //**Assignment to sparse vectors****************************************************************
408  template< typename VT1 > // Type of the target sparse vector
409  friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
410  {
412 
413  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
414 
415  using VectorIterator = ConstIterator_< RemoveReference_<LT> >;
416  using MatrixIterator = ConstIterator_< RemoveReference_<RT> >;
417 
418  // Evaluation of the left-hand side sparse vector operand
419  LT x( serial( rhs.vec_ ) );
420  if( x.nonZeros() == 0UL ) return;
421 
422  // Evaluation of the right-hand side sparse matrix operand
423  RT A( serial( rhs.mat_ ) );
424 
425  // Checking the evaluated operands
426  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
427  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
428  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
429  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
430 
431  // Performing the sparse vector-sparse matrix multiplication
432  ElementType accu;
433  const VectorIterator vend( x.end() );
434 
435  for( size_t j=0UL; j<A.columns(); ++j )
436  {
437  const MatrixIterator mend ( A.end(j) );
438  MatrixIterator melem( A.begin(j) );
439 
440  if( melem == mend ) continue;
441 
442  VectorIterator velem( x.begin() );
443 
444  reset( accu );
445 
446  while( true ) {
447  if( velem->index() < melem->index() ) {
448  ++velem;
449  if( velem == vend ) break;
450  }
451  else if( melem->index() < velem->index() ) {
452  ++melem;
453  if( melem == mend ) break;
454  }
455  else {
456  accu = velem->value() * melem->value();
457  ++velem;
458  ++melem;
459  break;
460  }
461  }
462 
463  if( velem != vend && melem != mend )
464  {
465  while( true ) {
466  if( velem->index() < melem->index() ) {
467  ++velem;
468  if( velem == vend ) break;
469  }
470  else if( melem->index() < velem->index() ) {
471  ++melem;
472  if( melem == mend ) break;
473  }
474  else {
475  accu += velem->value() * melem->value();
476  ++velem;
477  if( velem == vend ) break;
478  ++melem;
479  if( melem == mend ) break;
480  }
481  }
482  }
483 
484  if( !isDefault( accu ) )
485  (~lhs).insert( j, accu );
486  }
487  }
489  //**********************************************************************************************
490 
491  //**Addition assignment to dense vectors********************************************************
504  template< typename VT1 > // Type of the target dense vector
505  friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
506  {
508 
509  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
510 
511  // Evaluation of the left-hand side sparse vector operand
512  LT x( serial( rhs.vec_ ) );
513  if( x.nonZeros() == 0UL ) return;
514 
515  // Evaluation of the right-hand side sparse matrix operand
516  RT A( serial( rhs.mat_ ) );
517 
518  // Checking the evaluated operands
519  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
520  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
521  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
522  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
523 
524  // Performing the sparse matrix-sparse vector multiplication
525  TSVecTSMatMultExpr::selectAddAssignKernel( ~lhs, x, A );
526  }
528  //**********************************************************************************************
529 
530  //**Default addition assignment to dense vectors************************************************
544  template< typename VT1 // Type of the left-hand side target vector
545  , typename VT2 // Type of the left-hand side vector operand
546  , typename MT1 > // Type of the right-hand side matrix operand
547  static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
548  {
549  using VectorIterator = ConstIterator_< RemoveReference_<VT2> >;
550  using MatrixIterator = ConstIterator_< RemoveReference_<MT1> >;
551 
552  const VectorIterator vend( x.end() );
553 
554  for( size_t j=0UL; j<A.columns(); ++j )
555  {
556  const MatrixIterator mend ( A.end(j) );
557  MatrixIterator melem( A.begin(j) );
558 
559  if( melem == mend ) continue;
560 
561  VectorIterator velem( x.begin() );
562 
563  while( true ) {
564  if( velem->index() < melem->index() ) {
565  ++velem;
566  if( velem == vend ) break;
567  }
568  else if( melem->index() < velem->index() ) {
569  ++melem;
570  if( melem == mend ) break;
571  }
572  else {
573  y[j] += velem->value() * melem->value();
574  ++velem;
575  if( velem == vend ) break;
576  ++melem;
577  if( melem == mend ) break;
578  }
579  }
580  }
581  }
583  //**********************************************************************************************
584 
585  //**Addition assignment to sparse vectors*******************************************************
586  // No special implementation for the addition assignment to sparse vectors.
587  //**********************************************************************************************
588 
589  //**Subtraction assignment to dense vectors*****************************************************
602  template< typename VT1 > // Type of the target dense vector
603  friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
604  {
606 
607  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
608 
609  // Evaluation of the left-hand side sparse vector operand
610  LT x( serial( rhs.vec_ ) );
611  if( x.nonZeros() == 0UL ) return;
612 
613  // Evaluation of the right-hand side sparse matrix operand
614  RT A( serial( rhs.mat_ ) );
615 
616  // Checking the evaluated operands
617  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
618  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
619  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
620  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
621 
622  // Performing the sparse matrix-sparse vector multiplication
623  TSVecTSMatMultExpr::selectSubAssignKernel( ~lhs, x, A );
624  }
626  //**********************************************************************************************
627 
628  //**Default subtraction assignment to dense vectors*********************************************
642  template< typename VT1 // Type of the left-hand side target vector
643  , typename VT2 // Type of the left-hand side vector operand
644  , typename MT1 > // Type of the right-hand side matrix operand
645  static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
646  {
647  using VectorIterator = ConstIterator_< RemoveReference_<VT2> >;
648  using MatrixIterator = ConstIterator_< RemoveReference_<MT1> >;
649 
650  const VectorIterator vend( x.end() );
651 
652  for( size_t j=0UL; j<A.columns(); ++j )
653  {
654  const MatrixIterator mend ( A.end(j) );
655  MatrixIterator melem( A.begin(j) );
656 
657  if( melem == mend ) continue;
658 
659  VectorIterator velem( x.begin() );
660 
661  while( true ) {
662  if( velem->index() < melem->index() ) {
663  ++velem;
664  if( velem == vend ) break;
665  }
666  else if( melem->index() < velem->index() ) {
667  ++melem;
668  if( melem == mend ) break;
669  }
670  else {
671  y[j] -= velem->value() * melem->value();
672  ++velem;
673  if( velem == vend ) break;
674  ++melem;
675  if( melem == mend ) break;
676  }
677  }
678  }
679  }
681  //**********************************************************************************************
682 
683  //**Subtraction assignment to sparse vectors****************************************************
684  // No special implementation for the subtraction assignment to sparse vectors.
685  //**********************************************************************************************
686 
687  //**Multiplication assignment to dense vectors**************************************************
700  template< typename VT1 > // Type of the target dense vector
701  friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
702  {
704 
708 
709  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
710 
711  const ResultType tmp( serial( rhs ) );
712  multAssign( ~lhs, tmp );
713  }
715  //**********************************************************************************************
716 
717  //**Multiplication assignment to sparse vectors*************************************************
718  // No special implementation for the multiplication assignment to sparse vectors.
719  //**********************************************************************************************
720 
721  //**SMP assignment to dense vectors*************************************************************
736  template< typename VT1 > // Type of the target dense vector
737  friend inline EnableIf_< UseSMPAssign<VT1> >
739  {
741 
742  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
743 
744  // Resetting the left-hand side target dense vector
745  reset( ~lhs );
746 
747  // Evaluation of the left-hand side sparse vector operand
748  LT x( rhs.vec_ );
749  if( x.nonZeros() == 0UL ) return;
750 
751  // Evaluation of the right-hand side sparse matrix operand
752  RT A( rhs.mat_ );
753 
754  // Checking the evaluated operands
755  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
756  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
757  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
758  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
759 
760  // Performing the sparse vector-sparse matrix multiplication
761  smpAssign( ~lhs, x * A );
762  }
764  //**********************************************************************************************
765 
766  //**SMP assignment to sparse vectors************************************************************
767  // No special implementation for the SMP assignment to sparse vectors.
768  //**********************************************************************************************
769 
770  //**SMP addition assignment to dense vectors****************************************************
785  template< typename VT1 > // Type of the target dense vector
786  friend inline EnableIf_< UseSMPAssign<VT1> >
788  {
790 
791  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
792 
793  // Evaluation of the left-hand side sparse vector operand
794  LT x( rhs.vec_ );
795  if( x.nonZeros() == 0UL ) return;
796 
797  // Evaluation of the right-hand side sparse matrix operand
798  RT A( rhs.mat_ );
799 
800  // Checking the evaluated operands
801  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
802  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
803  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
804  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
805 
806  // Performing the sparse matrix-sparse vector multiplication
807  smpAddAssign( ~lhs, x * A );
808  }
810  //**********************************************************************************************
811 
812  //**SMP addition assignment to sparse vectors***************************************************
813  // No special implementation for the SMP addition assignment to sparse vectors.
814  //**********************************************************************************************
815 
816  //**SMP subtraction assignment to dense vectors*************************************************
831  template< typename VT1 > // Type of the target dense vector
832  friend inline EnableIf_< UseSMPAssign<VT1> >
834  {
836 
837  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
838 
839  // Evaluation of the left-hand side sparse vector operand
840  LT x( rhs.vec_ );
841  if( x.nonZeros() == 0UL ) return;
842 
843  // Evaluation of the right-hand side sparse matrix operand
844  RT A( rhs.mat_ );
845 
846  // Checking the evaluated operands
847  BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
848  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
849  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
850  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).size() , "Invalid vector size" );
851 
852  // Performing the sparse matrix-sparse vector multiplication
853  smpSubAssign( ~lhs, x * A );
854  }
856  //**********************************************************************************************
857 
858  //**SMP subtraction assignment to sparse vectors************************************************
859  // No special implementation for the SMP subtraction assignment to sparse vectors.
860  //**********************************************************************************************
861 
862  //**SMP multiplication assignment to dense vectors**********************************************
877  template< typename VT1 > // Type of the target dense vector
878  friend inline EnableIf_< UseSMPAssign<VT1> >
880  {
882 
886 
887  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
888 
889  const ResultType tmp( rhs );
890  smpMultAssign( ~lhs, tmp );
891  }
893  //**********************************************************************************************
894 
895  //**SMP multiplication assignment to sparse vectors*********************************************
896  // No special implementation for the SMP multiplication assignment to sparse vectors.
897  //**********************************************************************************************
898 
899  //**Compile time checks*************************************************************************
908  //**********************************************************************************************
909 };
910 //*************************************************************************************************
911 
912 
913 
914 
915 //=================================================================================================
916 //
917 // GLOBAL BINARY ARITHMETIC OPERATORS
918 //
919 //=================================================================================================
920 
921 //*************************************************************************************************
935 template< typename VT // Type of the left-hand side sparse vector
936  , typename MT // Type of the right-hand side sparse matrix
937  , typename = DisableIf_< IsSymmetric<MT> > >
938 inline const TSVecTSMatMultExpr<VT,MT>
939  tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
940 {
942 
943  BLAZE_INTERNAL_ASSERT( (~vec).size() == (~mat).rows(), "Invalid vector and matrix sizes" );
944 
945  return TSVecTSMatMultExpr<VT,MT>( ~vec, ~mat );
946 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
965 template< typename VT // Type of the left-hand side sparse vector
966  , typename MT // Type of the right-hand side sparse matrix
967  , typename = EnableIf_< IsSymmetric<MT> > >
968 inline decltype(auto)
969  tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
970 {
972 
973  BLAZE_INTERNAL_ASSERT( (~vec).size() == (~mat).rows(), "Invalid vector and matrix sizes" );
974 
975  return (~vec) * trans( ~mat );
976 }
978 //*************************************************************************************************
979 
980 
981 //*************************************************************************************************
1012 template< typename VT // Type of the left-hand side sparse vector
1013  , typename MT > // Type of the right-hand side sparse matrix
1014 inline decltype(auto)
1015  operator*( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
1016 {
1018 
1020 
1021  if( (~vec).size() != (~mat).rows() ) {
1022  BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
1023  }
1024 
1025  return tsvectsmatmult( ~vec, ~mat );
1026 }
1027 //*************************************************************************************************
1028 
1029 
1030 
1031 
1032 //=================================================================================================
1033 //
1034 // SIZE SPECIALIZATIONS
1035 //
1036 //=================================================================================================
1037 
1038 //*************************************************************************************************
1040 template< typename VT, typename MT >
1041 struct Size< TSVecTSMatMultExpr<VT,MT> >
1042  : public Columns<MT>
1043 {};
1045 //*************************************************************************************************
1046 
1047 } // namespace blaze
1048 
1049 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
size_t nonZeros() const
Returns an estimation for the number of non-zero elements in the sparse vector.
Definition: TSVecTSMatMultExpr.h:213
Header file for auxiliary alias declarations.
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:72
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:135
Header file for basic type definitions.
Header file for the SparseVector base class.
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the serial shim.
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:267
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:250
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
Header file for the Computation base class.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:233
Header file for the RequiresEvaluation type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
If_< IsExpression< VT >, const VT, const VT &> LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:139
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:133
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSVecTSMatMultExpr.h:257
Constraint on the data type.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:72
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
IfTrue_< evaluateMatrix, const MRT, MCT > RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:148
RightOperand mat_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:275
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
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
Expression object for sparse vector-sparse matrix multiplications.The TSVecTSMatMultExpr class repres...
Definition: Forward.h:176
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the Columns type trait.
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:274
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:61
CompositeType_< MT > MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:103
#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:88
ResultType_< MT > MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:101
Header file for the exception macros of the math module.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:245
CompositeType_< VT > VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:102
Constraint on the data type.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the EnableIf class template.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
Header file for run time assertion macros.
If_< IsExpression< MT >, const MT, const MT &> 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_< VT > VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:100
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
Header file for the reset shim.
Constraint on the data type.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:223
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for the isDefault shim.
Header file for the TVecMatMultExpr base class.
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
IfTrue_< evaluateVector, const VRT, VCT > LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:145
Header file for the RemoveReference type trait.
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:177
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_TVECMATMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/matrix ...
Definition: TVecMatMultExpr.h:109
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
MultTrait_< VRT, MRT > ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:132
Header file for the IsComputation type trait class.
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:203
Compile time evaluation of the size of a vector.The Size type trait evaluates the size of the given v...
Definition: Size.h:74
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:130
Compile time evaluation of the number of columns of a matrix.The Columns type trait evaluates the num...
Definition: Columns.h:75
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
TSVecTSMatMultExpr(const VT &vec, const MT &mat) noexcept
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:163
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
Constraint on the data type.
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
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: TSVecTSMatMultExpr.h:190
ElementType_< ResultType > ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:134
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.