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 <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
63 #include <blaze/util/Assert.h>
65 #include <blaze/util/mpl/If.h>
66 #include <blaze/util/Types.h>
68 
69 
70 namespace blaze {
71 
72 //=================================================================================================
73 //
74 // CLASS SVECSVECOUTEREXPR
75 //
76 //=================================================================================================
77 
78 //*************************************************************************************************
85 template< typename VT1 // Type of the left-hand side sparse vector
86  , typename VT2 > // Type of the right-hand side sparse vector
87 class SVecSVecOuterExpr
88  : public VecTVecMultExpr< SparseMatrix< SVecSVecOuterExpr<VT1,VT2>, false > >
89  , private Computation
90 {
91  private:
92  //**Type definitions****************************************************************************
99  //**********************************************************************************************
100 
101  //**Return type evaluation**********************************************************************
103 
108  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
109 
112  //**********************************************************************************************
113 
114  public:
115  //**Type definitions****************************************************************************
121 
124 
126  using CompositeType = const ResultType;
127 
129  using LeftOperand = If_< IsExpression<VT1>, const VT1, const VT1& >;
130 
132  using RightOperand = If_< IsExpression<VT2>, const VT2, const VT2& >;
133 
135  using LT = If_< IsComputation<VT1>, const RT1, CT1 >;
136 
138  using RT = If_< IsComputation<VT2>, const RT2, CT2 >;
139  //**********************************************************************************************
140 
141  //**Compilation flags***************************************************************************
143  enum : bool { smpAssignable = false };
144  //**********************************************************************************************
145 
146  //**Constructor*********************************************************************************
152  explicit inline SVecSVecOuterExpr( const VT1& lhs, const VT2& rhs ) noexcept
153  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
154  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
155  {}
156  //**********************************************************************************************
157 
158  //**Access operator*****************************************************************************
165  inline ReturnType operator()( size_t i, size_t j ) const {
166  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
167  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
168 
169  return lhs_[i] * rhs_[j];
170  }
171  //**********************************************************************************************
172 
173  //**At function*********************************************************************************
181  inline ReturnType at( size_t i, size_t j ) const {
182  if( i >= lhs_.size() ) {
183  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
184  }
185  if( j >= rhs_.size() ) {
186  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
187  }
188  return (*this)(i,j);
189  }
190  //**********************************************************************************************
191 
192  //**Rows function*******************************************************************************
197  inline size_t rows() const noexcept {
198  return lhs_.size();
199  }
200  //**********************************************************************************************
201 
202  //**Columns function****************************************************************************
207  inline size_t columns() const noexcept {
208  return rhs_.size();
209  }
210  //**********************************************************************************************
211 
212  //**NonZeros function***************************************************************************
217  inline size_t nonZeros() const {
218  return lhs_.nonZeros() * rhs_.nonZeros();
219  }
220  //**********************************************************************************************
221 
222  //**NonZeros function***************************************************************************
228  inline size_t nonZeros( size_t i ) const {
229  return ( isDefault( lhs_[i] ) )?( size_t(0) ):( rhs_.nonZeros(i) );
230  }
231  //**********************************************************************************************
232 
233  //**Left operand access*************************************************************************
238  inline LeftOperand leftOperand() const noexcept {
239  return lhs_;
240  }
241  //**********************************************************************************************
242 
243  //**Right operand access************************************************************************
248  inline RightOperand rightOperand() const noexcept {
249  return rhs_;
250  }
251  //**********************************************************************************************
252 
253  //**********************************************************************************************
259  template< typename T >
260  inline bool canAlias( const T* alias ) const noexcept {
261  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
262  }
263  //**********************************************************************************************
264 
265  //**********************************************************************************************
271  template< typename T >
272  inline bool isAliased( const T* alias ) const noexcept {
273  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
274  }
275  //**********************************************************************************************
276 
277  private:
278  //**Member variables****************************************************************************
281  //**********************************************************************************************
282 
283  //**Assignment to row-major dense matrices******************************************************
295  template< typename MT > // Type of the target dense matrix
296  friend inline void assign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
297  {
299 
300  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
301  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
302 
303  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
304  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
305 
306  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
307  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
308 
309  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
310  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
311  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
312  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
313 
314  const LeftIterator lend( x.end() );
315  const RightIterator rend( y.end() );
316 
317  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
318  if( !isDefault( lelem->value() ) ) {
319  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
320  (~lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
321  }
322  }
323  }
324  }
326  //**********************************************************************************************
327 
328  //**Assignment to column-major dense matrices***************************************************
341  template< typename MT > // Type of the target dense matrix
342  friend inline void assign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
343  {
345 
347 
348  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
349  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
350 
351  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
352  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
353 
354  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
355  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
356 
357  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
358  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
359  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
360  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
361 
362  const LeftIterator lend( x.end() );
363  const RightIterator rend( y.end() );
364 
365  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
366  if( !isDefault( relem->value() ) ) {
367  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
368  (~lhs)(lelem->index(),relem->index()) = lelem->value() * relem->value();
369  }
370  }
371  }
372  }
374  //**********************************************************************************************
375 
376  //**Assignment to row-major sparse matrices*****************************************************
388  template< typename MT > // Type of the target sparse matrix
389  friend inline void assign( SparseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
390  {
392 
393  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
394  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
395  BLAZE_INTERNAL_ASSERT( (~lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
396 
397  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
398  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
399 
400  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
401  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
402 
403  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
404  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
405  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
406  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
407 
408  // Final memory allocation (based on the evaluated operands)
409  (~lhs).reserve( x.nonZeros() * y.nonZeros() );
410 
411  // Performing the outer product
412  const LeftIterator lend( x.end() );
413  const RightIterator rend( y.end() );
414  size_t index( 0UL );
415 
416  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
417  if( !isDefault( lelem->value() ) ) {
418  for( ; index < lelem->index(); ++index ) {
419  (~lhs).finalize( index );
420  }
421  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
422  (~lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
423  }
424  (~lhs).finalize( index++ );
425  }
426  }
427 
428  for( ; index < x.size(); ++index ) {
429  (~lhs).finalize( index );
430  }
431  }
433  //**********************************************************************************************
434 
435  //**Assignment to column-major sparse matrices**************************************************
448  template< typename MT > // Type of the target sparse matrix
449  friend inline void assign( SparseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
450  {
452 
454 
455  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
456  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns() , "Invalid number of columns" );
457  BLAZE_INTERNAL_ASSERT( (~lhs).capacity() >= rhs.nonZeros(), "Insufficient capacity" );
458 
459  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
460  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
461 
462  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
463  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
464 
465  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
466  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
467  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
468  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
469 
470  const LeftIterator lend( x.end() );
471  const RightIterator rend( y.end() );
472  size_t index( 0UL );
473 
474  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
475  if( !isDefault( relem->value() ) ) {
476  for( ; index < relem->index(); ++index ) {
477  (~lhs).finalize( index );
478  }
479  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
480  (~lhs).append( lelem->index(), relem->index(), lelem->value() * relem->value() );
481  }
482  (~lhs).finalize( index++ );
483  }
484  }
485 
486  for( ; index < y.size(); ++index ) {
487  (~lhs).finalize( index );
488  }
489  }
491  //**********************************************************************************************
492 
493  //**Addition assignment to row-major dense matrices*********************************************
506  template< typename MT > // Type of the target dense matrix
507  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
508  {
510 
511  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
512  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
513 
514  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
515  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
516 
517  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
518  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
519 
520  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
521  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
522  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
523  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
524 
525  const LeftIterator lend( x.end() );
526  const RightIterator rend( y.end() );
527 
528  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
529  if( !isDefault( lelem->value() ) ) {
530  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
531  (~lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
532  }
533  }
534  }
535  }
537  //**********************************************************************************************
538 
539  //**Addition assignment to column-major dense matrices******************************************
552  template< typename MT > // Type of the target dense matrix
553  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
554  {
556 
558 
559  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
560  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
561 
562  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
563  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
564 
565  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
566  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
567 
568  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
569  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
570  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
571  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
572 
573  const LeftIterator lend( x.end() );
574  const RightIterator rend( y.end() );
575 
576  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
577  if( !isDefault( relem->value() ) ) {
578  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
579  (~lhs)(lelem->index(),relem->index()) += lelem->value() * relem->value();
580  }
581  }
582  }
583  }
585  //**********************************************************************************************
586 
587  //**Addition assignment to sparse matrices******************************************************
588  // No special implementation for the addition assignment to sparse matrices.
589  //**********************************************************************************************
590 
591  //**Subtraction assignment to row-major dense matrices******************************************
604  template< typename MT > // Type of the target dense matrix
605  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
606  {
608 
609  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
610  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
611 
612  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
613  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
614 
615  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
616  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
617 
618  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
619  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
620  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
621  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
622 
623  const LeftIterator lend( x.end() );
624  const RightIterator rend( y.end() );
625 
626  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
627  if( !isDefault( lelem->value() ) ) {
628  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
629  (~lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
630  }
631  }
632  }
633  }
635  //**********************************************************************************************
636 
637  //**Subtraction assignment to column-major dense matrices***************************************
650  template< typename MT > // Type of the target dense matrix
651  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
652  {
654 
656 
657  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
658  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
659 
660  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
661  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
662 
663  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
664  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
665 
666  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
667  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
668  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
669  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
670 
671  const LeftIterator lend( x.end() );
672  const RightIterator rend( y.end() );
673 
674  for( RightIterator relem=y.begin(); relem!=rend; ++relem ) {
675  if( !isDefault( relem->value() ) ) {
676  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem ) {
677  (~lhs)(lelem->index(),relem->index()) -= lelem->value() * relem->value();
678  }
679  }
680  }
681  }
683  //**********************************************************************************************
684 
685  //**Subtraction assignment to sparse matrices***************************************************
686  // No special implementation for the subtraction assignment to sparse matrices.
687  //**********************************************************************************************
688 
689  //**Schur product assignment to row-major dense matrices****************************************
702  template< typename MT > // Type of the target dense matrix
703  friend inline void schurAssign( DenseMatrix<MT,false>& lhs, const SVecSVecOuterExpr& rhs )
704  {
706 
707  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
708  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
709 
710  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
711  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
712 
713  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
714  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
715 
716  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
717  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
718  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
719  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
720 
721  const LeftIterator lend( x.end() );
722  const RightIterator rend( y.end() );
723 
724  size_t i( 0UL );
725 
726  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem )
727  {
728  if( isDefault( lelem->value() ) ) continue;
729 
730  for( ; i<lelem->index(); ++i ) {
731  for( size_t j=0UL; j<y.size(); ++j )
732  reset( (~lhs)(i,j) );
733  }
734 
735  size_t j( 0UL );
736 
737  for( RightIterator relem=y.begin(); relem!=rend; ++relem, ++j ) {
738  for( ; j<relem->index(); ++j )
739  reset( (~lhs)(i,j) );
740  (~lhs)(lelem->index(),relem->index()) *= lelem->value() * relem->value();
741  }
742 
743  for( ; j<y.size(); ++j ) {
744  reset( (~lhs)(i,j) );
745  }
746 
747  ++i;
748  }
749 
750  for( ; i<x.size(); ++i ) {
751  for( size_t j=0UL; j<y.size(); ++j )
752  reset( (~lhs)(i,j) );
753  }
754  }
756  //**********************************************************************************************
757 
758  //**Schur product assignment to column-major dense matrices*************************************
771  template< typename MT > // Type of the target dense matrix
772  friend inline void schurAssign( DenseMatrix<MT,true>& lhs, const SVecSVecOuterExpr& rhs )
773  {
775 
777 
778  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
779  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
780 
781  using LeftIterator = ConstIterator_< RemoveReference_<LT> >;
782  using RightIterator = ConstIterator_< RemoveReference_<RT> >;
783 
784  LT x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
785  RT y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse vector operand
786 
787  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
788  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
789  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
790  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
791 
792  const LeftIterator lend( x.end() );
793  const RightIterator rend( y.end() );
794 
795  size_t j( 0UL );
796 
797  for( RightIterator relem=y.begin(); relem!=rend; ++relem )
798  {
799  if( isDefault( relem->value() ) ) continue;
800 
801  for( ; j<relem->index(); ++j ) {
802  for( size_t i=0UL; i<x.size(); ++i )
803  reset( (~lhs)(i,j) );
804  }
805 
806  size_t i( 0UL );
807 
808  for( LeftIterator lelem=x.begin(); lelem!=lend; ++lelem, ++i ) {
809  for( ; i<lelem->index(); ++i )
810  reset( (~lhs)(i,j) );
811  (~lhs)(lelem->index(),relem->index()) *= lelem->value() * relem->value();
812  }
813 
814  for( ; i<x.size(); ++i ) {
815  reset( (~lhs)(i,j) );
816  }
817 
818  ++j;
819  }
820 
821  for( ; j<y.size(); ++j ) {
822  for( size_t i=0UL; i<x.size(); ++i )
823  reset( (~lhs)(i,j) );
824  }
825  }
827  //**********************************************************************************************
828 
829  //**Schur product assignment to sparse matrices*************************************************
830  // No special implementation for the Schur product assignment to sparse matrices.
831  //**********************************************************************************************
832 
833  //**Multiplication assignment to dense matrices*************************************************
834  // No special implementation for the multiplication assignment to dense matrices.
835  //**********************************************************************************************
836 
837  //**Multiplication assignment to sparse matrices************************************************
838  // No special implementation for the multiplication assignment to sparse matrices.
839  //**********************************************************************************************
840 
841  //**Compile time checks*************************************************************************
849  //**********************************************************************************************
850 };
851 //*************************************************************************************************
852 
853 
854 
855 
856 //=================================================================================================
857 //
858 // GLOBAL BINARY ARITHMETIC OPERATORS
859 //
860 //=================================================================================================
861 
862 //*************************************************************************************************
889 template< typename VT1 // Type of the left-hand side sparse vector
890  , typename VT2 > // Type of the right-hand side sparse vector
891 inline decltype(auto)
892  operator*( const SparseVector<VT1,false>& lhs, const SparseVector<VT2,true>& rhs )
893 {
895 
897  return ReturnType( ~lhs, ~rhs );
898 }
899 //*************************************************************************************************
900 
901 
902 
903 
904 //=================================================================================================
905 //
906 // SIZE SPECIALIZATIONS
907 //
908 //=================================================================================================
909 
910 //*************************************************************************************************
912 template< typename VT1, typename VT2 >
913 struct Size< SVecSVecOuterExpr<VT1,VT2>, 0UL >
914  : public Size<VT1,0UL>
915 {};
916 
917 template< typename VT1, typename VT2 >
918 struct Size< SVecSVecOuterExpr<VT1,VT2>, 1UL >
919  : public Size<VT2,0UL>
920 {};
922 //*************************************************************************************************
923 
924 } // namespace blaze
925 
926 #endif
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SVecSVecOuterExpr.h:118
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecSVecOuterExpr.h:238
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecSVecOuterExpr.h:119
Header file for auxiliary alias declarations.
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
ReturnType_< VT2 > RN2
Return type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:96
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SVecSVecOuterExpr.h:165
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
Expression object for sparse vector-sparse vector outer products.The SVecSVecOuterExpr class represen...
Definition: Forward.h:144
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:61
Header file for the serial shim.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:291
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SVecSVecOuterExpr.h:197
Header file for the Computation base class.
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse vector operand.
Definition: SVecSVecOuterExpr.h:248
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
CompositeType_< VT1 > CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:97
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SVecSVecOuterExpr.h:228
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SVecSVecOuterExpr.h:217
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecSVecOuterExpr.h:123
Header file for the SparseMatrix base class.
Constraint on the transpose flag of vector types.
RightOperand rhs_
Right-hand side sparse vector of the multiplication expression.
Definition: SVecSVecOuterExpr.h:280
Constraint on the data type.
typename MultExprTrait< T1, T2 >::Type MultExprTrait_
Auxiliary alias declaration for the MultExprTrait class template.The MultExprTrait_ alias declaration...
Definition: MultExprTrait.h:112
Header file for the MultExprTrait class template.
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
ResultType_< VT1 > RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:93
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
If_< IsComputation< VT1 >, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense vector operand.
Definition: SVecSVecOuterExpr.h:135
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_VECTVECMULTEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/vector ...
Definition: VecTVecMultExpr.h:104
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:61
SVecSVecOuterExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the SVecSVecOuterExpr class.
Definition: SVecSVecOuterExpr.h:152
If_< IsComputation< VT2 >, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense vector operand.
Definition: SVecSVecOuterExpr.h:138
MultTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SVecSVecOuterExpr.h:117
Header file for the exception macros of the math module.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
Header file for the VecTVecMultExpr base class.
If_< IsExpression< VT2 >, const VT2, const VT2 &> RightOperand
Composite type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:132
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
Header file for run time assertion macros.
MultExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: SVecSVecOuterExpr.h:111
CompositeType_< VT2 > CT2
Composite type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:98
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for the isDefault shim.
Constraint on the data type.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
Constraint on the data type.
ReturnType_< VT1 > RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:95
Header file for the RemoveReference type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SVecSVecOuterExpr.h:207
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SVecSVecOuterExpr.h:181
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
const ResultType CompositeType
Data type for composite expression templates.
Definition: SVecSVecOuterExpr.h:126
Header file for the IsComputation type trait class.
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecSVecOuterExpr.h:260
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:130
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SVecSVecOuterExpr.h:120
ResultType_< VT2 > RT2
Result type of the right-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:94
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: RowVector.h:61
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecSVecOuterExpr.h:272
Header file for the Size type trait.
Size type of the Blaze library.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Constraint on the transpose flag of vector types.
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
If_< IsExpression< VT1 >, const VT1, const VT1 &> LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecSVecOuterExpr.h:129
LeftOperand lhs_
Left-hand side sparse vector of the multiplication expression.
Definition: SVecSVecOuterExpr.h:279