All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
37 #include <blaze/math/Intrinsics.h>
45 #include <blaze/util/Assert.h>
47 #include <blaze/util/EnableIf.h>
48 #include <blaze/util/SelectType.h>
49 #include <blaze/util/Types.h>
51 
52 
53 namespace blaze {
54 
55 //=================================================================================================
56 //
57 // CLASS DVECDVECMULTEXPR
58 //
59 //=================================================================================================
60 
61 //*************************************************************************************************
68 template< typename VT1 // Type of the left-hand side dense vector
69  , typename VT2 // Type of the right-hand side dense vector
70  , bool TF > // Transpose flag
71 class DVecDVecMultExpr : public DenseVector< DVecDVecMultExpr<VT1,VT2,TF>, TF >
72  , private Expression
73  , private Computation
74 {
75  private:
76  //**Type definitions****************************************************************************
77  typedef typename VT1::ResultType RT1;
78  typedef typename VT2::ResultType RT2;
79  typedef typename VT1::ReturnType RN1;
80  typedef typename VT2::ReturnType RN2;
81  typedef typename VT1::CompositeType CT1;
82  typedef typename VT2::CompositeType CT2;
83  typedef typename VT1::ElementType ET1;
84  typedef typename VT2::ElementType ET2;
85  //**********************************************************************************************
86 
87  //**Return type evaluation**********************************************************************
89 
94  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
95 
98  //**********************************************************************************************
99 
100  //**Evaluation strategy*************************************************************************
102 
108  enum { useAssign = ( RequiresEvaluation<VT1>::value || RequiresEvaluation<VT2>::value || !returnExpr ) };
109 
111 
112  template< typename VT >
113  struct UseAssign {
114  enum { value = useAssign };
115  };
117  //**********************************************************************************************
118 
119  public:
120  //**Type definitions****************************************************************************
123  typedef typename ResultType::TransposeType TransposeType;
124  typedef typename ResultType::ElementType ElementType;
126 
129 
132 
134  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
135 
137  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
138  //**********************************************************************************************
139 
140  //**Compilation flags***************************************************************************
142  enum { vectorizable = VT1::vectorizable && VT2::vectorizable &&
145 
147  enum { canAlias = ( IsComputation<VT1>::value && CanAlias<VT1>::value ) ||
149  //**********************************************************************************************
150 
151  //**Constructor*********************************************************************************
157  explicit inline DVecDVecMultExpr( const VT1& lhs, const VT2& rhs )
158  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
159  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
160  {
161  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
162  }
163  //**********************************************************************************************
164 
165  //**Subscript operator**************************************************************************
171  inline ReturnType operator[]( size_t index ) const {
172  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
173  return lhs_[index] * rhs_[index];
174  }
175  //**********************************************************************************************
176 
177  //**Get function********************************************************************************
183  inline IntrinsicType get( size_t index ) const {
184  typedef IntrinsicTrait<ElementType> IT;
185  BLAZE_INTERNAL_ASSERT( index < lhs_.size() , "Invalid vector access index" );
186  BLAZE_INTERNAL_ASSERT( index % IT::size == 0UL, "Invalid vector access index" );
187  const IntrinsicType xmm1( lhs_.get( index ) );
188  const IntrinsicType xmm2( rhs_.get( index ) );
189  return xmm1 * xmm2;
190  }
191  //**********************************************************************************************
192 
193  //**Size function*******************************************************************************
198  inline size_t size() const {
199  return lhs_.size();
200  }
201  //**********************************************************************************************
202 
203  //**Left operand access*************************************************************************
208  inline LeftOperand leftOperand() const {
209  return lhs_;
210  }
211  //**********************************************************************************************
212 
213  //**Right operand access************************************************************************
218  inline RightOperand rightOperand() const {
219  return rhs_;
220  }
221  //**********************************************************************************************
222 
223  //**********************************************************************************************
229  template< typename T >
230  inline bool isAliased( const T* alias ) const {
231  return ( IsComputation<VT1>::value && CanAlias<VT1>::value && lhs_.isAliased( alias ) ) ||
232  ( IsComputation<VT2>::value && CanAlias<VT2>::value && rhs_.isAliased( alias ) );
233  }
234  //**********************************************************************************************
235 
236  private:
237  //**Member variables****************************************************************************
238  LeftOperand lhs_;
239  RightOperand rhs_;
240  //**********************************************************************************************
241 
242  //**Assignment to dense vectors*****************************************************************
256  template< typename VT > // Type of the target dense vector
257  friend inline typename EnableIf< UseAssign<VT> >::Type
258  assign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
259  {
260  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
261 
262  if( !IsComputation<VT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
263  multAssign( ~lhs, rhs.rhs_ );
264  }
265  else if( !IsComputation<VT2>::value && (~lhs).isAliased( &rhs.rhs_ ) ) {
266  multAssign( ~lhs, rhs.lhs_ );
267  }
268  else {
269  assign ( ~lhs, rhs.lhs_ );
270  multAssign( ~lhs, rhs.rhs_ );
271  }
272  }
274  //**********************************************************************************************
275 
276  //**Assignment to sparse vectors****************************************************************
290  template< typename VT > // Type of the target sparse vector
291  friend inline typename EnableIf< UseAssign<VT> >::Type
292  assign( SparseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
293  {
296  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
297 
298  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
299 
300  const ResultType tmp( rhs );
301  assign( ~lhs, tmp );
302  }
304  //**********************************************************************************************
305 
306  //**Addition assignment to dense vectors********************************************************
320  template< typename VT > // Type of the target dense vector
321  friend inline typename EnableIf< UseAssign<VT> >::Type
322  addAssign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
323  {
326  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
327 
328  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
329 
330  const ResultType tmp( rhs );
331  addAssign( ~lhs, tmp );
332  }
334  //**********************************************************************************************
335 
336  //**Addition assignment to sparse vectors*******************************************************
337  // No special implementation for the addition assignment to sparse vectors.
338  //**********************************************************************************************
339 
340  //**Subtraction assignment to dense vectors*****************************************************
354  template< typename VT > // Type of the target dense vector
355  friend inline typename EnableIf< UseAssign<VT> >::Type
356  subAssign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
357  {
360  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
361 
362  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
363 
364  const ResultType tmp( rhs );
365  subAssign( ~lhs, tmp );
366  }
368  //**********************************************************************************************
369 
370  //**Subtraction assignment to sparse vectors****************************************************
371  // No special implementation for the subtraction assignment to sparse vectors.
372  //**********************************************************************************************
373 
374  //**Multiplication assignment to dense vectors**************************************************
388  template< typename VT > // Type of the target dense vector
389  friend inline typename EnableIf< UseAssign<VT> >::Type
390  multAssign( DenseVector<VT,TF>& lhs, const DVecDVecMultExpr& rhs )
391  {
392  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
393 
394  multAssign( ~lhs, rhs.lhs_ );
395  multAssign( ~lhs, rhs.rhs_ );
396  }
398  //**********************************************************************************************
399 
400  //**Multiplication assignment to sparse vectors*************************************************
414  template< typename VT > // Type of the target sparse vector
415  friend inline typename EnableIf< UseAssign<VT> >::Type
417  {
418  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
419 
420  multAssign( ~lhs, rhs.lhs_ );
421  multAssign( ~lhs, rhs.rhs_ );
422  }
424  //**********************************************************************************************
425 
426  //**Compile time checks*************************************************************************
433  //**********************************************************************************************
434 };
435 //*************************************************************************************************
436 
437 
438 
439 
440 //=================================================================================================
441 //
442 // GLOBAL BINARY ARITHMETIC OPERATORS
443 //
444 //=================================================================================================
445 
446 //*************************************************************************************************
471 template< typename T1 // Type of the left-hand side dense vector
472  , typename T2 // Type of the right-hand side dense vector
473  , bool TF > // Transpose flag
474 inline const DVecDVecMultExpr<T1,T2,TF>
476 {
477  if( (~lhs).size() != (~rhs).size() )
478  throw std::invalid_argument( "Vector sizes do not match" );
479 
480  return DVecDVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
481 }
482 //*************************************************************************************************
483 
484 } // namespace blaze
485 
486 #endif