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 
45 #include <blaze/util/Assert.h>
47 #include <blaze/util/EnableIf.h>
49 #include <blaze/util/SelectType.h>
50 #include <blaze/util/Types.h>
52 
53 
54 namespace blaze {
55 
56 //=================================================================================================
57 //
58 // CLASS DVECTDVECMULTEXPR
59 //
60 //=================================================================================================
61 
62 //*************************************************************************************************
69 template< typename VT1 // Type of the left-hand side dense vector
70  , typename VT2 > // Type of the right-hand side dense vector
71 class DVecTDVecMultExpr : public DenseMatrix< DVecTDVecMultExpr<VT1,VT2>, false >
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  //**********************************************************************************************
84 
85  //**Return type evaluation**********************************************************************
87 
92  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
93 
96  //**********************************************************************************************
97 
98  //**Evaluation strategy*************************************************************************
100 
106  enum { useAssign = ( IsComputation<VT1>::value || IsComputation<VT2>::value ) };
107 
109 
110  template< typename VT >
111  struct UseAssign {
112  enum { value = useAssign };
113  };
115  //**********************************************************************************************
116 
117  public:
118  //**Type definitions****************************************************************************
121  typedef typename ResultType::OppositeType OppositeType;
122  typedef typename ResultType::TransposeType TransposeType;
123  typedef typename ResultType::ElementType ElementType;
124 
127 
130 
132  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
133 
135  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
136 
138  typedef typename SelectType< IsComputation<VT1>::value, const RT1, CT1 >::Type LT;
139 
141  typedef typename SelectType< IsComputation<VT2>::value, const RT2, CT2 >::Type RT;
142  //**********************************************************************************************
143 
144  //**Compilation flags***************************************************************************
146  enum { vectorizable = 0 };
147  //**********************************************************************************************
148 
149  //**Constructor*********************************************************************************
155  explicit inline DVecTDVecMultExpr( const VT1& lhs, const VT2& rhs )
156  : lhs_( lhs ) // Left-hand side dense vector of the multiplication expression
157  , rhs_( rhs ) // Right-hand side dense vector of the multiplication expression
158  {}
159  //**********************************************************************************************
160 
161  //**Access operator*****************************************************************************
168  inline ReturnType operator()( size_t i, size_t j ) const {
169  BLAZE_INTERNAL_ASSERT( i < lhs_.size(), "Invalid row access index" );
170  BLAZE_INTERNAL_ASSERT( j < rhs_.size(), "Invalid column access index" );
171 
172  return lhs_[i] * rhs_[j];
173  }
174  //**********************************************************************************************
175 
176  //**Rows function*******************************************************************************
181  inline size_t rows() const {
182  return lhs_.size();
183  }
184  //**********************************************************************************************
185 
186  //**Columns function****************************************************************************
191  inline size_t columns() const {
192  return rhs_.size();
193  }
194  //**********************************************************************************************
195 
196  //**Left operand access*************************************************************************
201  inline LeftOperand leftOperand() const {
202  return lhs_;
203  }
204  //**********************************************************************************************
205 
206  //**Right operand access************************************************************************
211  inline RightOperand rightOperand() const {
212  return rhs_;
213  }
214  //**********************************************************************************************
215 
216  //**********************************************************************************************
222  template< typename T >
223  inline bool canAlias( const T* alias ) const {
224  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
225  }
226  //**********************************************************************************************
227 
228  //**********************************************************************************************
234  template< typename T >
235  inline bool isAliased( const T* alias ) const {
236  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
237  }
238  //**********************************************************************************************
239 
240  private:
241  //**Member variables****************************************************************************
242  LeftOperand lhs_;
243  RightOperand rhs_;
244  //**********************************************************************************************
245 
246  //**Assignment to row-major dense matrices******************************************************
260  template< typename MT > // Type of the target dense matrix
261  friend inline typename EnableIf< UseAssign<MT> >::Type
263  {
265 
266  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
267  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
268 
269  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
270  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
271 
272  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
273  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
274  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
275  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
276 
277  const size_t m( (~lhs).rows() );
278  const size_t n( (~lhs).columns() );
279 
280  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == ( n & size_t(-2) ), "Invalid end calculation" );
281  const size_t jend( n & size_t(-2) );
282 
283  for( size_t i=0UL; i<m; ++i ) {
284  for( size_t j=0UL; j<jend; j+=2UL ) {
285  (~lhs)(i,j ) = x[i] * y[j ];
286  (~lhs)(i,j+1UL) = x[i] * y[j+1];
287  }
288  if( jend < n ) {
289  (~lhs)(i,jend) = x[i] * y[jend];
290  }
291  }
292  }
294  //**********************************************************************************************
295 
296  //**Assignment to column-major dense matrices***************************************************
308  template< typename MT > // Type of the target dense matrix
309  friend inline void assign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
310  {
312 
313  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
314  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
315 
316  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
317  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
318 
319  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
320  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
321  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
322  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
323 
324  const size_t m( (~lhs).rows() );
325  const size_t n( (~lhs).columns() );
326 
327  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ( m & size_t(-2) ), "Invalid end calculation" );
328  const size_t iend( m & size_t(-2) );
329 
330  for( size_t j=0UL; j<n; ++j ) {
331  for( size_t i=0UL; i<iend; i+=2UL ) {
332  (~lhs)(i ,j) = x[i ] * y[j];
333  (~lhs)(i+1UL,j) = x[i+1] * y[j];
334  }
335  if( iend < m ) {
336  (~lhs)(iend,j) = x[iend] * y[j];
337  }
338  }
339  }
341  //**********************************************************************************************
342 
343  //**Assignment to sparse matrices***************************************************************
355  template< typename MT // Type of the target sparse matrix
356  , bool SO > // Storage order of the target sparse matrix
357  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DVecTDVecMultExpr& rhs )
358  {
360 
361  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
362 
368  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
369 
370  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
371  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
372 
373  const TmpType tmp( rhs );
374  assign( ~lhs, tmp );
375  }
377  //**********************************************************************************************
378 
379  //**Addition assignment to row-major dense matrices*********************************************
394  template< typename MT > // Type of the target dense matrix
395  friend inline typename EnableIf< UseAssign<MT> >::Type
396  addAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
397  {
399 
400  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
401  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
402 
403  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
404  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
405 
406  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
407  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
408  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
409  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
410 
411  const size_t m( (~lhs).rows() );
412  const size_t n( (~lhs).columns() );
413 
414  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == ( n & size_t(-2) ), "Invalid end calculation" );
415  const size_t jend( n & size_t(-2) );
416 
417  for( size_t i=0UL; i<m; ++i ) {
418  for( size_t j=0UL; j<jend; j+=2UL ) {
419  (~lhs)(i,j ) += x[i] * y[j ];
420  (~lhs)(i,j+1UL) += x[i] * y[j+1UL];
421  }
422  if( jend < n ) {
423  (~lhs)(i,jend) += x[i] * y[jend];
424  }
425  }
426  }
428  //**********************************************************************************************
429 
430  //**Addition assignment to column-major dense matrices******************************************
443  template< typename MT > // Type of the target dense matrix
444  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
445  {
447 
448  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
449  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
450 
451  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
452  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
453 
454  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
455  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
456  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
457  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
458 
459  const size_t m( (~lhs).rows() );
460  const size_t n( (~lhs).columns() );
461 
462  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ( m & size_t(-2) ), "Invalid end calculation" );
463  const size_t iend( m & size_t(-2) );
464 
465  for( size_t j=0UL; j<n; ++j ) {
466  for( size_t i=0UL; i<iend; i+=2UL ) {
467  (~lhs)(i ,j) += x[i ] * y[j];
468  (~lhs)(i+1UL,j) += x[i+1UL] * y[j];
469  }
470  if( iend < m ) {
471  (~lhs)(iend,j) += x[iend] * y[j];
472  }
473  }
474  }
476  //**********************************************************************************************
477 
478  //**Addition assignment to sparse matrices******************************************************
479  // No special implementation for the addition assignment to sparse matrices.
480  //**********************************************************************************************
481 
482  //**Subtraction assignment to row-major dense matrices******************************************
497  template< typename MT > // Type of the target dense matrix
498  friend inline typename EnableIf< UseAssign<MT> >::Type
499  subAssign( DenseMatrix<MT,false>& lhs, const DVecTDVecMultExpr& rhs )
500  {
502 
503  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
504  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
505 
506  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
507  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
508 
509  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
510  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
511  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
512  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
513 
514  const size_t m( (~lhs).rows() );
515  const size_t n( (~lhs).columns() );
516 
517  BLAZE_INTERNAL_ASSERT( ( n - ( n % 2UL ) ) == ( n & size_t(-2) ), "Invalid end calculation" );
518  const size_t jend( n & size_t(-2) );
519 
520  for( size_t i=0UL; i<m; ++i ) {
521  for( size_t j=0UL; j<jend; j+=2UL ) {
522  (~lhs)(i,j ) -= x[i] * y[j ];
523  (~lhs)(i,j+1UL) -= x[i] * y[j+1UL];
524  }
525  if( jend < n ) {
526  (~lhs)(i,jend) -= x[i] * y[jend];
527  }
528  }
529  }
531  //**********************************************************************************************
532 
533  //**Subtraction assignment to column-major dense matrices***************************************
546  template< typename MT > // Type of the target dense matrix
547  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DVecTDVecMultExpr& rhs )
548  {
550 
551  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
552  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
553 
554  LT x( rhs.lhs_ ); // Evaluation of the left-hand side dense vector operand
555  RT y( rhs.rhs_ ); // Evaluation of the right-hand side dense vector operand
556 
557  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size() , "Invalid vector size" );
558  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size() , "Invalid vector size" );
559  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).rows() , "Invalid vector size" );
560  BLAZE_INTERNAL_ASSERT( y.size() == (~lhs).columns(), "Invalid vector size" );
561 
562  const size_t m( (~lhs).rows() );
563  const size_t n( (~lhs).columns() );
564 
565  BLAZE_INTERNAL_ASSERT( ( m - ( m % 2UL ) ) == ( m & size_t(-2) ), "Invalid end calculation" );
566  const size_t iend( m & size_t(-2) );
567 
568  for( size_t j=0UL; j<n; ++j ) {
569  for( size_t i=0UL; i<iend; i+=2UL ) {
570  (~lhs)(i ,j) -= x[i ] * y[j];
571  (~lhs)(i+1UL,j) -= x[i+1UL] * y[j];
572  }
573  if( iend < m ) {
574  (~lhs)(iend,j) -= x[iend] * y[j];
575  }
576  }
577  }
579  //**********************************************************************************************
580 
581  //**Subtraction assignment to sparse matrices***************************************************
582  // No special implementation for the subtraction assignment to sparse matrices.
583  //**********************************************************************************************
584 
585  //**Multiplication assignment to dense matrices*************************************************
586  // No special implementation for the multiplication assignment to dense matrices.
587  //**********************************************************************************************
588 
589  //**Multiplication assignment to sparse matrices************************************************
590  // No special implementation for the multiplication assignment to sparse matrices.
591  //**********************************************************************************************
592 
593  //**Compile time checks*************************************************************************
600  //**********************************************************************************************
601 };
602 //*************************************************************************************************
603 
604 
605 
606 
607 //=================================================================================================
608 //
609 // GLOBAL BINARY ARITHMETIC OPERATORS
610 //
611 //=================================================================================================
612 
613 //*************************************************************************************************
640 template< typename T1 // Type of the left-hand side dense vector
641  , typename T2 > // Type of the right-hand side dense vector
642 inline const DVecTDVecMultExpr<T1,T2>
644 {
646 
647  return DVecTDVecMultExpr<T1,T2>( ~lhs, ~rhs );
648 }
649 //*************************************************************************************************
650 
651 
652 
653 
654 //=================================================================================================
655 //
656 // GLOBAL OPERATORS
657 //
658 //=================================================================================================
659 
660 //*************************************************************************************************
672 template< typename VT1 // Type of the left-hand side dense vector
673  , typename VT2 > // Type of the right-hand side dense vector
674 inline typename RowExprTrait< DVecTDVecMultExpr<VT1,VT2> >::Type
675  row( const DVecTDVecMultExpr<VT1,VT2>& dm, size_t index )
676 {
678 
679  return dm.leftOperand()[index] * dm.rightOperand();
680 }
682 //*************************************************************************************************
683 
684 
685 //*************************************************************************************************
697 template< typename VT1 // Type of the left-hand side dense vector
698  , typename VT2 > // Type of the right-hand side dense vector
699 inline typename ColumnExprTrait< DVecTDVecMultExpr<VT1,VT2> >::Type
700  column( const DVecTDVecMultExpr<VT1,VT2>& dm, size_t index )
701 {
703 
704  return dm.leftOperand() * dm.rightOperand()[index];
705 }
707 //*************************************************************************************************
708 
709 
710 
711 
712 //=================================================================================================
713 //
714 // EXPRESSION TRAIT SPECIALIZATIONS
715 //
716 //=================================================================================================
717 
718 //*************************************************************************************************
720 template< typename VT1, typename VT2 >
721 struct RowExprTrait< DVecTDVecMultExpr<VT1,VT2> >
722 {
723  public:
724  //**********************************************************************************************
725  typedef typename MultExprTrait< typename VT1::ReturnType, VT2 >::Type Type;
726  //**********************************************************************************************
727 };
729 //*************************************************************************************************
730 
731 
732 //*************************************************************************************************
734 template< typename VT1, typename VT2 >
735 struct ColumnExprTrait< DVecTDVecMultExpr<VT1,VT2> >
736 {
737  public:
738  //**********************************************************************************************
739  typedef typename MultExprTrait< VT1, typename VT2::ReturnType >::Type Type;
740  //**********************************************************************************************
741 };
743 //*************************************************************************************************
744 
745 } // namespace blaze
746 
747 #endif