Blaze 3.9
SMatSVecMultExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_SMATSVECMULTEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_SMATSVECMULTEXPR_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 SMATDVECMULTEXPR
84//
85//=================================================================================================
86
87//*************************************************************************************************
94template< typename MT // Type of the left-hand side sparse matrix
95 , typename VT > // Type of the right-hand side sparse vector
97 : public MatVecMultExpr< SparseVector< SMatSVecMultExpr<MT,VT>, false > >
98 , private Computation
99{
100 private:
101 //**Type definitions****************************************************************************
106 //**********************************************************************************************
107
108 //**********************************************************************************************
110 static constexpr bool evaluateMatrix = RequiresEvaluation_v<MT>;
111 //**********************************************************************************************
112
113 //**********************************************************************************************
115 static constexpr bool evaluateVector = ( RequiresEvaluation_v<VT> || IsComputation_v<VT> );
116 //**********************************************************************************************
117
118 //**********************************************************************************************
120
124 template< typename T1 >
125 static constexpr bool UseSMPAssign_v = ( evaluateMatrix || evaluateVector );
127 //**********************************************************************************************
128
129 public:
130 //**Type definitions****************************************************************************
133
136
140 using ReturnType = const ElementType;
141
144
146 using LeftOperand = If_t< IsExpression_v<MT>, const MT, const MT& >;
147
149 using RightOperand = If_t< IsExpression_v<VT>, const VT, const VT& >;
150
153
156 //**********************************************************************************************
157
158 //**Compilation flags***************************************************************************
160 static constexpr bool smpAssignable =
161 ( !evaluateMatrix && MT::smpAssignable && !evaluateVector && VT::smpAssignable );
162 //**********************************************************************************************
163
164 //**Constructor*********************************************************************************
170 inline SMatSVecMultExpr( const MT& mat, const VT& vec ) noexcept
171 : mat_( mat ) // Left-hand side sparse matrix of the multiplication expression
172 , vec_( vec ) // Right-hand side sparse vector of the multiplication expression
173 {
174 BLAZE_INTERNAL_ASSERT( mat_.columns() == vec_.size(), "Invalid matrix and vector sizes" );
175 }
176 //**********************************************************************************************
177
178 //**Subscript operator**************************************************************************
184 inline ReturnType operator[]( size_t index ) const {
185 BLAZE_INTERNAL_ASSERT( index < mat_.rows(), "Invalid vector access index" );
186 return row( mat_, index, unchecked ) * vec_;
187 }
188 //**********************************************************************************************
189
190 //**At function*********************************************************************************
197 inline ReturnType at( size_t index ) const {
198 if( index >= mat_.rows() ) {
199 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
200 }
201 return (*this)[index];
202 }
203 //**********************************************************************************************
204
205 //**Size function*******************************************************************************
210 inline size_t size() const noexcept {
211 return mat_.rows();
212 }
213 //**********************************************************************************************
214
215 //**NonZeros function***************************************************************************
220 inline size_t nonZeros() const {
221 return mat_.rows();
222 }
223 //**********************************************************************************************
224
225 //**Left operand access*************************************************************************
230 inline LeftOperand leftOperand() const noexcept {
231 return mat_;
232 }
233 //**********************************************************************************************
234
235 //**Right operand access************************************************************************
240 inline RightOperand rightOperand() const noexcept {
241 return vec_;
242 }
243 //**********************************************************************************************
244
245 //**********************************************************************************************
251 template< typename T >
252 inline bool canAlias( const T* alias ) const noexcept {
253 return ( mat_.isAliased( alias ) || vec_.isAliased( alias ) );
254 }
255 //**********************************************************************************************
256
257 //**********************************************************************************************
263 template< typename T >
264 inline bool isAliased( const T* alias ) const noexcept {
265 return ( mat_.isAliased( alias ) || vec_.isAliased( alias ) );
266 }
267 //**********************************************************************************************
268
269 //**********************************************************************************************
274 inline bool canSMPAssign() const noexcept {
275 return ( size() > SMP_SMATSVECMULT_THRESHOLD );
276 }
277 //**********************************************************************************************
278
279 private:
280 //**Member variables****************************************************************************
283 //**********************************************************************************************
284
285 //**Assignment to dense vectors*****************************************************************
297 template< typename VT1 > // Type of the target dense vector
298 friend inline void assign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
299 {
301
302 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
303
304 // Resetting the left-hand side target dense vector
305 reset( *lhs );
306
307 // Evaluation of the right-hand side sparse vector operand
308 RT x( serial( rhs.vec_ ) );
309 if( x.nonZeros() == 0UL ) return;
310
311 // Evaluation of the left-hand side sparse matrix operand
312 LT A( serial( rhs.mat_ ) );
313
314 // Checking the evaluated operators
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( x.size() == rhs.vec_.size() , "Invalid vector size" );
318 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
319
320 // Performing the sparse matrix-sparse vector multiplication
321 SMatSVecMultExpr::selectAssignKernel( *lhs, A, x );
322 }
324 //**********************************************************************************************
325
326 //**Default assignment to dense vectors*********************************************************
340 template< typename VT1 // Type of the left-hand side target vector
341 , typename MT1 // Type of the left-hand side matrix operand
342 , typename VT2 > // Type of the right-hand side vector operand
343 static inline void selectAssignKernel( VT1& y, const MT1& A, const VT2& x )
344 {
345 const auto vend( x.end() );
346
347 for( size_t i=0UL; i<y.size(); ++i )
348 {
349 const auto mend ( A.end(i) );
350 auto melem( A.begin(i) );
351
352 if( melem == mend ) continue;
353
354 auto velem( x.begin() );
355
356 while( true ) {
357 if( melem->index() < velem->index() ) {
358 ++melem;
359 if( melem == mend ) break;
360 }
361 else if( velem->index() < melem->index() ) {
362 ++velem;
363 if( velem == vend ) break;
364 }
365 else {
366 y[i] = melem->value() * velem->value();
367 ++melem;
368 ++velem;
369 break;
370 }
371 }
372
373 if( melem != mend && velem != vend )
374 {
375 while( true ) {
376 if( melem->index() < velem->index() ) {
377 ++melem;
378 if( melem == mend ) break;
379 }
380 else if( velem->index() < melem->index() ) {
381 ++velem;
382 if( velem == vend ) break;
383 }
384 else {
385 y[i] += melem->value() * velem->value();
386 ++melem;
387 if( melem == mend ) break;
388 ++velem;
389 if( velem == vend ) break;
390 }
391 }
392 }
393 }
394 }
396 //**********************************************************************************************
397
398 //**Assignment to sparse vectors****************************************************************
410 template< typename VT1 > // Type of the target sparse vector
411 friend inline void assign( SparseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
412 {
414
415 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
416
417 RT x( rhs.vec_ ); // Evaluation of the right-hand side sparse vector operand
418 if( x.nonZeros() == 0UL ) return;
419
420 LT A( rhs.mat_ ); // Evaluation of the left-hand side sparse matrix operand
421
422 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
423 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
424 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
425 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
426
427 ElementType accu;
428 const auto vend( x.end() );
429
430 for( size_t i=0UL; i<(*lhs).size(); ++i )
431 {
432 const auto mend ( A.end(i) );
433 auto melem( A.begin(i) );
434
435 if( melem == mend ) continue;
436
437 auto velem( x.begin() );
438
439 reset( accu );
440
441 while( true ) {
442 if( melem->index() < velem->index() ) {
443 ++melem;
444 if( melem == mend ) break;
445 }
446 else if( velem->index() < melem->index() ) {
447 ++velem;
448 if( velem == vend ) break;
449 }
450 else {
451 accu = melem->value() * velem->value();
452 ++melem;
453 ++velem;
454 break;
455 }
456 }
457
458 if( melem != mend && velem != vend )
459 {
460 while( true ) {
461 if( melem->index() < velem->index() ) {
462 ++melem;
463 if( melem == mend ) break;
464 }
465 else if( velem->index() < melem->index() ) {
466 ++velem;
467 if( velem == vend ) break;
468 }
469 else {
470 accu += melem->value() * velem->value();
471 ++melem;
472 if( melem == mend ) break;
473 ++velem;
474 if( velem == vend ) break;
475 }
476 }
477 }
478
479 if( !isDefault( accu ) )
480 (*lhs).insert( i, accu );
481 }
482 }
484 //**********************************************************************************************
485
486 //**Addition assignment to dense vectors********************************************************
498 template< typename VT1 > // Type of the target dense vector
499 friend inline void addAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
500 {
502
503 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
504
505 // Evaluation of the right-hand side sparse vector operand
506 RT x( serial( rhs.vec_ ) );
507 if( x.nonZeros() == 0UL ) return;
508
509 // Evaluation of the left-hand side sparse matrix operand
510 LT A( serial( rhs.mat_ ) );
511
512 // Checking the evaluated operators
513 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
514 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
515 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
516 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
517
518 // Performing the sparse matrix-sparse vector multiplication
519 SMatSVecMultExpr::selectAddAssignKernel( *lhs, A, x );
520 }
522 //**********************************************************************************************
523
524 //**Default addition assignment to dense vectors************************************************
538 template< typename VT1 // Type of the left-hand side target vector
539 , typename MT1 // Type of the left-hand side matrix operand
540 , typename VT2 > // Type of the right-hand side vector operand
541 static inline void selectAddAssignKernel( VT1& y, const MT1& A, const VT2& x )
542 {
543 const auto vend( x.end() );
544
545 for( size_t i=0UL; i<y.size(); ++i )
546 {
547 const auto mend ( A.end(i) );
548 auto melem( A.begin(i) );
549
550 if( melem == mend ) continue;
551
552 auto velem( x.begin() );
553
554 while( true ) {
555 if( melem->index() < velem->index() ) {
556 ++melem;
557 if( melem == mend ) break;
558 }
559 else if( velem->index() < melem->index() ) {
560 ++velem;
561 if( velem == vend ) break;
562 }
563 else {
564 y[i] += melem->value() * velem->value();
565 ++melem;
566 if( melem == mend ) break;
567 ++velem;
568 if( velem == vend ) break;
569 }
570 }
571 }
572 }
574 //**********************************************************************************************
575
576 //**Addition assignment to sparse vectors*******************************************************
577 // No special implementation for the addition assignment to sparse vectors.
578 //**********************************************************************************************
579
580 //**Subtraction assignment to dense vectors*****************************************************
592 template< typename VT1 > // Type of the target dense vector
593 friend inline void subAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
594 {
596
597 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
598
599 // Evaluation of the right-hand side sparse vector operand
600 RT x( serial( rhs.vec_ ) );
601 if( x.nonZeros() == 0UL ) return;
602
603 // Evaluation of the left-hand side sparse matrix operand
604 LT A( serial( rhs.mat_ ) );
605
606 // Checking the evaluated operators
607 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
608 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
609 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
610 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
611
612 // Performing the sparse matrix-sparse vector multiplication
613 SMatSVecMultExpr::selectSubAssignKernel( *lhs, A, x );
614 }
616 //**********************************************************************************************
617
618 //**Default subtraction assignment to dense vectors*********************************************
632 template< typename VT1 // Type of the left-hand side target vector
633 , typename MT1 // Type of the left-hand side matrix operand
634 , typename VT2 > // Type of the right-hand side vector operand
635 static inline void selectSubAssignKernel( VT1& y, const MT1& A, const VT2& x )
636 {
637 const auto vend( x.end() );
638
639 for( size_t i=0UL; i<y.size(); ++i )
640 {
641 const auto mend ( A.end(i) );
642 auto melem( A.begin(i) );
643
644 if( melem == mend ) continue;
645
646 auto velem( x.begin() );
647
648 while( true ) {
649 if( melem->index() < velem->index() ) {
650 ++melem;
651 if( melem == mend ) break;
652 }
653 else if( velem->index() < melem->index() ) {
654 ++velem;
655 if( velem == vend ) break;
656 }
657 else {
658 y[i] -= melem->value() * velem->value();
659 ++melem;
660 if( melem == mend ) break;
661 ++velem;
662 if( velem == vend ) break;
663 }
664 }
665 }
666 }
668 //**********************************************************************************************
669
670 //**Subtraction assignment to sparse vectors****************************************************
671 // No special implementation for the subtraction assignment to sparse vectors.
672 //**********************************************************************************************
673
674 //**Multiplication assignment to dense vectors**************************************************
686 template< typename VT1 > // Type of the target dense vector
687 friend inline void multAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
688 {
690
694
695 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
696
697 const ResultType tmp( serial( rhs ) );
698 multAssign( *lhs, tmp );
699 }
701 //**********************************************************************************************
702
703 //**Multiplication assignment to sparse vectors*************************************************
704 // No special implementation for the multiplication assignment to sparse vectors.
705 //**********************************************************************************************
706
707 //**SMP assignment to dense vectors*************************************************************
721 template< typename VT1 > // Type of the target dense vector
722 friend inline auto smpAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
723 -> EnableIf_t< UseSMPAssign_v<VT1> >
724 {
726
727 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
728
729 // Resetting the left-hand side target dense vector
730 reset( *lhs );
731
732 // Evaluation of the right-hand side sparse vector operand
733 RT x( rhs.vec_ );
734 if( x.nonZeros() == 0UL ) return;
735
736 // Evaluation of the left-hand side sparse matrix operand
737 LT A( rhs.mat_ );
738
739 // Checking the evaluated operators
740 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
741 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
742 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
743 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
744
745 // Performing the sparse matrix-sparse vector multiplication
746 smpAssign( *lhs, A * x );
747 }
749 //**********************************************************************************************
750
751 //**SMP assignment to sparse vectors************************************************************
752 // No special implementation for the SMP assignment to sparse vectors.
753 //**********************************************************************************************
754
755 //**SMP addition assignment to dense vectors****************************************************
770 template< typename VT1 > // Type of the target dense vector
771 friend inline auto smpAddAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
772 -> EnableIf_t< UseSMPAssign_v<VT1> >
773 {
775
776 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
777
778 // Evaluation of the right-hand side sparse vector operand
779 RT x( rhs.vec_ );
780 if( x.nonZeros() == 0UL ) return;
781
782 // Evaluation of the left-hand side sparse matrix operand
783 LT A( rhs.mat_ );
784
785 // Checking the evaluated operators
786 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
787 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
788 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
789 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
790
791 // Performing the sparse matrix-sparse vector multiplication
792 smpAddAssign( *lhs, A * x );
793 }
795 //**********************************************************************************************
796
797 //**SMP addition assignment to sparse vectors***************************************************
798 // No special implementation for the SMP addition assignment to sparse vectors.
799 //**********************************************************************************************
800
801 //**SMP subtraction assignment to dense vectors*************************************************
816 template< typename VT1 > // Type of the target dense vector
817 friend inline auto smpSubAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
818 -> EnableIf_t< UseSMPAssign_v<VT1> >
819 {
821
822 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
823
824 // Evaluation of the right-hand side sparse vector operand
825 RT x( rhs.vec_ );
826 if( x.nonZeros() == 0UL ) return;
827
828 // Evaluation of the left-hand side sparse matrix operand
829 LT A( rhs.mat_ );
830
831 // Checking the evaluated operators
832 BLAZE_INTERNAL_ASSERT( A.rows() == rhs.mat_.rows() , "Invalid number of rows" );
833 BLAZE_INTERNAL_ASSERT( A.columns() == rhs.mat_.columns(), "Invalid number of columns" );
834 BLAZE_INTERNAL_ASSERT( x.size() == rhs.vec_.size() , "Invalid vector size" );
835 BLAZE_INTERNAL_ASSERT( A.rows() == (*lhs).size() , "Invalid vector size" );
836
837 // Performing the sparse matrix-sparse vector multiplication
838 smpSubAssign( *lhs, A * x );
839 }
841 //**********************************************************************************************
842
843 //**SMP subtraction assignment to sparse vectors************************************************
844 // No special implementation for the SMP subtraction assignment to sparse vectors.
845 //**********************************************************************************************
846
847 //**SMP multiplication assignment to dense vectors**********************************************
862 template< typename VT1 > // Type of the target dense vector
863 friend inline auto smpMultAssign( DenseVector<VT1,false>& lhs, const SMatSVecMultExpr& rhs )
864 -> EnableIf_t< UseSMPAssign_v<VT1> >
865 {
867
871
872 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
873
874 const ResultType tmp( rhs );
875 smpMultAssign( *lhs, tmp );
876 }
878 //**********************************************************************************************
879
880 //**SMP multiplication assignment to sparse vectors*********************************************
881 // No special implementation for the SMP multiplication assignment to sparse vectors.
882 //**********************************************************************************************
883
884 //**Compile time checks*************************************************************************
895 //**********************************************************************************************
896};
897//*************************************************************************************************
898
899
900
901
902//=================================================================================================
903//
904// GLOBAL BINARY ARITHMETIC OPERATORS
905//
906//=================================================================================================
907
908//*************************************************************************************************
921template< typename MT // Type of the left-hand side sparse matrix
922 , typename VT // Type of the right-hand side sparse vector
923 , DisableIf_t< IsSymmetric_v<MT> ||
924 ( IsIdentity_v<MT> &&
925 IsSame_v< ElementType_t<MT>, ElementType_t<VT> > ) ||
926 ( IsZero_v<MT> || IsZero_v<VT> ) >* = nullptr >
927inline const SMatSVecMultExpr<MT,VT>
928 smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
929{
931
932 BLAZE_INTERNAL_ASSERT( (*mat).columns() == (*vec).size(), "Invalid matrix and vector sizes" );
933
934 return SMatSVecMultExpr<MT,VT>( *mat, *vec );
935}
937//*************************************************************************************************
938
939
940//*************************************************************************************************
954template< typename MT // Type of the left-hand side sparse matrix
955 , typename VT // Type of the right-hand side sparse vector
956 , EnableIf_t< IsSymmetric_v<MT> &&
957 !( IsIdentity_v<MT> &&
958 IsSame_v< ElementType_t<MT>, ElementType_t<VT> > ) &&
959 !( IsZero_v<MT> || IsZero_v<VT> ) >* = nullptr >
960inline decltype(auto)
961 smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
962{
964
965 BLAZE_INTERNAL_ASSERT( (*mat).columns() == (*vec).size(), "Invalid matrix and vector sizes" );
966
967 return trans( *mat ) * (*vec);
968}
970//*************************************************************************************************
971
972
973//*************************************************************************************************
987template< typename MT // Type of the left-hand side sparse matrix
988 , typename VT // Type of the right-hand side sparse vector
989 , EnableIf_t< ( IsIdentity_v<MT> &&
990 IsSame_v< ElementType_t<MT>, ElementType_t<VT> > ) &&
991 !IsZero_v<VT> >* = nullptr >
992inline const VT&
993 smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
994{
996
997 MAYBE_UNUSED( mat );
998
999 BLAZE_INTERNAL_ASSERT( (*mat).columns() == (*vec).size(), "Invalid matrix and vector sizes" );
1000
1001 return (*vec);
1002}
1004//*************************************************************************************************
1005
1006
1007//*************************************************************************************************
1020template< typename MT // Type of the left-hand side sparse matrix
1021 , typename VT // Type of the right-hand side sparse vector
1022 , EnableIf_t< IsZero_v<MT> || IsZero_v<VT> >* = nullptr >
1023inline decltype(auto)
1024 smatsvecmult( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
1025{
1027
1028 MAYBE_UNUSED( vec );
1029
1030 BLAZE_INTERNAL_ASSERT( (*mat).columns() == (*vec).size(), "Invalid matrix and vector sizes" );
1031
1032 using ReturnType = const MultTrait_t< ResultType_t<MT>, ResultType_t<VT> >;
1033
1036
1037 return ReturnType( (*mat).rows() );
1038}
1040//*************************************************************************************************
1041
1042
1043//*************************************************************************************************
1074template< typename MT // Type of the left-hand side sparse matrix
1075 , typename VT > // Type of the right-hand side sparse vector
1076inline decltype(auto)
1077 operator*( const SparseMatrix<MT,false>& mat, const SparseVector<VT,false>& vec )
1078{
1080
1082
1083 if( (*mat).columns() != (*vec).size() ) {
1084 BLAZE_THROW_INVALID_ARGUMENT( "Matrix and vector sizes do not match" );
1085 }
1086
1087 return smatsvecmult( *mat, *vec );
1088}
1089//*************************************************************************************************
1090
1091} // namespace blaze
1092
1093#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.
Constraint on the transpose flag of vector 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.
Constraints on the storage order of matrix types.
Constraint on the data type.
Constraint on the data type.
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Expression object for sparse matrix-sparse vector multiplications.
Definition: SMatSVecMultExpr.h:99
If_t< evaluateVector, const VRT, VCT > RT
Type for the assignment of the right-hand side sparse vector operand.
Definition: SMatSVecMultExpr.h:155
CompositeType_t< VT > VCT
Composite type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:105
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: SMatSVecMultExpr.h:274
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SMatSVecMultExpr.h:184
LeftOperand mat_
Left-hand side sparse matrix of the multiplication expression.
Definition: SMatSVecMultExpr.h:281
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSVecMultExpr.h:252
size_t nonZeros() const
Returns an estimation for the number of non-zero elements in the sparse vector.
Definition: SMatSVecMultExpr.h:220
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSVecMultExpr.h:138
const ElementType ReturnType
Return type for expression template evaluations.
Definition: SMatSVecMultExpr.h:140
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatSVecMultExpr.h:264
If_t< IsExpression_v< MT >, const MT, const MT & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:146
MultTrait_t< MRT, VRT > ResultType
Result type for expression template evaluations.
Definition: SMatSVecMultExpr.h:137
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSVecMultExpr.h:143
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatSVecMultExpr.h:139
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: SMatSVecMultExpr.h:210
static constexpr bool evaluateMatrix
Compilation switch for the composite type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:110
RightOperand vec_
Right-hand side sparse vector of the multiplication expression.
Definition: SMatSVecMultExpr.h:282
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: SMatSVecMultExpr.h:197
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSVecMultExpr.h:230
CompositeType_t< MT > MCT
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:104
SMatSVecMultExpr(const MT &mat, const VT &vec) noexcept
Constructor for the SMatSVecMultExpr class.
Definition: SMatSVecMultExpr.h:170
ResultType_t< MT > MRT
Result type of the left-hand side sparse matrix expression.
Definition: SMatSVecMultExpr.h:102
static constexpr bool evaluateVector
Compilation switch for the composite type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:115
If_t< IsExpression_v< VT >, const VT, const VT & > RightOperand
Composite type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:149
ResultType_t< VT > VRT
Result type of the right-hand side sparse vector expression.
Definition: SMatSVecMultExpr.h:103
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatSVecMultExpr.h:160
If_t< evaluateMatrix, const MRT, MCT > LT
Type for the assignment of the left-hand side sparse matrix operand.
Definition: SMatSVecMultExpr.h:152
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse vector operand.
Definition: SMatSVecMultExpr.h:240
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Base class for sparse vectors.
Definition: SparseVector.h:72
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 MatVecMultExpr base class.
Header file for the SparseVector base class.
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_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#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_FORM_VALID_MATVECMULTEXPR(T1, T2)
Constraint on the data type.
Definition: MatVecMultExpr.h:104
#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_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.
Definition: ColumnVector.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
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#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 matrix/vector multiplication expression templates.
Definition: MatVecMultExpr.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.