Blaze 3.9
SVecSVecOuterExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_SVECSVECOUTEREXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_SVECSVECOUTEREXPR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <utility>
44#include <blaze/math/Aliases.h>
65#include <blaze/util/Assert.h>
66#include <blaze/util/EnableIf.h>
68#include <blaze/util/mpl/If.h>
69#include <blaze/util/Types.h>
70
71
72namespace blaze {
73
74//=================================================================================================
75//
76// CLASS SVECSVECOUTEREXPR
77//
78//=================================================================================================
79
80//*************************************************************************************************
87template< typename VT1 // Type of the left-hand side sparse vector
88 , typename VT2 > // Type of the right-hand side sparse vector
90 : public VecTVecMultExpr< SparseMatrix< SVecSVecOuterExpr<VT1,VT2>, false > >
91 , private Computation
92{
93 private:
94 //**Type definitions****************************************************************************
101 //**********************************************************************************************
102
103 //**Return type evaluation**********************************************************************
105
110 static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
111
113 using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
114 //**********************************************************************************************
115
116 public:
117 //**Type definitions****************************************************************************
120
123
128
131
134
136 using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
137
139 using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
140
143
146 //**********************************************************************************************
147
148 //**Compilation flags***************************************************************************
150 static constexpr bool smpAssignable = false;
151 //**********************************************************************************************
152
153 //**Constructor*********************************************************************************
159 inline SVecSVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
160 : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
161 , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
162 {}
163 //**********************************************************************************************
164
165 //**Access operator*****************************************************************************
172 inline ReturnType operator()( size_t i, size_t j ) const {
173 BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
174 BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
175
176 return lhs_[i] * rhs_[j];
177 }
178 //**********************************************************************************************
179
180 //**At function*********************************************************************************
188 inline ReturnType at( size_t i, size_t j ) const {
189 if( i >= lhs_.size() ) {
190 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
191 }
192 if( j >= rhs_.size() ) {
193 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
194 }
195 return (*this)(i,j);
196 }
197 //**********************************************************************************************
198
199 //**Rows function*******************************************************************************
204 inline size_t rows() const noexcept {
205 return lhs_.size();
206 }
207 //**********************************************************************************************
208
209 //**Columns function****************************************************************************
214 inline size_t columns() const noexcept {
215 return rhs_.size();
216 }
217 //**********************************************************************************************
218
219 //**NonZeros function***************************************************************************
224 inline size_t nonZeros() const {
225 return lhs_.nonZeros() * rhs_.nonZeros();
226 }
227 //**********************************************************************************************
228
229 //**NonZeros function***************************************************************************
235 inline size_t nonZeros( size_t i ) const {
236 return ( isDefault( lhs_[i] ) )?( size_t(0) ):( rhs_.nonZeros(i) );
237 }
238 //**********************************************************************************************
239
240 //**Left operand access*************************************************************************
245 inline LeftOperand leftOperand() const noexcept {
246 return lhs_;
247 }
248 //**********************************************************************************************
249
250 //**Right operand access************************************************************************
255 inline RightOperand rightOperand() const noexcept {
256 return rhs_;
257 }
258 //**********************************************************************************************
259
260 //**********************************************************************************************
266 template< typename T >
267 inline bool canAlias( const T* alias ) const noexcept {
268 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
269 }
270 //**********************************************************************************************
271
272 //**********************************************************************************************
278 template< typename T >
279 inline bool isAliased( const T* alias ) const noexcept {
280 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
281 }
282 //**********************************************************************************************
283
284 private:
285 //**Member variables****************************************************************************
288 //**********************************************************************************************
289
290 //**Assignment to row-major dense matrices******************************************************
302 template< typename MT > // Type of the target dense matrix
303 friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
304 {
306
307 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
308 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
309
310 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
311 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
312
313 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
314 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
315 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
316 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
317
318 const auto lend( x.end() );
319 const auto rend( y.end() );
320
321 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
322 if( !isDefault( lelem->value() ) ) {
323 for( auto relem=y.begin(); relem!=rend; ++relem ) {
324 (*lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
325 }
326 }
327 }
328 }
330 //**********************************************************************************************
331
332 //**Assignment to column-major dense matrices***************************************************
345 template< typename MT > // Type of the target dense matrix
346 friend inline void assign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
347 {
349
351
352 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
353 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
354
355 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
356 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
357
358 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
359 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
360 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
361 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
362
363 const auto lend( x.end() );
364 const auto rend( y.end() );
365
366 for( auto relem=y.begin(); relem!=rend; ++relem ) {
367 if( !isDefault( relem->value() ) ) {
368 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
369 (*lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
370 }
371 }
372 }
373 }
375 //**********************************************************************************************
376
377 //**Assignment to row-major sparse matrices*****************************************************
389 template< typename MT > // Type of the target sparse matrix
390 friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
391 {
393
394 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
395 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns() , "Invalid number of columns" );
396 BLAZE_INTERNAL_ASSERT( (*lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
397
398 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
399 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
400
401 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
402 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
403 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
404 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
405
406 // Final memory allocation (based on the evaluated operands)
407 (*lhs).reserve( x.nonZeros() * y.nonZeros() );
408
409 // Performing the outer product
410 const auto lend( x.end() );
411 const auto rend( y.end() );
412 size_t index( 0UL );
413
414 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
415 if( !isDefault( lelem->value() ) ) {
416 for( ; index < lelem->index(); ++index ) {
417 (*lhs).finalize( index );
418 }
419 for( auto relem=y.begin(); relem!=rend; ++relem ) {
420 (*lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
421 }
422 (*lhs).finalize( index++ );
423 }
424 }
425
426 for( ; index < x.size(); ++index ) {
427 (*lhs).finalize( index );
428 }
429 }
431 //**********************************************************************************************
432
433 //**Assignment to column-major sparse matrices**************************************************
446 template< typename MT > // Type of the target sparse matrix
447 friend inline void assign( SparseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
448 {
450
452
453 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
454 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns() , "Invalid number of columns" );
455 BLAZE_INTERNAL_ASSERT( (*lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
456
457 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
458 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
459
460 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
461 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
462 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
463 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
464
465 const auto lend( x.end() );
466 const auto rend( y.end() );
467 size_t index( 0UL );
468
469 for( auto relem=y.begin(); relem!=rend; ++relem ) {
470 if( !isDefault( relem->value() ) ) {
471 for( ; index < relem->index(); ++index ) {
472 (*lhs).finalize( index );
473 }
474 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
475 (*lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
476 }
477 (*lhs).finalize( index++ );
478 }
479 }
480
481 for( ; index < y.size(); ++index ) {
482 (*lhs).finalize( index );
483 }
484 }
486 //**********************************************************************************************
487
488 //**Addition assignment to row-major dense matrices*********************************************
501 template< typename MT > // Type of the target dense matrix
502 friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
503 {
505
506 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
507 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
508
509 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
510 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
511
512 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
513 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
514 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
515 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
516
517 const auto lend( x.end() );
518 const auto rend( y.end() );
519
520 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
521 if( !isDefault( lelem->value() ) ) {
522 for( auto relem=y.begin(); relem!=rend; ++relem ) {
523 (*lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
524 }
525 }
526 }
527 }
529 //**********************************************************************************************
530
531 //**Addition assignment to column-major dense matrices******************************************
544 template< typename MT > // Type of the target dense matrix
545 friend inline void addAssign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
546 {
548
550
551 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
552 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
553
554 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
555 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
556
557 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
558 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
559 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
560 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
561
562 const auto lend( x.end() );
563 const auto rend( y.end() );
564
565 for( auto relem=y.begin(); relem!=rend; ++relem ) {
566 if( !isDefault( relem->value() ) ) {
567 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
568 (*lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
569 }
570 }
571 }
572 }
574 //**********************************************************************************************
575
576 //**Addition assignment to sparse matrices******************************************************
577 // No special implementation for the addition assignment to sparse matrices.
578 //**********************************************************************************************
579
580 //**Subtraction assignment to row-major dense matrices******************************************
593 template< typename MT > // Type of the target dense matrix
594 friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
595 {
597
598 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
599 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
600
601 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
602 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
603
604 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
605 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
606 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
607 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
608
609 const auto lend( x.end() );
610 const auto rend( y.end() );
611
612 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
613 if( !isDefault( lelem->value() ) ) {
614 for( auto relem=y.begin(); relem!=rend; ++relem ) {
615 (*lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
616 }
617 }
618 }
619 }
621 //**********************************************************************************************
622
623 //**Subtraction assignment to column-major dense matrices***************************************
636 template< typename MT > // Type of the target dense matrix
637 friend inline void subAssign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
638 {
640
642
643 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
644 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
645
646 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
647 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
648
649 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
650 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
651 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
652 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
653
654 const auto lend( x.end() );
655 const auto rend( y.end() );
656
657 for( auto relem=y.begin(); relem!=rend; ++relem ) {
658 if( !isDefault( relem->value() ) ) {
659 for( auto lelem=x.begin(); lelem!=lend; ++lelem ) {
660 (*lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
661 }
662 }
663 }
664 }
666 //**********************************************************************************************
667
668 //**Subtraction assignment to sparse matrices***************************************************
669 // No special implementation for the subtraction assignment to sparse matrices.
670 //**********************************************************************************************
671
672 //**Schur product assignment to row-major dense matrices****************************************
685 template< typename MT > // Type of the target dense matrix
686 friend inline void schurAssign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
687 {
689
690 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
691 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
692
693 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
694 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
695
696 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
697 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
698 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
699 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
700
701 const auto lend( x.end() );
702 const auto rend( y.end() );
703
704 size_t i( 0UL );
705
706 for( auto lelem=x.begin(); lelem!=lend; ++lelem )
707 {
708 if( isDefault( lelem->value() ) ) continue;
709
710 for( ; i<lelem->index(); ++i ) {
711 for( size_t j=0UL; j<y.size(); ++j )
712 reset( (*lhs)(i,j) );
713 }
714
715 size_t j( 0UL );
716
717 for( auto relem=y.begin(); relem!=rend; ++relem, ++j ) {
718 for( ; j<relem->index(); ++j )
719 reset( (*lhs)(i,j) );
720 (*lhs)(lelem->index(),relem->index()) *= lelem->value() * relem->value();
721 }
722
723 for( ; j<y.size(); ++j ) {
724 reset( (*lhs)(i,j) );
725 }
726
727 ++i;
728 }
729
730 for( ; i<x.size(); ++i ) {
731 for( size_t j=0UL; j<y.size(); ++j )
732 reset( (*lhs)(i,j) );
733 }
734 }
736 //**********************************************************************************************
737
738 //**Schur product assignment to column-major dense matrices*************************************
751 template< typename MT > // Type of the target dense matrix
752 friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
753 {
755
757
758 BLAZE_INTERNAL_ASSERT( (*lhs).rows() == rhs.rows() , "Invalid number of rows" );
759 BLAZE_INTERNAL_ASSERT( (*lhs).columns() == rhs.columns(), "Invalid number of columns" );
760
761 LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
762 RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
763
764 BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
765 BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
766 BLAZE_INTERNAL_ASSERT( x.size() == (*lhs).rows() , "Invalid vector size" );
767 BLAZE_INTERNAL_ASSERT( y.size() == (*lhs).columns(), "Invalid vector size" );
768
769 const auto lend( x.end() );
770 const auto rend( y.end() );
771
772 size_t j( 0UL );
773
774 for( auto relem=y.begin(); relem!=rend; ++relem )
775 {
776 if( isDefault( relem->value() ) ) continue;
777
778 for( ; j<relem->index(); ++j ) {
779 for( size_t i=0UL; i<x.size(); ++i )
780 reset( (*lhs)(i,j) );
781 }
782
783 size_t i( 0UL );
784
785 for( auto lelem=x.begin(); lelem!=lend; ++lelem, ++i ) {
786 for( ; i<lelem->index(); ++i )
787 reset( (*lhs)(i,j) );
788 (*lhs)(lelem->index(),relem->index()) *= lelem->value() * relem->value();
789 }
790
791 for( ; i<x.size(); ++i ) {
792 reset( (*lhs)(i,j) );
793 }
794
795 ++j;
796 }
797
798 for( ; j<y.size(); ++j ) {
799 for( size_t i=0UL; i<x.size(); ++i )
800 reset( (*lhs)(i,j) );
801 }
802 }
804 //**********************************************************************************************
805
806 //**Schur product assignment to sparse matrices*************************************************
807 // No special implementation for the Schur product assignment to sparse matrices.
808 //**********************************************************************************************
809
810 //**Multiplication assignment to dense matrices*************************************************
811 // No special implementation for the multiplication assignment to dense matrices.
812 //**********************************************************************************************
813
814 //**Multiplication assignment to sparse matrices************************************************
815 // No special implementation for the multiplication assignment to sparse matrices.
816 //**********************************************************************************************
817
818 //**Compile time checks*************************************************************************
828 //**********************************************************************************************
829};
830//*************************************************************************************************
831
832
833
834
835//=================================================================================================
836//
837// GLOBAL BINARY ARITHMETIC OPERATORS
838//
839//=================================================================================================
840
841//*************************************************************************************************
854template< typename VT1 // Type of the left-hand side sparse vector
855 , typename VT2 // Type of the right-hand side sparse vector
856 , DisableIf_t< IsZero_v<VT1> || IsZero_v<VT2> >* = nullptr >
857inline const SVecSVecOuterExpr<VT1,VT2>
858 svecsvecouter( const SparseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
859{
861
862 return SVecSVecOuterExpr<VT1,VT2>( *lhs, *rhs );
863}
865//*************************************************************************************************
866
867
868//*************************************************************************************************
881template< typename VT1 // Type of the left-hand side sparse vector
882 , typename VT2 // Type of the right-hand side sparse vector
883 , EnableIf_t< IsZero_v<VT1> || IsZero_v<VT2> >* = nullptr >
884inline decltype(auto)
885 svecsvecouter( const SparseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
886{
888
889 using ReturnType = const MultTrait_t< ResultType_t<VT1>, ResultType_t<VT2> >;
890
893
894 return ReturnType( (*lhs).size(), (*rhs).size() );
895}
897//*************************************************************************************************
898
899
900//*************************************************************************************************
927template< typename VT1 // Type of the left-hand side sparse vector
928 , typename VT2 > // Type of the right-hand side sparse vector
929inline decltype(auto)
930 operator*( const SparseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
931{
933
934 return svecsvecouter( *lhs, *rhs );
935}
936//*************************************************************************************************
937
938} // namespace blaze
939
940#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::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.
Definition: Aliases.h:470
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::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.
Definition: Aliases.h:310
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.
Definition: Aliases.h:550
Header file for run time assertion macros.
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 IsTemporary type trait class.
Deactivation of problematic macros.
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 dense matrices.
Definition: DenseMatrix.h:82
Expression object for sparse vector-sparse vector outer products.
Definition: SVecSVecOuterExpr.h:92
ReturnType_t< VT1 > RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:97
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SVecSVecOuterExpr.h:204
ResultType_t< VT2 > RT2
Result type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:96
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SVecSVecOuterExpr.h:188
CompositeType_t< VT1 > CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:99
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecSVecOuterExpr.h:245
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SVecSVecOuterExpr.h:172
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse vector operand.
Definition: SVecSVecOuterExpr.h:255
RightOperand rhs_
Right-hand side sparse vector of the multiplication expression.
Definition: SVecSVecOuterExpr.h:287
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecSVecOuterExpr.h:130
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SVecSVecOuterExpr.h:125
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SVecSVecOuterExpr.h:150
SVecSVecOuterExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the SVecSVecOuterExpr class.
Definition: SVecSVecOuterExpr.h:159
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SVecSVecOuterExpr.h:214
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SVecSVecOuterExpr.h:113
ReturnType_t< VT2 > RN2
Return type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:98
ResultType_t< VT1 > RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:95
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SVecSVecOuterExpr.h:127
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecSVecOuterExpr.h:126
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecSVecOuterExpr.h:279
CompositeType_t< VT2 > CT2
Composite type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:100
const ResultType CompositeType
Data type for composite expression templates.
Definition: SVecSVecOuterExpr.h:133
LeftOperand lhs_
Left-hand side sparse vector of the multiplication expression.
Definition: SVecSVecOuterExpr.h:286
If_t< IsExpression_v< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:136
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SVecSVecOuterExpr.h:235
MultTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SVecSVecOuterExpr.h:124
If_t< IsComputation_v< VT2 >, const RT2, CT2 > RT
Type for the assignment of the right-hand side sparse vector operand.
Definition: SVecSVecOuterExpr.h:145
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecSVecOuterExpr.h:267
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SVecSVecOuterExpr.h:224
If_t< IsExpression_v< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:139
If_t< IsComputation_v< VT1 >, const RT1, CT1 > LT
Type for the assignment of the left-hand side sparse vector operand.
Definition: SVecSVecOuterExpr.h:142
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SVecSVecOuterExpr.h:110
Base class for sparse vectors.
Definition: SparseVector.h:72
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 SparseMatrix base class.
Header file for the VecTVecMultExpr base class.
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_FORM_VALID_VECTVECMULTEXPR(T1, T2)
Constraint on the data type.
Definition: VecTVecMultExpr.h:103
#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_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.
Definition: ColumnVector.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_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
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_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
Header file for the exception macros of the math module.
Header file for all forward declarations for expression class templates.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all outer product expression templates.
Definition: VecTVecMultExpr.h:69
Header file for the IsZero type trait.
Header file for basic type definitions.