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>
43 #include <blaze/util/Assert.h>
45 #include <blaze/util/EnableIf.h>
46 #include <blaze/util/SelectType.h>
47 #include <blaze/util/Types.h>
49 
50 
51 namespace blaze {
52 
53 //=================================================================================================
54 //
55 // CLASS DMATDMATADDEXPR
56 //
57 //=================================================================================================
58 
59 //*************************************************************************************************
66 template< typename MT1 // Type of the left-hand side dense matrix
67  , typename MT2 // Type of the right-hand side dense matrix
68  , bool SO > // Storage order
69 class DMatDMatAddExpr : public DenseMatrix< DMatDMatAddExpr<MT1,MT2,SO>, SO >
70  , private Expression
71  , private Computation
72 {
73  private:
74  //**Type definitions****************************************************************************
75  typedef typename MT1::ResultType RT1;
76  typedef typename MT2::ResultType RT2;
77  typedef typename MT1::ReturnType RN1;
78  typedef typename MT2::ReturnType RN2;
79  typedef typename MT1::CompositeType CT1;
80  typedef typename MT2::CompositeType CT2;
81  typedef typename MT1::ElementType ET1;
82  typedef typename MT2::ElementType ET2;
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 = RequiresEvaluation<MT1>::value || RequiresEvaluation<MT2>::value || !returnExpr };
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;
125 
128 
131 
133  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
134 
136  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
137  //**********************************************************************************************
138 
139  //**Compilation flags***************************************************************************
141  enum { vectorizable = MT1::vectorizable && MT2::vectorizable &&
144 
146  enum { canAlias = IsExpression<MT1>::value || IsExpression<MT2>::value };
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 || ( j % IT::size == 0UL ), "Invalid column access index" );
190  BLAZE_INTERNAL_ASSERT( !SO || ( i % 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 isAliased( const T* alias ) const {
245  return ( IsExpression<MT1>::value && lhs_.isAliased( alias ) ) ||
246  ( IsExpression<MT2>::value && rhs_.isAliased( alias ) );
247  }
248  //**********************************************************************************************
249 
250  private:
251  //**Member variables****************************************************************************
254  //**********************************************************************************************
255 
256  //**Assignment to dense matrices****************************************************************
270  template< typename MT // Type of the target dense matrix
271  , bool SO2 > // Storage order of the target dense matrix
272  friend inline typename EnableIf< UseAssign<MT> >::Type
273  assign( DenseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
274  {
275  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
276  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
277 
278  if( !IsExpression<MT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
279  addAssign( ~lhs, rhs.rhs_ );
280  }
281  else if( !IsExpression<MT2>::value && (~lhs).isAliased( &rhs.rhs_ ) ) {
282  addAssign( ~lhs, rhs.lhs_ );
283  }
284  else {
285  assign ( ~lhs, rhs.lhs_ );
286  addAssign( ~lhs, rhs.rhs_ );
287  }
288  }
290  //**********************************************************************************************
291 
292  //**Assignment to sparse matrices***************************************************************
306  template< typename MT // Type of the target sparse matrix
307  , bool SO2 > // Storage order of the target sparse matrix
308  friend inline typename EnableIf< UseAssign<MT> >::Type
309  assign( SparseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
310  {
312 
318  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
319 
320  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
321  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
322 
323  const TmpType tmp( rhs );
324  assign( ~lhs, tmp );
325  }
327  //**********************************************************************************************
328 
329  //**Addition assignment to dense matrices*******************************************************
343  template< typename MT // Type of the target dense matrix
344  , bool SO2 > // Storage order of the target dense matrix
345  friend inline typename EnableIf< UseAssign<MT> >::Type
346  addAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
347  {
348  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
349  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
350 
351  addAssign( ~lhs, rhs.lhs_ );
352  addAssign( ~lhs, rhs.rhs_ );
353  }
355  //**********************************************************************************************
356 
357  //**Addition assignment to sparse matrices******************************************************
358  // No special implementation for the addition assignment to sparse matrices.
359  //**********************************************************************************************
360 
361  //**Subtraction assignment to dense matrices****************************************************
375  template< typename MT // Type of the target dense matrix
376  , bool SO2 > // Storage order of the target dense matrix
377  friend inline typename EnableIf< UseAssign<MT> >::Type
378  subAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatAddExpr& rhs )
379  {
380  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
381  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
382 
383  subAssign( ~lhs, rhs.lhs_ );
384  subAssign( ~lhs, rhs.rhs_ );
385  }
387  //**********************************************************************************************
388 
389  //**Subtraction assignment to sparse matrices***************************************************
390  // No special implementation for the subtraction assignment to sparse matrices.
391  //**********************************************************************************************
392 
393  //**Multiplication assignment to dense matrices*************************************************
394  // No special implementation for the multiplication assignment to dense matrices.
395  //**********************************************************************************************
396 
397  //**Multiplication assignment to sparse matrices************************************************
398  // No special implementation for the multiplication assignment to sparse matrices.
399  //**********************************************************************************************
400 
401  //**Compile time checks*************************************************************************
407  //**********************************************************************************************
408 };
409 //*************************************************************************************************
410 
411 
412 
413 
414 //=================================================================================================
415 //
416 // GLOBAL BINARY ARITHMETIC OPERATORS
417 //
418 //=================================================================================================
419 
420 //*************************************************************************************************
447 template< typename T1 // Type of the left-hand side dense matrix
448  , typename T2 // Type of the right-hand side dense matrix
449  , bool SO > // Storage order
450 inline const DMatDMatAddExpr<T1,T2,SO>
452 {
453  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
454  throw std::invalid_argument( "Matrix sizes do not match" );
455 
456  return DMatDMatAddExpr<T1,T2,SO>( ~lhs, ~rhs );
457 }
458 //*************************************************************************************************
459 
460 } // namespace blaze
461 
462 #endif