Blaze  3.6
SVecDVecKronExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECDVECKRONEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECDVECKRONEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
51 #include <blaze/math/Exception.h>
57 #include <blaze/math/shims/Reset.h>
62 #include <blaze/util/Assert.h>
63 #include <blaze/util/DisableIf.h>
64 #include <blaze/util/EnableIf.h>
66 #include <blaze/util/mpl/If.h>
67 #include <blaze/util/TypeList.h>
68 #include <blaze/util/Types.h>
69 
70 
71 namespace blaze {
72 
73 //=================================================================================================
74 //
75 // CLASS SVECDVECKRONEXPR
76 //
77 //=================================================================================================
78 
79 //*************************************************************************************************
86 template< typename VT1 // Type of the left-hand side sparse vector
87  , typename VT2 // Type of the right-hand side dense vector
88  , bool TF > // Transpose flag
89 class SVecDVecKronExpr
90  : public VecVecKronExpr< SparseVector< SVecDVecKronExpr<VT1,VT2,TF>, TF > >
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****************************************************************************
123 
126 
128  using CompositeType = const ResultType;
129 
131  using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
132 
134  using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
135  //**********************************************************************************************
136 
137  //**Compilation flags***************************************************************************
139  static constexpr bool smpAssignable = false;
140  //**********************************************************************************************
141 
142  //**Constructor*********************************************************************************
148  explicit inline SVecDVecKronExpr( const VT1& lhs, const VT2& rhs ) noexcept
149  : lhs_( lhs ) // Left-hand side sparse vector of the Kronecker product expression
150  , rhs_( rhs ) // Right-hand side dense vector of the Kronecker product expression
151  {}
152  //**********************************************************************************************
153 
154  //**Subscript operator**************************************************************************
160  inline ReturnType operator[]( size_t index ) const {
161  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
162  return lhs_[index/rhs_.size()] * rhs_[index%rhs_.size()];
163  }
164  //**********************************************************************************************
165 
166  //**At function*********************************************************************************
173  inline ReturnType at( size_t index ) const {
174  if( index >= lhs_.size() ) {
175  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
176  }
177  return (*this)[index];
178  }
179  //**********************************************************************************************
180 
181  //**Size function*******************************************************************************
186  inline size_t size() const noexcept {
187  return lhs_.size() * rhs_.size();
188  }
189  //**********************************************************************************************
190 
191  //**NonZeros function***************************************************************************
196  inline size_t nonZeros() const {
197  return lhs_.nonZeros() * rhs_.size();
198  }
199  //**********************************************************************************************
200 
201  //**Left operand access*************************************************************************
206  inline LeftOperand leftOperand() const noexcept {
207  return lhs_;
208  }
209  //**********************************************************************************************
210 
211  //**Right operand access************************************************************************
216  inline RightOperand rightOperand() const noexcept {
217  return rhs_;
218  }
219  //**********************************************************************************************
220 
221  //**********************************************************************************************
227  template< typename T >
228  inline bool canAlias( const T* alias ) const noexcept {
229  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
230  }
231  //**********************************************************************************************
232 
233  //**********************************************************************************************
239  template< typename T >
240  inline bool isAliased( const T* alias ) const noexcept {
241  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
242  }
243  //**********************************************************************************************
244 
245  private:
246  //**Member variables****************************************************************************
249  //**********************************************************************************************
250 
251  //**Assignment to dense vectors*****************************************************************
263  template< typename VT > // Type of the target dense vector
264  friend inline void assign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
265  {
267 
268  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
269 
270  if( rhs.size() == 0UL ) {
271  return;
272  }
273 
274  CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
275  CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
276 
277  const size_t N( y.size() );
278  const auto xend( x.end() );
279 
280  for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
281  for( size_t j=0UL; j<N; ++j ) {
282  (~lhs)[xelem->index()*N+j] = xelem->value() * y[j];
283  }
284  }
285  }
287  //**********************************************************************************************
288 
289  //**Assignment to sparse vectors****************************************************************
301  template< typename VT > // Type of the target sparse vector
302  friend inline void assign( SparseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
303  {
305 
306  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
307 
308  if( rhs.size() == 0UL ) {
309  return;
310  }
311 
312  CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
313  CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
314 
315  const size_t N( y.size() );
316  const auto xend( x.end() );
317 
318  for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
319  for( size_t j=0UL; j<N; ++j ) {
320  (~lhs).append( xelem->index()*N+j, xelem->value() * y[j], true );
321  }
322  }
323  }
325  //**********************************************************************************************
326 
327  //**Addition assignment to dense vectors********************************************************
339  template< typename VT > // Type of the target dense vector
340  friend inline void addAssign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
341  {
343 
344  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
345 
346  if( rhs.size() == 0UL ) {
347  return;
348  }
349 
350  CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
351  CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
352 
353  const size_t N( y.size() );
354  const auto xend( x.end() );
355 
356  for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
357  for( size_t j=0UL; j<N; ++j ) {
358  (~lhs)[xelem->index()*N+j] += xelem->value() * y[j];
359  }
360  }
361  }
363  //**********************************************************************************************
364 
365  //**Addition assignment to sparse vectors*******************************************************
366  // No special implementation for the addition assignment to sparse vectors.
367  //**********************************************************************************************
368 
369  //**Subtraction assignment to dense vectors*****************************************************
382  template< typename VT > // Type of the target dense vector
383  friend inline void subAssign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
384  {
386 
387  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
388 
389  if( rhs.size() == 0UL ) {
390  return;
391  }
392 
393  CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
394  CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
395 
396  const size_t N( y.size() );
397  const auto xend( x.end() );
398 
399  for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
400  for( size_t j=0UL; j<N; ++j ) {
401  (~lhs)[xelem->index()*N+j] -= xelem->value() * y[j];
402  }
403  }
404  }
406  //**********************************************************************************************
407 
408  //**Subtraction assignment to sparse vectors****************************************************
409  // No special implementation for the subtraction assignment to sparse vectors.
410  //**********************************************************************************************
411 
412  //**Multiplication assignment to dense vectors**************************************************
425  template< typename VT > // Type of the target dense vector
426  friend inline void multAssign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
427  {
429 
430  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
431 
432  if( rhs.size() == 0UL ) {
433  return;
434  }
435 
436  CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
437  CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
438 
439  const size_t N( y.size() );
440  const auto xend( x.end() );
441  size_t i( 0UL );
442 
443  for( auto xelem=x.begin(); xelem!=xend; ++xelem, ++i )
444  {
445  for( ; i<xelem->index(); ++i ) {
446  for( size_t j=0UL; j<N; ++j )
447  reset( (~lhs)[i*N+j] );
448  }
449 
450  for( size_t j=0UL; j<N; ++j ) {
451  (~lhs)[xelem->index()*N+j] *= xelem->value() * y[j];
452  }
453  }
454 
455  for( ; i<x.size(); ++i ) {
456  for( size_t j=0UL; j<N; ++j )
457  reset( (~lhs)[i*N+j] );
458  }
459  }
461  //**********************************************************************************************
462 
463  //**Multiplication assignment to sparse vectors*************************************************
464  // No special implementation for the multiplication assignment to sparse vectors.
465  //**********************************************************************************************
466 
467  //**Compile time checks*************************************************************************
476  //**********************************************************************************************
477 };
478 //*************************************************************************************************
479 
480 
481 
482 
483 //=================================================================================================
484 //
485 // GLOBAL FUNCTIONS
486 //
487 //=================================================================================================
488 
489 //*************************************************************************************************
502 template< typename VT1 // Type of the left-hand side sparse vector
503  , typename VT2 // Type of the right-hand side dense vector
504  , bool TF // Transpose flag
505  , DisableIf_t< IsZero_v<VT1> >* = nullptr >
506 inline const SVecDVecKronExpr<VT1,VT2,TF>
507  svecdveckron( const SparseVector<VT1,TF>& lhs, const DenseVector<VT2,TF>& rhs )
508 {
510 
511  return SVecDVecKronExpr<VT1,VT2,TF>( ~lhs, ~rhs );
512 }
514 //*************************************************************************************************
515 
516 
517 //*************************************************************************************************
530 template< typename VT1 // Type of the left-hand side sparse vector
531  , typename VT2 // Type of the right-hand side dense vector
532  , bool TF // Transpose flag
533  , EnableIf_t< IsZero_v<VT1> >* = nullptr >
534 inline decltype(auto)
535  svecdveckron( const SparseVector<VT1,TF>& lhs, const DenseVector<VT2,TF>& rhs )
536 {
538 
539  using ReturnType = const KronTrait_t< ResultType_t<VT1>, ResultType_t<VT2> >;
540 
543 
544  return ReturnType( (~lhs).size()*(~rhs).size() );
545 }
547 //*************************************************************************************************
548 
549 
550 //*************************************************************************************************
572 template< typename VT1 // Type of the left-hand side sparse vector
573  , typename VT2 // Type of the right-hand side dense vector
574  , bool TF > // Transpose flag
575 inline decltype(auto)
576  kron( const SparseVector<VT1,TF>& lhs, const DenseVector<VT2,TF>& rhs )
577 {
579 
580  return svecdveckron( ~lhs, ~rhs );
581 }
582 //*************************************************************************************************
583 
584 } // namespace blaze
585 
586 #endif
Header file for auxiliary alias declarations.
Header file for the alignment flag values.
Header file for basic type definitions.
Header file for the SparseVector base class.
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SVecDVecKronExpr.h:120
ReturnType_t< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:98
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
CompositeType_t< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:100
Header file for the serial shim.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SVecDVecKronExpr.h:128
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
Constraint on the data type.
Header file for the DenseVector base class.
Constraint on the data type.
Header file for the Computation base class.
Header file for the reset shim.
LeftOperand lhs_
Left-hand side sparse vector of the Kronecker product expression.
Definition: SVecDVecKronExpr.h:247
CompositeType_t< VT1 > CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:99
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
decltype(auto) kron(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the Kronecker product of two dense matrices ( ).
Definition: DMatDMatKronExpr.h:954
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: SVecDVecKronExpr.h:216
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SVecDVecKronExpr.h:110
SVecDVecKronExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the SVecDVecKronExpr class.
Definition: SVecDVecKronExpr.h:148
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: SVecDVecKronExpr.h:186
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse vector.
Definition: SVecDVecKronExpr.h:196
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type,...
Definition: Zero.h:61
typename KronTrait< T1, T2 >::Type KronTrait_t
Auxiliary alias declaration for the KronTrait class template.The KronTrait_t alias declaration provid...
Definition: KronTrait.h:163
#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
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:76
Header file for the VecVecKronExpr base class.
#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
Constraint on the data type.
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SVecDVecKronExpr.h:160
Header file for the Kron product trait.
ReturnType_t< VT1 > RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:97
If_t< IsExpression_v< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:134
Constraint on the data type.
Header file for the exception macros of the math module.
Constraint on the data type.
Header file for the EnableIf class template.
ResultType_t< VT1 > RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:95
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecDVecKronExpr.h:206
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecDVecKronExpr.h:228
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SVecDVecKronExpr.h:139
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecDVecKronExpr.h:125
Header file for the Unique class template.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecDVecKronExpr.h:240
Expression object for sparse vector-dense vector Kronecker products.The SVecDVecKronExpr class repres...
Definition: Forward.h:149
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecDVecKronExpr.h:121
Header file for the IsZero type trait.
#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
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SVecDVecKronExpr.h:122
If_t< IsExpression_v< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:131
ResultType_t< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:96
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type,...
Definition: DenseVector.h:61
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SVecDVecKronExpr.h:113
RightOperand rhs_
Right-hand side dense vector of the Kronecker product expression.
Definition: SVecDVecKronExpr.h:248
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: SVecDVecKronExpr.h:173
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_VECVECKRONEXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid vector/vector ...
Definition: VecVecKronExpr.h:102
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:146
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type,...
Definition: Zero.h:81
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
Header file for the IsExpression type trait class.
Header file for the function trace functionality.