Blaze 3.9
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>
63#include <blaze/util/Assert.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
71namespace blaze {
72
73//=================================================================================================
74//
75// CLASS SVECDVECKRONEXPR
76//
77//=================================================================================================
78
79//*************************************************************************************************
86template< 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
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****************************************************************************
120
123
127
130
133
135 using LeftOperand = If_t< IsExpression_v<VT1>, const VT1, const VT1& >;
136
138 using RightOperand = If_t< IsExpression_v<VT2>, const VT2, const VT2& >;
139 //**********************************************************************************************
140
141 //**Compilation flags***************************************************************************
143 static constexpr bool smpAssignable = false;
144 //**********************************************************************************************
145
146 //**Constructor*********************************************************************************
152 inline SVecDVecKronExpr( const VT1& lhs, const VT2& rhs ) noexcept
153 : lhs_( lhs ) // Left-hand side sparse vector of the Kronecker product expression
154 , rhs_( rhs ) // Right-hand side dense vector of the Kronecker product expression
155 {}
156 //**********************************************************************************************
157
158 //**Subscript operator**************************************************************************
164 inline ReturnType operator[]( size_t index ) const {
165 BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
166 return lhs_[index/rhs_.size()] * rhs_[index%rhs_.size()];
167 }
168 //**********************************************************************************************
169
170 //**At function*********************************************************************************
177 inline ReturnType at( size_t index ) const {
178 if( index >= lhs_.size() ) {
179 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
180 }
181 return (*this)[index];
182 }
183 //**********************************************************************************************
184
185 //**Size function*******************************************************************************
190 inline size_t size() const noexcept {
191 return lhs_.size() * rhs_.size();
192 }
193 //**********************************************************************************************
194
195 //**NonZeros function***************************************************************************
200 inline size_t nonZeros() const {
201 return lhs_.nonZeros() * rhs_.size();
202 }
203 //**********************************************************************************************
204
205 //**Left operand access*************************************************************************
210 inline LeftOperand leftOperand() const noexcept {
211 return lhs_;
212 }
213 //**********************************************************************************************
214
215 //**Right operand access************************************************************************
220 inline RightOperand rightOperand() const noexcept {
221 return rhs_;
222 }
223 //**********************************************************************************************
224
225 //**********************************************************************************************
231 template< typename T >
232 inline bool canAlias( const T* alias ) const noexcept {
233 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
234 }
235 //**********************************************************************************************
236
237 //**********************************************************************************************
243 template< typename T >
244 inline bool isAliased( const T* alias ) const noexcept {
245 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
246 }
247 //**********************************************************************************************
248
249 private:
250 //**Member variables****************************************************************************
253 //**********************************************************************************************
254
255 //**Assignment to dense vectors*****************************************************************
267 template< typename VT > // Type of the target dense vector
268 friend inline void assign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
269 {
271
272 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
273
274 if( rhs.size() == 0UL ) {
275 return;
276 }
277
278 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
279 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
280
281 const size_t N( y.size() );
282 const auto xend( x.end() );
283
284 for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
285 for( size_t j=0UL; j<N; ++j ) {
286 (*lhs)[xelem->index()*N+j] = xelem->value() * y[j];
287 }
288 }
289 }
291 //**********************************************************************************************
292
293 //**Assignment to sparse vectors****************************************************************
305 template< typename VT > // Type of the target sparse vector
306 friend inline void assign( SparseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
307 {
309
310 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
311
312 if( rhs.size() == 0UL ) {
313 return;
314 }
315
316 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
317 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
318
319 const size_t N( y.size() );
320 const auto xend( x.end() );
321
322 for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
323 for( size_t j=0UL; j<N; ++j ) {
324 (*lhs).append( xelem->index()*N+j, xelem->value() * y[j], true );
325 }
326 }
327 }
329 //**********************************************************************************************
330
331 //**Addition assignment to dense vectors********************************************************
343 template< typename VT > // Type of the target dense vector
344 friend inline void addAssign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
345 {
347
348 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
349
350 if( rhs.size() == 0UL ) {
351 return;
352 }
353
354 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
355 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
356
357 const size_t N( y.size() );
358 const auto xend( x.end() );
359
360 for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
361 for( size_t j=0UL; j<N; ++j ) {
362 (*lhs)[xelem->index()*N+j] += xelem->value() * y[j];
363 }
364 }
365 }
367 //**********************************************************************************************
368
369 //**Addition assignment to sparse vectors*******************************************************
370 // No special implementation for the addition assignment to sparse vectors.
371 //**********************************************************************************************
372
373 //**Subtraction assignment to dense vectors*****************************************************
386 template< typename VT > // Type of the target dense vector
387 friend inline void subAssign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
388 {
390
391 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
392
393 if( rhs.size() == 0UL ) {
394 return;
395 }
396
397 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
398 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
399
400 const size_t N( y.size() );
401 const auto xend( x.end() );
402
403 for( auto xelem=x.begin(); xelem!=xend; ++xelem ) {
404 for( size_t j=0UL; j<N; ++j ) {
405 (*lhs)[xelem->index()*N+j] -= xelem->value() * y[j];
406 }
407 }
408 }
410 //**********************************************************************************************
411
412 //**Subtraction assignment to sparse vectors****************************************************
413 // No special implementation for the subtraction assignment to sparse vectors.
414 //**********************************************************************************************
415
416 //**Multiplication assignment to dense vectors**************************************************
429 template< typename VT > // Type of the target dense vector
430 friend inline void multAssign( DenseVector<VT,TF>& lhs, const SVecDVecKronExpr& rhs )
431 {
433
434 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
435
436 if( rhs.size() == 0UL ) {
437 return;
438 }
439
440 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse vector operand
441 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
442
443 const size_t N( y.size() );
444 const auto xend( x.end() );
445 size_t i( 0UL );
446
447 for( auto xelem=x.begin(); xelem!=xend; ++xelem, ++i )
448 {
449 for( ; i<xelem->index(); ++i ) {
450 for( size_t j=0UL; j<N; ++j )
451 reset( (*lhs)[i*N+j] );
452 }
453
454 for( size_t j=0UL; j<N; ++j ) {
455 (*lhs)[xelem->index()*N+j] *= xelem->value() * y[j];
456 }
457 }
458
459 for( ; i<x.size(); ++i ) {
460 for( size_t j=0UL; j<N; ++j )
461 reset( (*lhs)[i*N+j] );
462 }
463 }
465 //**********************************************************************************************
466
467 //**Multiplication assignment to sparse vectors*************************************************
468 // No special implementation for the multiplication assignment to sparse vectors.
469 //**********************************************************************************************
470
471 //**Compile time checks*************************************************************************
480 //**********************************************************************************************
481};
482//*************************************************************************************************
483
484
485
486
487//=================================================================================================
488//
489// GLOBAL FUNCTIONS
490//
491//=================================================================================================
492
493//*************************************************************************************************
506template< typename VT1 // Type of the left-hand side sparse vector
507 , typename VT2 // Type of the right-hand side dense vector
508 , bool TF // Transpose flag
509 , DisableIf_t< IsZero_v<VT1> >* = nullptr >
510inline const SVecDVecKronExpr<VT1,VT2,TF>
511 svecdveckron( const SparseVector<VT1,TF>& lhs, const DenseVector<VT2,TF>& rhs )
512{
514
515 return SVecDVecKronExpr<VT1,VT2,TF>( *lhs, *rhs );
516}
518//*************************************************************************************************
519
520
521//*************************************************************************************************
534template< typename VT1 // Type of the left-hand side sparse vector
535 , typename VT2 // Type of the right-hand side dense vector
536 , bool TF // Transpose flag
537 , EnableIf_t< IsZero_v<VT1> >* = nullptr >
538inline decltype(auto)
539 svecdveckron( const SparseVector<VT1,TF>& lhs, const DenseVector<VT2,TF>& rhs )
540{
542
543 using ReturnType = const KronTrait_t< ResultType_t<VT1>, ResultType_t<VT2> >;
544
547
548 return ReturnType( (*lhs).size()*(*rhs).size() );
549}
551//*************************************************************************************************
552
553
554//*************************************************************************************************
576template< typename VT1 // Type of the left-hand side sparse vector
577 , typename VT2 // Type of the right-hand side dense vector
578 , bool TF > // Transpose flag
579inline decltype(auto)
581{
583
584 return svecdveckron( *lhs, *rhs );
585}
586//*************************************************************************************************
587
588} // namespace blaze
589
590#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::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.
Definition: Aliases.h:550
Header file for the alignment flag enumeration.
Header file for run time assertion macros.
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 IsExpression type trait class.
Header file for the IsTemporary type trait class.
Header file for the Kron product trait.
Deactivation of problematic macros.
Header file for the type list functionality.
Constraint on the data type.
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Expression object for sparse vector-dense vector Kronecker products.
Definition: SVecDVecKronExpr.h:92
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SVecDVecKronExpr.h:164
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SVecDVecKronExpr.h:125
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SVecDVecKronExpr.h:113
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SVecDVecKronExpr.h:143
CompositeType_t< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:100
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: SVecDVecKronExpr.h:177
ResultType_t< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:96
If_t< IsExpression_v< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:135
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SVecDVecKronExpr.h:124
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SVecDVecKronExpr.h:110
ReturnType_t< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:98
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: SVecDVecKronExpr.h:220
LeftOperand lhs_
Left-hand side sparse vector of the Kronecker product expression.
Definition: SVecDVecKronExpr.h:251
ReturnType_t< VT1 > RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:97
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SVecDVecKronExpr.h:129
const ResultType CompositeType
Data type for composite expression templates.
Definition: SVecDVecKronExpr.h:132
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse vector operand.
Definition: SVecDVecKronExpr.h:210
ResultType_t< VT1 > RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:95
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SVecDVecKronExpr.h:232
CompositeType_t< VT1 > CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecDVecKronExpr.h:99
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: SVecDVecKronExpr.h:190
SVecDVecKronExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the SVecDVecKronExpr class.
Definition: SVecDVecKronExpr.h:152
RightOperand rhs_
Right-hand side dense vector of the Kronecker product expression.
Definition: SVecDVecKronExpr.h:252
If_t< IsExpression_v< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: SVecDVecKronExpr.h:138
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SVecDVecKronExpr.h:126
size_t nonZeros() const
Returns the number of non-zero elements in the sparse vector.
Definition: SVecDVecKronExpr.h:200
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SVecDVecKronExpr.h:244
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 DenseVector base class.
Header file for the SparseVector base class.
Header file for the VecVecKronExpr 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
decltype(auto) kron(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the Kronecker product of two dense matrices ( ).
Definition: DMatDMatKronExpr.h:957
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.
Definition: TransposeFlag.h:63
#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_DENSE_VECTOR_TYPE(T)
Constraint on the data type.
Definition: DenseVector.h:61
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_VECVECKRONEXPR(T1, T2)
Constraint on the data type.
Definition: VecVecKronExpr.h:102
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.
Definition: Zero.h:61
typename KronTrait< T1, T2 >::Type KronTrait_t
Auxiliary alias declaration for the KronTrait class template.
Definition: KronTrait.h:137
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.
Constraint on the data type.
Header file for the reset shim.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all vector/vector Kronecker expression templates.
Definition: VecVecKronExpr.h:69
Header file for the IsZero type trait.
Header file for basic type definitions.