All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatTDMatSubExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTDMATSUBEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DMATTDMATSUBEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
44 #include <blaze/util/Assert.h>
47 #include <blaze/util/SelectType.h>
48 #include <blaze/util/Types.h>
49 
50 
51 namespace blaze {
52 
53 //=================================================================================================
54 //
55 // CLASS DMATTDMATSUBEXPR
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 class DMatTDMatSubExpr : public DenseMatrix< DMatTDMatSubExpr<MT1,MT2>, false >
69  , private MatMatSubExpr
70  , private Computation
71 {
72  private:
73  //**Type definitions****************************************************************************
74  typedef typename MT1::ResultType RT1;
75  typedef typename MT2::ResultType RT2;
76  typedef typename MT1::ReturnType RN1;
77  typedef typename MT2::ReturnType RN2;
78  typedef typename MT1::CompositeType CT1;
79  typedef typename MT2::CompositeType CT2;
80  //**********************************************************************************************
81 
82  //**Return type evaluation**********************************************************************
84 
89  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
90 
93  //**********************************************************************************************
94 
95  public:
96  //**Type definitions****************************************************************************
99  typedef typename ResultType::OppositeType OppositeType;
100  typedef typename ResultType::TransposeType TransposeType;
101  typedef typename ResultType::ElementType ElementType;
102 
105 
107  typedef const ResultType CompositeType;
108 
110  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
111 
113  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
114  //**********************************************************************************************
115 
116  //**Compilation flags***************************************************************************
118  enum { vectorizable = 0 };
119  //**********************************************************************************************
120 
121  //**Constructor*********************************************************************************
127  explicit inline DMatTDMatSubExpr( const MT1& lhs, const MT2& rhs )
128  : lhs_( lhs ) // Left-hand side dense matrix of the subtraction expression
129  , rhs_( rhs ) // Right-hand side dense matrix of the subtraction expression
130  {
131  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
132  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
133  }
134  //**********************************************************************************************
135 
136  //**Access operator*****************************************************************************
143  inline ReturnType operator()( size_t i, size_t j ) const {
144  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
145  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
146  return lhs_(i,j) - rhs_(i,j);
147  }
148  //**********************************************************************************************
149 
150  //**Rows function*******************************************************************************
155  inline size_t rows() const {
156  return lhs_.rows();
157  }
158  //**********************************************************************************************
159 
160  //**Columns function****************************************************************************
165  inline size_t columns() const {
166  return lhs_.columns();
167  }
168  //**********************************************************************************************
169 
170  //**Left operand access*************************************************************************
175  inline LeftOperand leftOperand() const {
176  return lhs_;
177  }
178  //**********************************************************************************************
179 
180  //**Right operand access************************************************************************
185  inline RightOperand rightOperand() const {
186  return rhs_;
187  }
188  //**********************************************************************************************
189 
190  //**********************************************************************************************
196  template< typename T >
197  inline bool canAlias( const T* alias ) const {
198  return ( IsExpression<MT1>::value && ( RequiresEvaluation<MT1>::value ? lhs_.isAliased( alias ) : lhs_.canAlias( alias ) ) ) ||
199  ( IsExpression<MT2>::value && ( RequiresEvaluation<MT2>::value ? rhs_.isAliased( alias ) : rhs_.canAlias( alias ) ) );
200  }
201  //**********************************************************************************************
202 
203  //**********************************************************************************************
209  template< typename T >
210  inline bool isAliased( const T* alias ) const {
211  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
212  }
213  //**********************************************************************************************
214 
215  private:
216  //**Member variables****************************************************************************
219  //**********************************************************************************************
220 
221  //**Assignment to dense matrices****************************************************************
233  template< typename MT // Type of the target dense matrix
234  , bool SO2 > // Storage order of the target dense matrix
235  friend inline void assign( DenseMatrix<MT,SO2>& lhs, const DMatTDMatSubExpr& rhs )
236  {
238 
239  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
240  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
241 
242  // In case non of the two dense operands requires an intermediate evaluation, the
243  // addition expression is assigned directly in a cache-efficient manner.
245  {
246  const size_t m( rhs.rows() );
247  const size_t n( rhs.columns() );
248  const size_t block( 16UL );
249 
250  for( size_t ii=0UL; ii<m; ii+=block ) {
251  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
252  for( size_t jj=0UL; jj<n; jj+=block ) {
253  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
254  for( size_t i=ii; i<iend; ++i ) {
255  for( size_t j=jj; j<jend; ++j ) {
256  (~lhs)(i,j) = rhs.lhs_(i,j) - rhs.rhs_(i,j);
257  }
258  }
259  }
260  }
261  }
262 
263  // In case either of the two dense operands requires an intermediate evaluation, the
264  // expression is evaluated in a one- or two-step approach (depending on whether any
265  // of the operands is aliased with the target matrix).
266  else if( !IsExpression<MT1>::value && (~lhs).isAliased( &rhs.lhs_ ) ) {
267  subAssign( ~lhs, rhs.rhs_ );
268  }
269  else {
270  assign ( ~lhs, rhs.lhs_ );
271  subAssign( ~lhs, rhs.rhs_ );
272  }
273  }
275  //**********************************************************************************************
276 
277  //**Assignment to sparse matrices***************************************************************
289  template< typename MT // Type of the target sparse matrix
290  , bool SO2 > // Storage order of the target sparse matrix
291  friend inline void assign( SparseMatrix<MT,SO2>& lhs, const DMatTDMatSubExpr& rhs )
292  {
294 
295  typedef typename SelectType< SO2, OppositeType, ResultType >::Type TmpType;
296 
302  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename TmpType::CompositeType );
303 
304  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
305  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
306 
307  const TmpType tmp( rhs );
308  assign( ~lhs, tmp );
309  }
311  //**********************************************************************************************
312 
313  //**Addition assignment to dense matrices*******************************************************
326  template< typename MT // Type of the target dense matrix
327  , bool SO2 > // Storage order of the target dense matrix
328  friend inline void addAssign( DenseMatrix<MT,SO2>& lhs, const DMatTDMatSubExpr& rhs )
329  {
331 
332  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
333  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
334 
335  // In case non of the two dense operands requires an intermediate evaluation, the
336  // addition expression is assigned directly in a cache-efficient manner.
337  if( !RequiresEvaluation<MT1>::value && !RequiresEvaluation<MT2>::value )
338  {
339  const size_t m( rhs.rows() );
340  const size_t n( rhs.columns() );
341  const size_t block( 16UL );
342 
343  for( size_t ii=0UL; ii<m; ii+=block ) {
344  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
345  for( size_t jj=0UL; jj<n; jj+=block ) {
346  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
347  for( size_t i=ii; i<iend; ++i ) {
348  for( size_t j=jj; j<jend; ++j ) {
349  (~lhs)(i,j) += rhs.lhs_(i,j) - rhs.rhs_(i,j);
350  }
351  }
352  }
353  }
354  }
355 
356  // In case either of the two dense operands requires an intermediate evaluation, the
357  // expression is evaluated in a two-step approach.
358  else
359  {
360  addAssign( ~lhs, rhs.lhs_ );
361  subAssign( ~lhs, rhs.rhs_ );
362  }
363  }
365  //**********************************************************************************************
366 
367  //**Addition assignment to sparse matrices******************************************************
368  // No special implementation for the addition assignment to sparse matrices.
369  //**********************************************************************************************
370 
371  //**Subtraction assignment to dense matrices****************************************************
384  template< typename MT // Type of the target dense matrix
385  , bool SO2 > // Storage order of the target dense matrix
386  friend inline void subAssign( DenseMatrix<MT,SO2>& lhs, const DMatTDMatSubExpr& rhs )
387  {
389 
390  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
391  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
392 
393  // In case non of the two dense operands requires an intermediate evaluation, the
394  // addition expression is assigned directly in a cache-efficient manner.
395  if( !RequiresEvaluation<MT1>::value && !RequiresEvaluation<MT2>::value )
396  {
397  const size_t m( rhs.rows() );
398  const size_t n( rhs.columns() );
399  const size_t block( 16UL );
400 
401  for( size_t ii=0UL; ii<m; ii+=block ) {
402  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
403  for( size_t jj=0UL; jj<n; jj+=block ) {
404  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
405  for( size_t i=ii; i<iend; ++i ) {
406  for( size_t j=jj; j<jend; ++j ) {
407  (~lhs)(i,j) -= rhs.lhs_(i,j) - rhs.rhs_(i,j);
408  }
409  }
410  }
411  }
412  }
413 
414  // In case either of the two dense operands requires an intermediate evaluation, the
415  // expression is evaluated in a two-step approach.
416  else
417  {
418  subAssign( ~lhs, rhs.lhs_ );
419  addAssign( ~lhs, rhs.rhs_ );
420  }
421  }
423  //**********************************************************************************************
424 
425  //**Subtraction assignment to sparse matrices***************************************************
426  // No special implementation for the subtraction assignment to sparse matrices.
427  //**********************************************************************************************
428 
429  //**Multiplication assignment to dense matrices*************************************************
430  // No special implementation for the multiplication assignment to dense matrices.
431  //**********************************************************************************************
432 
433  //**Multiplication assignment to sparse matrices************************************************
434  // No special implementation for the multiplication assignment to sparse matrices.
435  //**********************************************************************************************
436 
437  //**Compile time checks*************************************************************************
443  //**********************************************************************************************
444 };
445 //*************************************************************************************************
446 
447 
448 
449 
450 //=================================================================================================
451 //
452 // GLOBAL BINARY ARITHMETIC OPERATORS
453 //
454 //=================================================================================================
455 
456 //*************************************************************************************************
485 template< typename T1 // Type of the left-hand side dense matrix
486  , typename T2 > // Type of the right-hand side dense matrix
487 inline const DMatTDMatSubExpr<T1,T2>
489 {
491 
492  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
493  throw std::invalid_argument( "Matrix sizes do not match" );
494 
495  return DMatTDMatSubExpr<T1,T2>( ~lhs, ~rhs );
496 }
497 //*************************************************************************************************
498 
499 
500 //*************************************************************************************************
529 template< typename T1 // Type of the left-hand side dense matrix
530  , typename T2 > // Type of the right-hand side dense matrix
531 inline const DMatTDMatSubExpr<T1,T2>
533 {
535 
536  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
537  throw std::invalid_argument( "Matrix sizes do not match" );
538 
539  return DMatTDMatSubExpr<T1,T2>( ~lhs, ~rhs );
540 }
541 //*************************************************************************************************
542 
543 
544 
545 
546 //=================================================================================================
547 //
548 // EXPRESSION TRAIT SPECIALIZATIONS
549 //
550 //=================================================================================================
551 
552 //*************************************************************************************************
554 template< typename MT1, typename MT2 >
555 struct RowExprTrait< DMatTDMatSubExpr<MT1,MT2> >
556 {
557  public:
558  //**********************************************************************************************
559  typedef typename SubExprTrait< typename RowExprTrait<const MT1>::Type
560  , typename RowExprTrait<const MT2>::Type >::Type Type;
561  //**********************************************************************************************
562 };
564 //*************************************************************************************************
565 
566 
567 //*************************************************************************************************
569 template< typename MT1, typename MT2 >
570 struct ColumnExprTrait< DMatTDMatSubExpr<MT1,MT2> >
571 {
572  public:
573  //**********************************************************************************************
574  typedef typename SubExprTrait< typename ColumnExprTrait<const MT1>::Type
575  , typename ColumnExprTrait<const MT2>::Type >::Type Type;
576  //**********************************************************************************************
577 };
579 //*************************************************************************************************
580 
581 } // namespace blaze
582 
583 #endif