All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatDMatAddExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATDMATADDEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DMATDMATADDEXPR_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>
49 #include <blaze/util/SelectType.h>
50 #include <blaze/util/Types.h>
52 
53 
54 namespace blaze {
55 
56 //=================================================================================================
57 //
58 // CLASS DMATDMATADDEXPR
59 //
60 //=================================================================================================
61 
62 //*************************************************************************************************
69 template< typename MT1 // Type of the left-hand side dense matrix
70  , typename MT2 // Type of the right-hand side dense matrix
71  , bool SO > // Storage order
72 class DMatDMatAddExpr : public DenseMatrix< DMatDMatAddExpr<MT1,MT2,SO>, SO >
73  , private MatMatAddExpr
74  , private Computation
75 {
76  private:
77  //**Type definitions****************************************************************************
78  typedef typename MT1::ResultType RT1;
79  typedef typename MT2::ResultType RT2;
80  typedef typename MT1::ReturnType RN1;
81  typedef typename MT2::ReturnType RN2;
82  typedef typename MT1::CompositeType CT1;
83  typedef typename MT2::CompositeType CT2;
84  typedef typename MT1::ElementType ET1;
85  typedef typename MT2::ElementType ET2;
86  //**********************************************************************************************
87 
88  //**Return type evaluation**********************************************************************
90 
95  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
96 
99  //**********************************************************************************************
100 
101  //**Evaluation strategy*************************************************************************
103 
109  enum { useAssign = RequiresEvaluation<MT1>::value || RequiresEvaluation<MT2>::value || !returnExpr };
110 
112 
113  template< typename VT >
114  struct UseAssign {
115  enum { value = useAssign };
116  };
118  //**********************************************************************************************
119 
120  public:
121  //**Type definitions****************************************************************************
124  typedef typename ResultType::OppositeType OppositeType;
125  typedef typename ResultType::TransposeType TransposeType;
126  typedef typename ResultType::ElementType ElementType;
128 
131 
134 
136  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
137 
139  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
140  //**********************************************************************************************
141 
142  //**Compilation flags***************************************************************************
144  enum { vectorizable = MT1::vectorizable && MT2::vectorizable &&
147  //**********************************************************************************************
148 
149  //**Constructor*********************************************************************************
155  explicit inline DMatDMatAddExpr( const MT1& lhs, const MT2& rhs )
156  : lhs_( lhs ) // Left-hand side dense matrix of the addition expression
157  , rhs_( rhs ) // Right-hand side dense matrix of the addition expression
158  {
159  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
160  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
161  }
162  //**********************************************************************************************
163 
164  //**Access operator*****************************************************************************
171  inline ReturnType operator()( size_t i, size_t j ) const {
172  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
173  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
174  return lhs_(i,j) + rhs_(i,j);
175  }
176  //**********************************************************************************************
177 
178  //**Get function********************************************************************************
185  inline IntrinsicType get( size_t i, size_t j ) const {
186  typedef IntrinsicTrait<ElementType> IT;
187  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
188  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
189  BLAZE_INTERNAL_ASSERT( !SO || ( i % IT::size == 0UL ), "Invalid row access index" );
190  BLAZE_INTERNAL_ASSERT( SO || ( j % IT::size == 0UL ), "Invalid column access index" );
191  const IntrinsicType xmm1( lhs_.get(i,j) );
192  const IntrinsicType xmm2( rhs_.get(i,j) );
193  return xmm1 + xmm2;
194  }
195  //**********************************************************************************************
196 
197  //**Rows function*******************************************************************************
202  inline size_t rows() const {
203  return lhs_.rows();
204  }
205  //**********************************************************************************************
206 
207  //**Columns function****************************************************************************
212  inline size_t columns() const {
213  return lhs_.columns();
214  }
215  //**********************************************************************************************
216 
217  //**Left operand access*************************************************************************
222  inline LeftOperand leftOperand() const {
223  return lhs_;
224  }
225  //**********************************************************************************************
226 
227  //**Right operand access************************************************************************
232  inline RightOperand rightOperand() const {
233  return rhs_;
234  }
235  //**********************************************************************************************
236 
237  //**********************************************************************************************
243  template< typename T >
244  inline bool canAlias( const T* alias ) const {
245  return ( IsExpression<MT1>::value && ( RequiresEvaluation<MT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
246  ( IsExpression<MT2>::value && ( RequiresEvaluation<MT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
247  }
248  //**********************************************************************************************
249 
250  //**********************************************************************************************
256  template< typename T >
257  inline bool isAliased( const T* alias ) const {
258  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
259  }
260  //**********************************************************************************************
261 
262  private:
263  //**Member variables****************************************************************************
266  //**********************************************************************************************
267 
268  //**Assignment to dense matrices****************************************************************
282  template< typename MT // Type of the target dense matrix
283  , bool SO2 > // Storage order of the target dense matrix
284  friend inline typename EnableIf< UseAssign<MT> >::Type
285  assign( DenseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
286  {
288 
289  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
290  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
291 
292  if( !IsExpression<MT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
293  addAssign( ~lhs, rhs.rhs_ );
294  }
295  else if( !IsExpression<MT2>::value && (~lhs).isAliased( &rhs.rhs_ ) ) {
296  addAssign( ~lhs, rhs.lhs_ );
297  }
298  else {
299  assign ( ~lhs, rhs.lhs_ );
300  addAssign( ~lhs, rhs.rhs_ );
301  }
302  }
304  //**********************************************************************************************
305 
306  //**Assignment to sparse matrices***************************************************************
320  template< typename MT // Type of the target sparse matrix
321  , bool SO2 > // Storage order of the target sparse matrix
322  friend inline typename EnableIf< UseAssign<MT> >::Type
323  assign( SparseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
324  {
326 
328 
334  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
335 
336  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
337  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
338 
339  const TmpType tmp( rhs );
340  assign( ~lhs, tmp );
341  }
343  //**********************************************************************************************
344 
345  //**Addition assignment to dense matrices*******************************************************
359  template< typename MT // Type of the target dense matrix
360  , bool SO2 > // Storage order of the target dense matrix
361  friend inline typename EnableIf< UseAssign<MT> >::Type
362  addAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
363  {
365 
366  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
367  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
368 
369  addAssign( ~lhs, rhs.lhs_ );
370  addAssign( ~lhs, rhs.rhs_ );
371  }
373  //**********************************************************************************************
374 
375  //**Addition assignment to sparse matrices******************************************************
376  // No special implementation for the addition assignment to sparse matrices.
377  //**********************************************************************************************
378 
379  //**Subtraction assignment to dense matrices****************************************************
393  template< typename MT // Type of the target dense matrix
394  , bool SO2 > // Storage order of the target dense matrix
395  friend inline typename EnableIf< UseAssign<MT> >::Type
396  subAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& 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  subAssign( ~lhs, rhs.lhs_ );
404  subAssign( ~lhs, rhs.rhs_ );
405  }
407  //**********************************************************************************************
408 
409  //**Subtraction assignment to sparse matrices***************************************************
410  // No special implementation for the subtraction assignment to sparse matrices.
411  //**********************************************************************************************
412 
413  //**Multiplication assignment to dense matrices*************************************************
414  // No special implementation for the multiplication assignment to dense matrices.
415  //**********************************************************************************************
416 
417  //**Multiplication assignment to sparse matrices************************************************
418  // No special implementation for the multiplication assignment to sparse matrices.
419  //**********************************************************************************************
420 
421  //**Compile time checks*************************************************************************
427  //**********************************************************************************************
428 };
429 //*************************************************************************************************
430 
431 
432 
433 
434 //=================================================================================================
435 //
436 // GLOBAL BINARY ARITHMETIC OPERATORS
437 //
438 //=================================================================================================
439 
440 //*************************************************************************************************
467 template< typename T1 // Type of the left-hand side dense matrix
468  , typename T2 // Type of the right-hand side dense matrix
469  , bool SO > // Storage order
470 inline const DMatDMatAddExpr<T1,T2,SO>
472 {
474 
475  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
476  throw std::invalid_argument( "Matrix sizes do not match" );
477 
478  return DMatDMatAddExpr<T1,T2,SO>( ~lhs, ~rhs );
479 }
480 //*************************************************************************************************
481 
482 
483 
484 
485 //=================================================================================================
486 //
487 // EXPRESSION TRAIT SPECIALIZATIONS
488 //
489 //=================================================================================================
490 
491 //*************************************************************************************************
493 template< typename MT1, typename MT2, bool SO >
494 struct RowExprTrait< DMatDMatAddExpr<MT1,MT2,SO> >
495 {
496  public:
497  //**********************************************************************************************
498  typedef typename AddExprTrait< typename RowExprTrait<const MT1>::Type
499  , typename RowExprTrait<const MT2>::Type >::Type Type;
500  //**********************************************************************************************
501 };
503 //*************************************************************************************************
504 
505 
506 //*************************************************************************************************
508 template< typename MT1, typename MT2, bool SO >
509 struct ColumnExprTrait< DMatDMatAddExpr<MT1,MT2,SO> >
510 {
511  public:
512  //**********************************************************************************************
513  typedef typename AddExprTrait< typename ColumnExprTrait<const MT1>::Type
514  , typename ColumnExprTrait<const MT2>::Type >::Type Type;
515  //**********************************************************************************************
516 };
518 //*************************************************************************************************
519 
520 } // namespace blaze
521 
522 #endif