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>
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 DMATDMATSUBEXPR
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 DMatDMatSubExpr : public DenseMatrix< DMatDMatSubExpr<MT1,MT2,SO>, SO >
73  , private MatMatSubExpr
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 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 || ( 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 DMatDMatSubExpr& 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  subAssign( ~lhs, rhs.rhs_ );
294  }
295  else {
296  assign ( ~lhs, rhs.lhs_ );
297  subAssign( ~lhs, rhs.rhs_ );
298  }
299  }
301  //**********************************************************************************************
302 
303  //**Assignment to sparse matrices***************************************************************
317  template< typename MT // Type of the target sparse matrix
318  , bool SO2 > // Storage order of the target sparse matrix
319  friend inline typename EnableIf< UseAssign<MT> >::Type
320  assign( SparseMatrix<MT,SO2>& lhs, const DMatDMatSubExpr& rhs )
321  {
323 
325 
331  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
332 
333  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
334  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
335 
336  const TmpType tmp( rhs );
337  assign( ~lhs, tmp );
338  }
340  //**********************************************************************************************
341 
342  //**Addition assignment to dense matrices*******************************************************
356  template< typename MT // Type of the target dense matrix
357  , bool SO2 > // Storage order of the target dense matrix
358  friend inline typename EnableIf< UseAssign<MT> >::Type
359  addAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatSubExpr& rhs )
360  {
362 
363  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
364  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
365 
366  addAssign( ~lhs, rhs.lhs_ );
367  subAssign( ~lhs, rhs.rhs_ );
368  }
370  //**********************************************************************************************
371 
372  //**Addition assignment to sparse matrices******************************************************
373  // No special implementation for the addition assignment to sparse matrices.
374  //**********************************************************************************************
375 
376  //**Subtraction assignment to dense matrices****************************************************
390  template< typename MT // Type of the target dense matrix
391  , bool SO2 > // Storage order of the target dense matrix
392  friend inline typename EnableIf< UseAssign<MT> >::Type
393  subAssign( DenseMatrix<MT,SO2>& lhs, const DMatDMatSubExpr& rhs )
394  {
396 
397  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
398  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
399 
400  subAssign( ~lhs, rhs.lhs_ );
401  addAssign( ~lhs, rhs.rhs_ );
402  }
404  //**********************************************************************************************
405 
406  //**Subtraction assignment to sparse matrices***************************************************
407  // No special implementation for the subtraction assignment to sparse matrices.
408  //**********************************************************************************************
409 
410  //**Multiplication assignment to dense matrices*************************************************
411  // No special implementation for the multiplication assignment to dense matrices.
412  //**********************************************************************************************
413 
414  //**Multiplication assignment to sparse matrices************************************************
415  // No special implementation for the multiplication assignment to sparse matrices.
416  //**********************************************************************************************
417 
418  //**Compile time checks*************************************************************************
423  //**********************************************************************************************
424 };
425 //*************************************************************************************************
426 
427 
428 
429 
430 //=================================================================================================
431 //
432 // GLOBAL BINARY ARITHMETIC OPERATORS
433 //
434 //=================================================================================================
435 
436 //*************************************************************************************************
461 template< typename T1 // Type of the left-hand side dense matrix
462  , typename T2 // Type of the right-hand side dense matrix
463  , bool SO > // Storage order
464 inline const DMatDMatSubExpr<T1,T2,SO>
466 {
468 
469  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
470  throw std::invalid_argument( "Matrix sizes do not match" );
471 
472  return DMatDMatSubExpr<T1,T2,SO>( ~lhs, ~rhs );
473 }
474 //*************************************************************************************************
475 
476 
477 
478 
479 //=================================================================================================
480 //
481 // EXPRESSION TRAIT SPECIALIZATIONS
482 //
483 //=================================================================================================
484 
485 //*************************************************************************************************
487 template< typename MT1, typename MT2, bool SO >
488 struct RowExprTrait< DMatDMatSubExpr<MT1,MT2,SO> >
489 {
490  public:
491  //**********************************************************************************************
492  typedef typename SubExprTrait< typename RowExprTrait<const MT1>::Type
493  , typename RowExprTrait<const MT2>::Type >::Type Type;
494  //**********************************************************************************************
495 };
497 //*************************************************************************************************
498 
499 
500 //*************************************************************************************************
502 template< typename MT1, typename MT2, bool SO >
503 struct ColumnExprTrait< DMatDMatSubExpr<MT1,MT2,SO> >
504 {
505  public:
506  //**********************************************************************************************
507  typedef typename SubExprTrait< typename ColumnExprTrait<const MT1>::Type
508  , typename ColumnExprTrait<const MT2>::Type >::Type Type;
509  //**********************************************************************************************
510 };
512 //*************************************************************************************************
513 
514 } // namespace blaze
515 
516 #endif