Blaze 3.9
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>
71#include <blaze/util/Assert.h>
72#include <blaze/util/EnableIf.h>
75#include <blaze/util/mpl/If.h>
76#include <blaze/util/Types.h>
77
78
79namespace blaze {
80
81//=================================================================================================
82//
83// CLASS TSVECTSMATMULTEXPR
84//
85//=================================================================================================
86
87//*************************************************************************************************
94template< typename VT // Type of the left-hand side sparse vector
95 , typename MT > // Type of the right-hand side sparse matrix
97 : public TVecMatMultExpr< SparseVector< TSVecTSMatMultExpr<VT,MT>, true > >
98 , private Computation
99{
100 private:
101 //**Type definitions****************************************************************************
106 //**********************************************************************************************
107
108 //**********************************************************************************************
110 static constexpr bool evaluateVector = IsComputation_v<VT>;
111 //**********************************************************************************************
112
113 //**********************************************************************************************
115 static constexpr bool evaluateMatrix = RequiresEvaluation_v<MT>;
116 //**********************************************************************************************
117
118 //**********************************************************************************************
120
124 template< typename T1 >
125 static constexpr bool UseSMPAssign_v = ( evaluateVector || evaluateMatrix );
127 //**********************************************************************************************
128
129 public:
130 //**Type definitions****************************************************************************
133
136
140 using ReturnType = const ElementType;
141 using CompositeType = const ResultType;
142
144 using LeftOperand = If_t< IsExpression_v<VT>, const VT, const VT& >;
145
147 using RightOperand = If_t< IsExpression_v<MT>, const MT, const MT& >;
148
151
154 //**********************************************************************************************
155
156 //**Compilation flags***************************************************************************
158 static constexpr bool smpAssignable =
159 ( !evaluateVector && VT::smpAssignable && !evaluateMatrix && MT::smpAssignable );
160 //**********************************************************************************************
161
162 //**Constructor*********************************************************************************
168 inline TSVecTSMatMultExpr( const VT& vec, const MT& mat ) noexcept
169 : vec_( vec ) // Left-hand side sparse vector of the multiplication expression
170 , mat_( mat ) // Right-hand side sparse matrix of the multiplication expression
171 {
172 BLAZE_INTERNAL_ASSERT( vec_.size() == mat_.rows(), "Invalid vector and matrix sizes" );
173 }
174 //**********************************************************************************************
175
176 //**Subscript operator**************************************************************************
182 inline ReturnType operator[]( size_t index ) const {
183 BLAZE_INTERNAL_ASSERT( index < mat_.columns(), "Invalid vector access index" );
184 return vec_ * column( mat_, index, unchecked );
185 }
186 //**********************************************************************************************
187
188 //**At function*********************************************************************************
195 inline ReturnType at( size_t index ) const {
196 if( index >= mat_.columns() ) {
197 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
198 }
199 return (*this)[index];
200 }
201 //**********************************************************************************************
202
203 //**Size function*******************************************************************************
208 inline size_t size() const noexcept {
209 return mat_.columns();
210 }
211 //**********************************************************************************************
212
213 //**NonZeros function***************************************************************************
218 inline size_t nonZeros() const {
219 return mat_.columns();
220 }
221 //**********************************************************************************************
222
223 //**Left operand access*************************************************************************
228 inline LeftOperand leftOperand() const noexcept {
229 return vec_;
230 }
231 //**********************************************************************************************
232
233 //**Right operand access************************************************************************
238 inline RightOperand rightOperand() const noexcept {
239 return mat_;
240 }
241 //**********************************************************************************************
242
243 //**********************************************************************************************
249 template< typename T >
250 inline bool canAlias( const T* alias ) const noexcept {
251 return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
252 }
253 //**********************************************************************************************
254
255 //**********************************************************************************************
261 template< typename T >
262 inline bool isAliased( const T* alias ) const noexcept {
263 return ( vec_.isAliased( alias ) || mat_.isAliased( alias ) );
264 }
265 //**********************************************************************************************
266
267 //**********************************************************************************************
272 inline bool canSMPAssign() const noexcept {
273 return ( size() > SMP_TSVECSMATMULT_THRESHOLD );
274 }
275 //**********************************************************************************************
276
277 private:
278 //**Member variables****************************************************************************
281 //**********************************************************************************************
282
283 //**Assignment to dense vectors*****************************************************************
296 template< typename VT1 > // Type of the target dense vector
297 friend inline void assign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
298 {
300
301 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
302
303 // Resetting the left-hand side target dense vector
304 reset( *lhs );
305
306 // Evaluation of the left-hand side sparse vector operand
307 LT x( serial( rhs.vec_ ) );
308 if( x.nonZeros() == 0UL ) return;
309
310 // Evaluation of the right-hand side sparse matrix operand
311 RT A( serial( rhs.mat_ ) );
312
313 // Checking the evaluated operands
314 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
315 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
316 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
317 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
318
319 // Performing the sparse vector-sparse matrix multiplication
320 TSVecTSMatMultExpr::selectAssignKernel( *lhs, x, A );
321 }
323 //**********************************************************************************************
324
325 //**Default assignment to dense vectors*********************************************************
339 template< typename VT1 // Type of the left-hand side target vector
340 , typename VT2 // Type of the left-hand side vector operand
341 , typename MT1 > // Type of the right-hand side matrix operand
342 static inline void selectAssignKernel( VT1& y, const VT2& x, const MT1& A )
343 {
344 const auto vend( x.end() );
345
346 for( size_t j=0UL; j<A.columns(); ++j )
347 {
348 const auto mend ( A.end(j) );
349 auto melem( A.begin(j) );
350
351 if( melem == mend ) continue;
352
353 auto velem( x.begin() );
354
355 while( true ) {
356 if( velem->index() < melem->index() ) {
357 ++velem;
358 if( velem == vend ) break;
359 }
360 else if( melem->index() < velem->index() ) {
361 ++melem;
362 if( melem == mend ) break;
363 }
364 else {
365 y[j] = velem->value() * melem->value();
366 ++velem;
367 ++melem;
368 break;
369 }
370 }
371
372 if( velem != vend && melem != mend )
373 {
374 while( true ) {
375 if( velem->index() < melem->index() ) {
376 ++velem;
377 if( velem == vend ) break;
378 }
379 else if( melem->index() < velem->index() ) {
380 ++melem;
381 if( melem == mend ) break;
382 }
383 else {
384 y[j] += velem->value() * melem->value();
385 ++velem;
386 if( velem == vend ) break;
387 ++melem;
388 if( melem == mend ) break;
389 }
390 }
391 }
392 }
393 }
395 //**********************************************************************************************
396
397 //**Assignment to sparse vectors****************************************************************
410 template< typename VT1 > // Type of the target sparse vector
411 friend inline void assign( SparseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
412 {
414
415 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
416
417 // Evaluation of the left-hand side sparse vector operand
418 LT x( serial( rhs.vec_ ) );
419 if( x.nonZeros() == 0UL ) return;
420
421 // Evaluation of the right-hand side sparse matrix operand
422 RT A( serial( rhs.mat_ ) );
423
424 // Checking the evaluated operands
425 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
426 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
427 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
428 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
429
430 // Performing the sparse vector-sparse matrix multiplication
431 ElementType accu;
432 const auto vend( x.end() );
433
434 for( size_t j=0UL; j<A.columns(); ++j )
435 {
436 const auto mend ( A.end(j) );
437 auto melem( A.begin(j) );
438
439 if( melem == mend ) continue;
440
441 auto velem( x.begin() );
442
443 reset( accu );
444
445 while( true ) {
446 if( velem->index() < melem->index() ) {
447 ++velem;
448 if( velem == vend ) break;
449 }
450 else if( melem->index() < velem->index() ) {
451 ++melem;
452 if( melem == mend ) break;
453 }
454 else {
455 accu = velem->value() * melem->value();
456 ++velem;
457 ++melem;
458 break;
459 }
460 }
461
462 if( velem != vend && melem != mend )
463 {
464 while( true ) {
465 if( velem->index() < melem->index() ) {
466 ++velem;
467 if( velem == vend ) break;
468 }
469 else if( melem->index() < velem->index() ) {
470 ++melem;
471 if( melem == mend ) break;
472 }
473 else {
474 accu += velem->value() * melem->value();
475 ++velem;
476 if( velem == vend ) break;
477 ++melem;
478 if( melem == mend ) break;
479 }
480 }
481 }
482
483 if( !isDefault( accu ) )
484 (*lhs).insert( j, accu );
485 }
486 }
488 //**********************************************************************************************
489
490 //**Addition assignment to dense vectors********************************************************
503 template< typename VT1 > // Type of the target dense vector
504 friend inline void addAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
505 {
507
508 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
509
510 // Evaluation of the left-hand side sparse vector operand
511 LT x( serial( rhs.vec_ ) );
512 if( x.nonZeros() == 0UL ) return;
513
514 // Evaluation of the right-hand side sparse matrix operand
515 RT A( serial( rhs.mat_ ) );
516
517 // Checking the evaluated operands
518 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
519 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
520 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
521 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
522
523 // Performing the sparse matrix-sparse vector multiplication
524 TSVecTSMatMultExpr::selectAddAssignKernel( *lhs, x, A );
525 }
527 //**********************************************************************************************
528
529 //**Default addition assignment to dense vectors************************************************
543 template< typename VT1 // Type of the left-hand side target vector
544 , typename VT2 // Type of the left-hand side vector operand
545 , typename MT1 > // Type of the right-hand side matrix operand
546 static inline void selectAddAssignKernel( VT1& y, const VT2& x, const MT1& A )
547 {
548 const auto vend( x.end() );
549
550 for( size_t j=0UL; j<A.columns(); ++j )
551 {
552 const auto mend ( A.end(j) );
553 auto melem( A.begin(j) );
554
555 if( melem == mend ) continue;
556
557 auto velem( x.begin() );
558
559 while( true ) {
560 if( velem->index() < melem->index() ) {
561 ++velem;
562 if( velem == vend ) break;
563 }
564 else if( melem->index() < velem->index() ) {
565 ++melem;
566 if( melem == mend ) break;
567 }
568 else {
569 y[j] += velem->value() * melem->value();
570 ++velem;
571 if( velem == vend ) break;
572 ++melem;
573 if( melem == mend ) break;
574 }
575 }
576 }
577 }
579 //**********************************************************************************************
580
581 //**Addition assignment to sparse vectors*******************************************************
582 // No special implementation for the addition assignment to sparse vectors.
583 //**********************************************************************************************
584
585 //**Subtraction assignment to dense vectors*****************************************************
598 template< typename VT1 > // Type of the target dense vector
599 friend inline void subAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
600 {
602
603 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
604
605 // Evaluation of the left-hand side sparse vector operand
606 LT x( serial( rhs.vec_ ) );
607 if( x.nonZeros() == 0UL ) return;
608
609 // Evaluation of the right-hand side sparse matrix operand
610 RT A( serial( rhs.mat_ ) );
611
612 // Checking the evaluated operands
613 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
614 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
615 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
616 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
617
618 // Performing the sparse matrix-sparse vector multiplication
619 TSVecTSMatMultExpr::selectSubAssignKernel( *lhs, x, A );
620 }
622 //**********************************************************************************************
623
624 //**Default subtraction assignment to dense vectors*********************************************
638 template< typename VT1 // Type of the left-hand side target vector
639 , typename VT2 // Type of the left-hand side vector operand
640 , typename MT1 > // Type of the right-hand side matrix operand
641 static inline void selectSubAssignKernel( VT1& y, const VT2& x, const MT1& A )
642 {
643 const auto vend( x.end() );
644
645 for( size_t j=0UL; j<A.columns(); ++j )
646 {
647 const auto mend ( A.end(j) );
648 auto melem( A.begin(j) );
649
650 if( melem == mend ) continue;
651
652 auto velem( x.begin() );
653
654 while( true ) {
655 if( velem->index() < melem->index() ) {
656 ++velem;
657 if( velem == vend ) break;
658 }
659 else if( melem->index() < velem->index() ) {
660 ++melem;
661 if( melem == mend ) break;
662 }
663 else {
664 y[j] -= velem->value() * melem->value();
665 ++velem;
666 if( velem == vend ) break;
667 ++melem;
668 if( melem == mend ) break;
669 }
670 }
671 }
672 }
674 //**********************************************************************************************
675
676 //**Subtraction assignment to sparse vectors****************************************************
677 // No special implementation for the subtraction assignment to sparse vectors.
678 //**********************************************************************************************
679
680 //**Multiplication assignment to dense vectors**************************************************
693 template< typename VT1 > // Type of the target dense vector
694 friend inline void multAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
695 {
697
701
702 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
703
704 const ResultType tmp( serial( rhs ) );
705 multAssign( *lhs, tmp );
706 }
708 //**********************************************************************************************
709
710 //**Multiplication assignment to sparse vectors*************************************************
711 // No special implementation for the multiplication assignment to sparse vectors.
712 //**********************************************************************************************
713
714 //**SMP assignment to dense vectors*************************************************************
729 template< typename VT1 > // Type of the target dense vector
730 friend inline auto smpAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
731 -> EnableIf_t< UseSMPAssign_v<VT1> >
732 {
734
735 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
736
737 // Resetting the left-hand side target dense vector
738 reset( *lhs );
739
740 // Evaluation of the left-hand side sparse vector operand
741 LT x( rhs.vec_ );
742 if( x.nonZeros() == 0UL ) return;
743
744 // Evaluation of the right-hand side sparse matrix operand
745 RT A( rhs.mat_ );
746
747 // Checking the evaluated operands
748 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
749 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
750 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
751 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
752
753 // Performing the sparse vector-sparse matrix multiplication
754 smpAssign( *lhs, x * A );
755 }
757 //**********************************************************************************************
758
759 //**SMP assignment to sparse vectors************************************************************
760 // No special implementation for the SMP assignment to sparse vectors.
761 //**********************************************************************************************
762
763 //**SMP addition assignment to dense vectors****************************************************
778 template< typename VT1 > // Type of the target dense vector
779 friend inline auto smpAddAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
780 -> EnableIf_t< UseSMPAssign_v<VT1> >
781 {
783
784 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
785
786 // Evaluation of the left-hand side sparse vector operand
787 LT x( rhs.vec_ );
788 if( x.nonZeros() == 0UL ) return;
789
790 // Evaluation of the right-hand side sparse matrix operand
791 RT A( rhs.mat_ );
792
793 // Checking the evaluated operands
794 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
795 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
796 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
797 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
798
799 // Performing the sparse matrix-sparse vector multiplication
800 smpAddAssign( *lhs, x * A );
801 }
803 //**********************************************************************************************
804
805 //**SMP addition assignment to sparse vectors***************************************************
806 // No special implementation for the SMP addition assignment to sparse vectors.
807 //**********************************************************************************************
808
809 //**SMP subtraction assignment to dense vectors*************************************************
824 template< typename VT1 > // Type of the target dense vector
825 friend inline auto smpSubAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
826 -> EnableIf_t< UseSMPAssign_v<VT1> >
827 {
829
830 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
831
832 // Evaluation of the left-hand side sparse vector operand
833 LT x( rhs.vec_ );
834 if( x.nonZeros() == 0UL ) return;
835
836 // Evaluation of the right-hand side sparse matrix operand
837 RT A( rhs.mat_ );
838
839 // Checking the evaluated operands
840 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
841 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
842 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
843 BLAZE_INTERNAL_ASSERT( A.columns() == (*lhs).size() , "Invalid vector size" );
844
845 // Performing the sparse matrix-sparse vector multiplication
846 smpSubAssign( *lhs, x * A );
847 }
849 //**********************************************************************************************
850
851 //**SMP subtraction assignment to sparse vectors************************************************
852 // No special implementation for the SMP subtraction assignment to sparse vectors.
853 //**********************************************************************************************
854
855 //**SMP multiplication assignment to dense vectors**********************************************
870 template< typename VT1 > // Type of the target dense vector
871 friend inline auto smpMultAssign( DenseVector<VT1,true>& lhs, const TSVecTSMatMultExpr& rhs )
872 -> EnableIf_t< UseSMPAssign_v<VT1> >
873 {
875
879
880 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
881
882 const ResultType tmp( rhs );
883 smpMultAssign( *lhs, tmp );
884 }
886 //**********************************************************************************************
887
888 //**SMP multiplication assignment to sparse vectors*********************************************
889 // No special implementation for the SMP multiplication assignment to sparse vectors.
890 //**********************************************************************************************
891
892 //**Compile time checks*************************************************************************
903 //**********************************************************************************************
904};
905//*************************************************************************************************
906
907
908
909
910//=================================================================================================
911//
912// GLOBAL BINARY ARITHMETIC OPERATORS
913//
914//=================================================================================================
915
916//*************************************************************************************************
929template< typename VT // Type of the left-hand side sparse vector
930 , typename MT // Type of the right-hand side sparse matrix
931 , DisableIf_t< IsSymmetric_v<MT> || IsZero_v<MT> || IsZero_v<VT> >* = nullptr >
932inline const TSVecTSMatMultExpr<VT,MT>
933 tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
934{
936
937 BLAZE_INTERNAL_ASSERT( (*vec).size() == (*mat).rows(), "Invalid vector and matrix sizes" );
938
939 return TSVecTSMatMultExpr<VT,MT>( *vec, *mat );
940}
942//*************************************************************************************************
943
944
945//*************************************************************************************************
959template< typename VT // Type of the left-hand side sparse vector
960 , typename MT // Type of the right-hand side sparse matrix
961 , EnableIf_t< IsSymmetric_v<MT> &&
962 !( IsIdentity_v<MT> &&
963 IsSame_v< ElementType_t<VT>, ElementType_t<MT> > ) &&
964 !( IsZero_v<MT> || IsZero_v<VT> ) >* = nullptr >
965inline decltype(auto)
966 tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
967{
969
970 BLAZE_INTERNAL_ASSERT( (*vec).size() == (*mat).rows(), "Invalid vector and matrix sizes" );
971
972 return (*vec) * trans( *mat );
973}
975//*************************************************************************************************
976
977
978//*************************************************************************************************
992template< typename VT // Type of the left-hand side sparse vector
993 , typename MT // Type of the right-hand side sparse matrix
994 , EnableIf_t< ( IsIdentity_v<MT> &&
995 IsSame_v< ElementType_t<VT>, ElementType_t<MT> > ) &&
996 !IsZero_v<VT> >* = nullptr >
997inline const VT&
998 tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
999{
1001
1002 MAYBE_UNUSED( mat );
1003
1004 BLAZE_INTERNAL_ASSERT( (*vec).size() == (*mat).rows(), "Invalid vector and matrix sizes" );
1005
1006 return (*vec);
1007}
1009//*************************************************************************************************
1010
1011
1012//*************************************************************************************************
1026template< typename VT // Type of the left-hand side sparse vector
1027 , typename MT // Type of the right-hand side sparse matrix
1028 , EnableIf_t< IsZero_v<MT> || IsZero_v<VT> >* = nullptr >
1029inline decltype(auto)
1030 tsvectsmatmult( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
1031{
1033
1034 MAYBE_UNUSED( vec );
1035
1036 BLAZE_INTERNAL_ASSERT( (*vec).size() == (*mat).rows(), "Invalid vector and matrix sizes" );
1037
1038 using ReturnType = const MultTrait_t< ResultType_t<VT>, ResultType_t<MT> >;
1039
1042
1043 return ReturnType( (*mat).columns() );
1044}
1046//*************************************************************************************************
1047
1048
1049//*************************************************************************************************
1080template< typename VT // Type of the left-hand side sparse vector
1081 , typename MT > // Type of the right-hand side sparse matrix
1082inline decltype(auto)
1083 operator*( const SparseVector<VT,true>& vec, const SparseMatrix<MT,true>& mat )
1084{
1086
1088
1089 if( (*vec).size() != (*mat).rows() ) {
1090 BLAZE_THROW_INVALID_ARGUMENT( "Vector and matrix sizes do not match" );
1091 }
1092
1093 return tsvectsmatmult( *vec, *mat );
1094}
1095//*************************************************************************************************
1096
1097} // namespace blaze
1098
1099#endif
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.
Definition: Aliases.h:550
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
Header file for the EnableIf class template.
Header file for the function trace functionality.
Header file for the If class template.
Header file for the IsComputation type trait class.
Header file for the isDefault shim.
Header file for the IsExpression type trait class.
Header file for the IsIdentity type trait.
Header file for the IsSymmetric type trait.
Deactivation of problematic macros.
Header file for the MAYBE_UNUSED function template.
Header file for the multiplication trait.
Constraint on the transpose flag of vector types.
Constraint on the data type.
Constraint on the data type.
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Base class for sparse vectors.
Definition: SparseVector.h:72
Expression object for sparse vector-sparse matrix multiplications.
Definition: TSVecTSMatMultExpr.h:99
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:138
If_t< IsExpression_v< VT >, const VT, const VT & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:144
static constexpr bool evaluateVector
Compilation switch for the composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:110
size_t nonZeros() const
Returns an estimation for the number of non-zero elements in the sparse vector.
Definition: TSVecTSMatMultExpr.h:218
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:228
If_t< evaluateMatrix, const MRT, MCT > RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:153
static constexpr bool evaluateMatrix
Compilation switch for the composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:115
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSVecTSMatMultExpr.h:141
RightOperand mat_
Right-hand side sparse matrix of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:280
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: TSVecTSMatMultExpr.h:158
CompositeType_t< VT > VCT
Composite type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:104
CompositeType_t< MT > MCT
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:105
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSVecTSMatMultExpr.h:250
LeftOperand vec_
Left-hand side sparse vector of the multiplication expression.
Definition: TSVecTSMatMultExpr.h:279
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSVecTSMatMultExpr.h:238
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:140
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSVecTSMatMultExpr.h:262
If_t< evaluateVector, const VRT, VCT > LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: TSVecTSMatMultExpr.h:150
TSVecTSMatMultExpr(const VT &vec, const MT &mat) noexcept
Constructor for the TSVecTSMatMultExpr class.
Definition: TSVecTSMatMultExpr.h:168
ResultType_t< VT > VRT
Result type of the left-hand side sparse vector expression.
Definition: TSVecTSMatMultExpr.h:102
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: TSVecTSMatMultExpr.h:182
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: TSVecTSMatMultExpr.h:139
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: TSVecTSMatMultExpr.h:272
ResultType_t< MT > MRT
Result type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:103
MultTrait_t< VRT, MRT > ResultType
Result type for expression template evaluations.
Definition: TSVecTSMatMultExpr.h:137
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: TSVecTSMatMultExpr.h:195
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: TSVecTSMatMultExpr.h:208
If_t< IsExpression_v< MT >, const MT, const MT & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSVecTSMatMultExpr.h:147
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the Computation base class.
Header file for the SparseVector base class.
Header file for the TVecMatMultExpr base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:812
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_TVECMATMULTEXPR(T1, T2)
Constraint on the data type.
Definition: TVecMatMultExpr.h:104
#define BLAZE_CONSTRAINT_MUST_NOT_BE_MATMATMULTEXPR_TYPE(T)
Constraint on the data type.
Definition: MatMatMultExpr.h:83
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.
Definition: SparseVector.h:61
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.
Definition: RowVector.h:61
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.
Definition: MultTrait.h:165
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:192
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
#define BLAZE_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
Header file for the exception macros of the math module.
Header file for all forward declarations for expression class templates.
Header file for the reset shim.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all vector/matrix multiplication expression templates.
Definition: TVecMatMultExpr.h:69
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the IsZero type trait.
Header file for the RequiresEvaluation type trait.
Header file for basic type definitions.