All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatDMatSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATDMATSUBEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DMATDMATSUBEXPR_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 DMATDMATSUBEXPR
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 DMatDMatSubExpr : public DenseMatrix< DMatDMatSubExpr<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 DMatDMatSubExpr( const MT1& lhs, const MT2& rhs )
156  : lhs_( lhs ) // Left-hand side dense matrix of the subtraction expression
157  , rhs_( rhs ) // Right-hand side dense matrix of the subtraction 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 DMatDMatSubExpr& 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  subAssign( ~lhs, rhs.rhs_ );
280  }
281  else {
282  assign ( ~lhs, rhs.lhs_ );
283  subAssign( ~lhs, rhs.rhs_ );
284  }
285  }
287  //**********************************************************************************************
288 
289  //**Assignment to sparse matrices***************************************************************
303  template< typename MT // Type of the target sparse matrix
304  , bool SO2 > // Storage order of the target sparse matrix
305  friend inline typename EnableIf< UseAssign<MT> >::Type
306  assign( SparseMatrix<MT,SO2>& lhs, const DMatDMatSubExpr& rhs )
307  {
309 
315  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
316 
317  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
318  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
319 
320  const TmpType tmp( rhs );
321  assign( ~lhs, tmp );
322  }
324  //**********************************************************************************************
325 
326  //**Addition assignment to dense matrices*******************************************************
340  template< typename MT // Type of the target dense matrix
341  , bool SO2 > // Storage order of the target dense matrix
342  friend inline typename EnableIf< UseAssign<MT> >::Type
343  addAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatSubExpr& rhs )
344  {
345  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
346  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
347 
348  addAssign( ~lhs, rhs.lhs_ );
349  subAssign( ~lhs, rhs.rhs_ );
350  }
352  //**********************************************************************************************
353 
354  //**Addition assignment to sparse matrices******************************************************
355  // No special implementation for the addition assignment to sparse matrices.
356  //**********************************************************************************************
357 
358  //**Subtraction assignment to dense matrices****************************************************
372  template< typename MT // Type of the target dense matrix
373  , bool SO2 > // Storage order of the target dense matrix
374  friend inline typename EnableIf< UseAssign<MT> >::Type
375  subAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatSubExpr& rhs )
376  {
377  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
378  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
379 
380  subAssign( ~lhs, rhs.lhs_ );
381  addAssign( ~lhs, rhs.rhs_ );
382  }
384  //**********************************************************************************************
385 
386  //**Subtraction assignment to sparse matrices***************************************************
387  // No special implementation for the subtraction assignment to sparse matrices.
388  //**********************************************************************************************
389 
390  //**Multiplication assignment to dense matrices*************************************************
391  // No special implementation for the multiplication assignment to dense matrices.
392  //**********************************************************************************************
393 
394  //**Multiplication assignment to sparse matrices************************************************
395  // No special implementation for the multiplication assignment to sparse matrices.
396  //**********************************************************************************************
397 
398  //**Compile time checks*************************************************************************
403  //**********************************************************************************************
404 };
405 //*************************************************************************************************
406 
407 
408 
409 
410 //=================================================================================================
411 //
412 // GLOBAL BINARY ARITHMETIC OPERATORS
413 //
414 //=================================================================================================
415 
416 //*************************************************************************************************
441 template< typename T1 // Type of the left-hand side dense matrix
442  , typename T2 // Type of the right-hand side dense matrix
443  , bool SO > // Storage order
444 inline const DMatDMatSubExpr<T1,T2,SO>
446 {
447  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
448  throw std::invalid_argument( "Matrix sizes do not match" );
449 
450  return DMatDMatSubExpr<T1,T2,SO>( ~lhs, ~rhs );
451 }
452 //*************************************************************************************************
453 
454 } // namespace blaze
455 
456 #endif