All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DVecTDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECTDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DVECTDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
44 #include <blaze/util/Assert.h>
46 #include <blaze/util/EnableIf.h>
47 #include <blaze/util/SelectType.h>
48 #include <blaze/util/Types.h>
50 
51 
52 namespace blaze {
53 
54 //=================================================================================================
55 //
56 // CLASS DVECTDVECMULTEXPR
57 //
58 //=================================================================================================
59 
60 //*************************************************************************************************
67 template< typename VT1 // Type of the left-hand side dense vector
68  , typename VT2 > // Type of the right-hand side dense vector
69 class DVecTDVecMultExpr : public DenseMatrix< DVecTDVecMultExpr<VT1,VT2>, false >
70  , private Expression
71  , private Computation
72 {
73  private:
74  //**Type definitions****************************************************************************
75  typedef typename VT1::ResultType RT1;
76  typedef typename VT2::ResultType RT2;
77  typedef typename VT1::ReturnType RN1;
78  typedef typename VT2::ReturnType RN2;
79  typedef typename VT1::CompositeType CT1;
80  typedef typename VT2::CompositeType CT2;
81  //**********************************************************************************************
82 
83  //**Return type evaluation**********************************************************************
85 
90  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
91 
94  //**********************************************************************************************
95 
96  //**Evaluation strategy*************************************************************************
98 
104  enum { useAssign = ( IsComputation<VT1>::value || IsComputation<VT2>::value ) };
105 
107 
108  template< typename VT >
109  struct UseAssign {
110  enum { value = useAssign };
111  };
113  //**********************************************************************************************
114 
115  public:
116  //**Type definitions****************************************************************************
119  typedef typename ResultType::OppositeType OppositeType;
120  typedef typename ResultType::TransposeType TransposeType;
121  typedef typename ResultType::ElementType ElementType;
122 
125 
128 
130  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
131 
133  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
134 
136  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
137 
139  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
140  //**********************************************************************************************
141 
142  //**Compilation flags***************************************************************************
144  enum { vectorizable = 0 };
145 
147  enum { canAlias = !IsComputation<VT1>::value || !IsComputation<VT2>::value };
148  //**********************************************************************************************
149 
150  //**Constructor*********************************************************************************
156  explicit inline DVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
157  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
158  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
159  {}
160  //**********************************************************************************************
161 
162  //**Access operator*****************************************************************************
169  inline ReturnType operator()( size_t i, size_t j ) const {
170  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
171  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
172 
173  return lhs_[i] * rhs_[j];
174  }
175  //**********************************************************************************************
176 
177  //**Rows function*******************************************************************************
182  inline size_t rows() const {
183  return lhs_.size();
184  }
185  //**********************************************************************************************
186 
187  //**Columns function****************************************************************************
192  inline size_t columns() const {
193  return rhs_.size();
194  }
195  //**********************************************************************************************
196 
197  //**Left operand access*************************************************************************
202  inline LeftOperand leftOperand() const {
203  return lhs_;
204  }
205  //**********************************************************************************************
206 
207  //**Right operand access************************************************************************
212  inline RightOperand rightOperand() const {
213  return rhs_;
214  }
215  //**********************************************************************************************
216 
217  //**********************************************************************************************
223  template< typename T >
224  inline bool isAliased( const T* alias ) const {
225  return ( !IsComputation<VT1>::value && lhs_.isAliased( alias ) ) ||
226  ( !IsComputation<VT2>::value && rhs_.isAliased( alias ) );
227  }
228  //**********************************************************************************************
229 
230  private:
231  //**Member variables****************************************************************************
232  LeftOperand lhs_;
233  RightOperand rhs_;
234  //**********************************************************************************************
235 
236  //**Assignment to row-major dense matrices******************************************************
250  template< typename MT > // Type of the target dense matrix
251  friend inline typename EnableIf< UseAssign<MT> >::Type
253  {
254  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
255  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
256 
257  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
258  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
259 
260  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
261  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
262  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
263  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
264 
265  const size_t m( (~lhs).rows() );
266  const size_t n( (~lhs).columns() );
267 
268  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == ( n & size_t(-2) ), "Invalid end calculation" );
269  const size_t jend( n & size_t(-2) );
270 
271  for( size_t i=0UL; i<m; ++i ) {
272  for( size_t j=0UL; j<jend; j+=2UL ) {
273  (~lhs)(i,j ) = x[i] * y[j ];
274  (~lhs)(i,j+1UL) = x[i] * y[j+1];
275  }
276  if( jend < n ) {
277  (~lhs)(i,jend) = x[i] * y[jend];
278  }
279  }
280  }
282  //**********************************************************************************************
283 
284  //**Assignment to column-major dense matrices***************************************************
296  template< typename MT > // Type of the target dense matrix
297  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
298  {
299  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
300  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
301 
302  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
303  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
304 
305  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
306  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
307  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
308  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
309 
310  const size_t m( (~lhs).rows() );
311  const size_t n( (~lhs).columns() );
312 
313  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ( m & size_t(-2) ), "Invalid end calculation" );
314  const size_t iend( m & size_t(-2) );
315 
316  for( size_t j=0UL; j<n; ++j ) {
317  for( size_t i=0UL; i<iend; i+=2UL ) {
318  (~lhs)(i ,j) = x[i ] * y[j];
319  (~lhs)(i+1UL,j) = x[i+1] * y[j];
320  }
321  if( iend < m ) {
322  (~lhs)(iend,j) = x[iend] * y[j];
323  }
324  }
325  }
327  //**********************************************************************************************
328 
329  //**Assignment to sparse matrices***************************************************************
341  template< typename MT // Type of the target sparse matrix
342  , bool SO > // Storage order of the target sparse matrix
343  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecTDVecMultExpr& rhs )
344  {
345  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
346 
352  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
353 
354  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
356 
357  const TmpType tmp( rhs );
358  assign( ~lhs, tmp );
359  }
361  //**********************************************************************************************
362 
363  //**Addition assignment to row-major dense matrices*********************************************
378  template< typename MT > // Type of the target dense matrix
379  friend inline typename EnableIf< UseAssign<MT> >::Type
380  addAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
381  {
382  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
383  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
384 
385  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
386  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
387 
388  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
389  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
390  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
391  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
392 
393  const size_t m( (~lhs).rows() );
394  const size_t n( (~lhs).columns() );
395 
396  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == ( n & size_t(-2) ), "Invalid end calculation" );
397  const size_t jend( n & size_t(-2) );
398 
399  for( size_t i=0UL; i<m; ++i ) {
400  for( size_t j=0UL; j<jend; j+=2UL ) {
401  (~lhs)(i,j ) += x[i] * y[j ];
402  (~lhs)(i,j+1UL) += x[i] * y[j+1UL];
403  }
404  if( jend < n ) {
405  (~lhs)(i,jend) += x[i] * y[jend];
406  }
407  }
408  }
410  //**********************************************************************************************
411 
412  //**Addition assignment to column-major dense matrices******************************************
425  template< typename MT > // Type of the target dense matrix
426  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
427  {
428  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
429  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
430 
431  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
432  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
433 
434  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
435  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
436  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
437  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
438 
439  const size_t m( (~lhs).rows() );
440  const size_t n( (~lhs).columns() );
441 
442  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ( m & size_t(-2) ), "Invalid end calculation" );
443  const size_t iend( m & size_t(-2) );
444 
445  for( size_t j=0UL; j<n; ++j ) {
446  for( size_t i=0UL; i<iend; i+=2UL ) {
447  (~lhs)(i ,j) += x[i ] * y[j];
448  (~lhs)(i+1UL,j) += x[i+1UL] * y[j];
449  }
450  if( iend < m ) {
451  (~lhs)(iend,j) += x[iend] * y[j];
452  }
453  }
454  }
456  //**********************************************************************************************
457 
458  //**Addition assignment to sparse matrices******************************************************
459  // No special implementation for the addition assignment to sparse matrices.
460  //**********************************************************************************************
461 
462  //**Subtraction assignment to row-major dense matrices******************************************
477  template< typename MT > // Type of the target dense matrix
478  friend inline typename EnableIf< UseAssign<MT> >::Type
479  subAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
480  {
481  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
482  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
483 
484  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
485  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
486 
487  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
488  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
489  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
490  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
491 
492  const size_t m( (~lhs).rows() );
493  const size_t n( (~lhs).columns() );
494 
495  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == ( n & size_t(-2) ), "Invalid end calculation" );
496  const size_t jend( n & size_t(-2) );
497 
498  for( size_t i=0UL; i<m; ++i ) {
499  for( size_t j=0UL; j<jend; j+=2UL ) {
500  (~lhs)(i,j ) -= x[i] * y[j ];
501  (~lhs)(i,j+1UL) -= x[i] * y[j+1UL];
502  }
503  if( jend < n ) {
504  (~lhs)(i,jend) -= x[i] * y[jend];
505  }
506  }
507  }
509  //**********************************************************************************************
510 
511  //**Subtraction assignment to column-major dense matrices***************************************
524  template< typename MT > // Type of the target dense matrix
525  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
526  {
527  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
528  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
529 
530  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
531  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
532 
533  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
534  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
535  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
536  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
537 
538  const size_t m( (~lhs).rows() );
539  const size_t n( (~lhs).columns() );
540 
541  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ( m & size_t(-2) ), "Invalid end calculation" );
542  const size_t iend( m & size_t(-2) );
543 
544  for( size_t j=0UL; j<n; ++j ) {
545  for( size_t i=0UL; i<iend; i+=2UL ) {
546  (~lhs)(i ,j) -= x[i ] * y[j];
547  (~lhs)(i+1UL,j) -= x[i+1UL] * y[j];
548  }
549  if( iend < m ) {
550  (~lhs)(iend,j) -= x[iend] * y[j];
551  }
552  }
553  }
555  //**********************************************************************************************
556 
557  //**Subtraction assignment to sparse matrices***************************************************
558  // No special implementation for the subtraction assignment to sparse matrices.
559  //**********************************************************************************************
560 
561  //**Multiplication assignment to dense matrices*************************************************
562  // No special implementation for the multiplication assignment to dense matrices.
563  //**********************************************************************************************
564 
565  //**Multiplication assignment to sparse matrices************************************************
566  // No special implementation for the multiplication assignment to sparse matrices.
567  //**********************************************************************************************
568 
569  //**Compile time checks*************************************************************************
576  //**********************************************************************************************
577 };
578 //*************************************************************************************************
579 
580 
581 
582 
583 //=================================================================================================
584 //
585 // GLOBAL BINARY ARITHMETIC OPERATORS
586 //
587 //=================================================================================================
588 
589 //*************************************************************************************************
616 template< typename T1 // Type of the left-hand side dense vector
617  , typename T2 > // Type of the right-hand side dense vector
618 inline const DVecTDVecMultExpr<T1,T2>
620 {
621  return DVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
622 }
623 //*************************************************************************************************
624 
625 } // namespace blaze
626 
627 #endif