Blaze 3.9
DVecDVecKronExpr.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECKRONEXPR_H_
36#define _BLAZE_MATH_EXPRESSIONS_DVECDVECKRONEXPR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <utility>
44#include <blaze/math/Aliases.h>
62#include <blaze/util/Assert.h>
64#include <blaze/util/mpl/If.h>
65#include <blaze/util/TypeList.h>
66#include <blaze/util/Types.h>
67
68
69namespace blaze {
70
71//=================================================================================================
72//
73// CLASS DVECDVECKRONEXPR
74//
75//=================================================================================================
76
77//*************************************************************************************************
84template< typename VT1 // Type of the left-hand side dense vector
85 , typename VT2 // Type of the right-hand side dense vector
86 , bool TF > // Transpose flag
88 : public VecVecKronExpr< DenseVector< DVecDVecKronExpr<VT1,VT2,TF>, TF > >
89 , private Computation
90{
91 private:
92 //**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 simdEnabled = false;
144
146 static constexpr bool smpAssignable = false;
147 //**********************************************************************************************
148
149 //**Constructor*********************************************************************************
155 inline DVecDVecKronExpr( const VT1& lhs, const VT2& rhs ) noexcept
156 : lhs_( lhs ) // Left-hand side dense vector of the Kronecker product expression
157 , rhs_( rhs ) // Right-hand side dense vector of the Kronecker product expression
158 {}
159 //**********************************************************************************************
160
161 //**Subscript operator**************************************************************************
167 inline ReturnType operator[]( size_t index ) const {
168 BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
169 return lhs_[index/rhs_.size()] * rhs_[index%rhs_.size()];
170 }
171 //**********************************************************************************************
172
173 //**At function*********************************************************************************
180 inline ReturnType at( size_t index ) const {
181 if( index >= lhs_.size() ) {
182 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
183 }
184 return (*this)[index];
185 }
186 //**********************************************************************************************
187
188 //**Size function*******************************************************************************
193 inline size_t size() const noexcept {
194 return lhs_.size() * rhs_.size();
195 }
196 //**********************************************************************************************
197
198 //**Left operand access*************************************************************************
203 inline LeftOperand leftOperand() const noexcept {
204 return lhs_;
205 }
206 //**********************************************************************************************
207
208 //**Right operand access************************************************************************
213 inline RightOperand rightOperand() const noexcept {
214 return rhs_;
215 }
216 //**********************************************************************************************
217
218 //**********************************************************************************************
224 template< typename T >
225 inline bool canAlias( const T* alias ) const noexcept {
226 return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
227 }
228 //**********************************************************************************************
229
230 //**********************************************************************************************
236 template< typename T >
237 inline bool isAliased( const T* alias ) const noexcept {
238 return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
239 }
240 //**********************************************************************************************
241
242 //**********************************************************************************************
247 inline bool isAligned() const noexcept {
248 return rhs_.isAligned();
249 }
250 //**********************************************************************************************
251
252 //**********************************************************************************************
257 inline bool canSMPAssign() const noexcept {
258 return false;
259 }
260 //**********************************************************************************************
261
262 private:
263 //**Member variables****************************************************************************
266 //**********************************************************************************************
267
268 //**Assignment to dense vectors*****************************************************************
280 template< typename VT > // Type of the target dense vector
281 friend inline void assign( DenseVector<VT,TF>& lhs, const DVecDVecKronExpr& rhs )
282 {
284
285 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
286
287 if( rhs.size() == 0UL ) {
288 return;
289 }
290
291 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
292 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
293
294 const size_t N( y.size() );
295
296 for( size_t i=0UL; i<x.size(); ++i ) {
297 if( !isDefault<strict>( x[i] ) ) {
298 for( size_t j=0UL; j<N; ++j )
299 (*lhs)[i*N+j] = x[i] * y[j];
300 }
301 else {
302 for( size_t j=0UL; j<N; ++j )
303 reset( (*lhs)[i*N+j] );
304 }
305 }
306 }
308 //**********************************************************************************************
309
310 //**Assignment to sparse vectors****************************************************************
322 template< typename VT > // Type of the target sparse vector
323 friend inline void assign( SparseVector<VT,TF>& lhs, const DVecDVecKronExpr& rhs )
324 {
326
330
331 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
332
333 const ResultType tmp( serial( rhs ) );
334 assign( *lhs, tmp );
335 }
337 //**********************************************************************************************
338
339 //**Addition assignment to dense vectors********************************************************
351 template< typename VT > // Type of the target dense vector
352 friend inline void addAssign( DenseVector<VT,TF>& lhs, const DVecDVecKronExpr& rhs )
353 {
355
356 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
357
358 if( rhs.size() == 0UL ) {
359 return;
360 }
361
362 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
363 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
364
365 const size_t N( y.size() );
366
367 for( size_t i=0UL; i<x.size(); ++i ) {
368 if( !isDefault<strict>( x[i] ) ) {
369 for( size_t j=0UL; j<N; ++j )
370 (*lhs)[i*N+j] += x[i] * y[j];
371 }
372 }
373 }
375 //**********************************************************************************************
376
377 //**Addition assignment to sparse vectors*******************************************************
378 // No special implementation for the addition assignment to sparse vectors.
379 //**********************************************************************************************
380
381 //**Subtraction assignment to dense vectors*****************************************************
394 template< typename VT > // Type of the target dense vector
395 friend inline void subAssign( DenseVector<VT,TF>& lhs, const DVecDVecKronExpr& rhs )
396 {
398
399 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
400
401 if( rhs.size() == 0UL ) {
402 return;
403 }
404
405 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
406 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
407
408 const size_t N( y.size() );
409
410 for( size_t i=0UL; i<x.size(); ++i ) {
411 if( !isDefault<strict>( x[i] ) ) {
412 for( size_t j=0UL; j<N; ++j )
413 (*lhs)[i*N+j] -= x[i] * y[j];
414 }
415 }
416 }
418 //**********************************************************************************************
419
420 //**Subtraction assignment to sparse vectors****************************************************
421 // No special implementation for the subtraction assignment to sparse vectors.
422 //**********************************************************************************************
423
424 //**Multiplication assignment to dense vectors**************************************************
437 template< typename VT > // Type of the target dense vector
438 friend inline void multAssign( DenseVector<VT,TF>& lhs, const DVecDVecKronExpr& rhs )
439 {
441
442 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
443
444 if( rhs.size() == 0UL ) {
445 return;
446 }
447
448 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
449 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
450
451 const size_t N( y.size() );
452
453 for( size_t i=0UL; i<x.size(); ++i ) {
454 if( !isDefault<strict>( x[i] ) ) {
455 for( size_t j=0UL; j<N; ++j )
456 (*lhs)[i*N+j] *= x[i] * y[j];
457 }
458 else {
459 for( size_t j=0UL; j<N; ++j )
460 reset( (*lhs)[i*N+j] );
461 }
462 }
463 }
465 //**********************************************************************************************
466
467 //**Multiplication assignment to sparse vectors*************************************************
468 // No special implementation for the multiplication assignment to sparse vectors.
469 //**********************************************************************************************
470
471 //**Division assignment to dense vectors********************************************************
483 template< typename VT > // Type of the target dense vector
484 friend inline void divAssign( DenseVector<VT,TF>& lhs, const DVecDVecKronExpr& rhs )
485 {
487
488 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
489
490 if( rhs.size() == 0UL ) {
491 return;
492 }
493
494 CT1 x( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense vector operand
495 CT2 y( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense vector operand
496
497 const size_t N( y.size() );
498
499 for( size_t i=0UL; i<x.size(); ++i ) {
500 if( !isDefault<strict>( x[i] ) ) {
501 for( size_t j=0UL; j<N; ++j )
502 (*lhs)[i*N+j] /= x[i] * y[j];
503 }
504 }
505 }
507 //**********************************************************************************************
508
509 //**Division assignment to sparse vectors*******************************************************
510 // No special implementation for the division assignment to sparse vectors.
511 //**********************************************************************************************
512
513 //**Compile time checks*************************************************************************
521 //**********************************************************************************************
522};
523//*************************************************************************************************
524
525
526
527
528//=================================================================================================
529//
530// GLOBAL FUNCTIONS
531//
532//=================================================================================================
533
534//*************************************************************************************************
555template< typename VT1 // Type of the left-hand side dense vector
556 , typename VT2 // Type of the right-hand side dense vector
557 , bool TF > // Transpose flag
558inline decltype(auto)
560{
562
563 using ReturnType = const DVecDVecKronExpr<VT1,VT2,TF>;
564 return ReturnType( *lhs, *rhs );
565}
566//*************************************************************************************************
567
568} // namespace blaze
569
570#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 function trace functionality.
Header file for the If class template.
Header file for the isDefault shim.
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.
Expression object for dense vector-dense vector Kronecker product.
Definition: DVecDVecKronExpr.h:90
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: DVecDVecKronExpr.h:167
const ResultType CompositeType
Data type for composite expression templates.
Definition: DVecDVecKronExpr.h:132
ReturnType_t< VT2 > RN2
Return type of the right-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:96
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: DVecDVecKronExpr.h:129
ElementType_t< VT1 > ET1
Element type of the left-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:99
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DVecDVecKronExpr.h:126
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DVecDVecKronExpr.h:257
decltype(std::declval< RN1 >()+std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: DVecDVecKronExpr.h:113
ResultType_t< VT2 > RT2
Result type of the right-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:94
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DVecDVecKronExpr.h:146
If_t< IsExpression_v< VT1 >, const VT1, const VT1 & > LeftOperand
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:135
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense vector operand.
Definition: DVecDVecKronExpr.h:203
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: DVecDVecKronExpr.h:110
ElementType_t< VT2 > ET2
Element type of the right-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:100
ResultType_t< VT1 > RT1
Result type of the left-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:93
CompositeType_t< VT2 > CT2
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:98
DVecDVecKronExpr(const VT1 &lhs, const VT2 &rhs) noexcept
Constructor for the DVecDVecKronExpr class.
Definition: DVecDVecKronExpr.h:155
size_t size() const noexcept
Returns the current size/dimension of the vector.
Definition: DVecDVecKronExpr.h:193
ReturnType at(size_t index) const
Checked access to the vector elements.
Definition: DVecDVecKronExpr.h:180
If_t< IsExpression_v< VT2 >, const VT2, const VT2 & > RightOperand
Composite type of the right-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:138
RightOperand rightOperand() const noexcept
Returns the right-hand side dense vector operand.
Definition: DVecDVecKronExpr.h:213
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DVecDVecKronExpr.h:225
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DVecDVecKronExpr.h:247
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DVecDVecKronExpr.h:237
ReturnType_t< VT1 > RN1
Return type of the left-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:95
RightOperand rhs_
Right-hand side dense vector of the Kronecker product expression.
Definition: DVecDVecKronExpr.h:265
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DVecDVecKronExpr.h:125
KronTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: DVecDVecKronExpr.h:124
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DVecDVecKronExpr.h:143
LeftOperand lhs_
Left-hand side dense vector of the Kronecker product expression.
Definition: DVecDVecKronExpr.h:264
CompositeType_t< VT1 > CT1
Composite type of the left-hand side dense vector expression.
Definition: DVecDVecKronExpr.h:97
Base class for N-dimensional dense vectors.
Definition: DenseVector.h:77
Base class for sparse vectors.
Definition: SparseVector.h:72
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the Computation base class.
Header file for the DenseVector 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 DenseVector< VT1, TF > &lhs, const DenseVector< VT2, TF > &rhs)
Computes the Kronecker product of two dense vectors ( ).
Definition: DVecDVecKronExpr.h:559
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.
Definition: TransposeFlag.h:63
#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
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 all forward declarations for expression class templates.
Header file for the reset shim.
Header file for the serial shim.
Base class for all compute expression templates.
Definition: Computation.h:68
Base class for all vector/vector Kronecker expression templates.
Definition: VecVecKronExpr.h:69
Header file for basic type definitions.