All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatScalarDivExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATSCALARDIVEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_DMATSCALARDIVEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
48 #include <blaze/util/Assert.h>
53 #include <blaze/util/EnableIf.h>
54 #include <blaze/util/InvalidType.h>
55 #include <blaze/util/SelectType.h>
56 #include <blaze/util/Types.h>
59 
60 
61 namespace blaze {
62 
63 //=================================================================================================
64 //
65 // CLASS DMATSCALARDIVEXPRHELPER
66 //
67 //=================================================================================================
68 
69 //*************************************************************************************************
76 template< typename MT // Type of the left-hand side dense matrix
77  , typename ST // Type of the right-hand side scalar value
78  , bool SO > // Storage order
80 {
81  public:
82  //**Type definitions****************************************************************************
85  //**********************************************************************************************
86 
87  //**********************************************************************************************
89  enum { value = IsFloatingPoint<ScalarType>::value };
90  //**********************************************************************************************
91 
92  //**Type definitions****************************************************************************
94  typedef typename SelectType< value,
97  //**********************************************************************************************
98 
99  private:
100  //**Compile time checks*************************************************************************
107  //**********************************************************************************************
108 };
109 //*************************************************************************************************
110 
111 
112 
113 
114 //=================================================================================================
115 //
116 // CLASS DMATSCALARDIVEXPR
117 //
118 //=================================================================================================
119 
120 //*************************************************************************************************
127 template< typename MT // Type of the left-hand side dense matrix
128  , typename ST // Type of the right-hand side scalar value
129  , bool SO > // Storage order
130 class DMatScalarDivExpr : public DenseMatrix< DMatScalarDivExpr<MT,ST,SO>, SO >
131  , private Expression
132  , private Computation
133 {
134  private:
135  //**Type definitions****************************************************************************
136  typedef typename MT::ResultType RT;
137  typedef typename MT::ReturnType RN;
138  typedef typename MT::CompositeType CT;
139  //**********************************************************************************************
140 
141  //**Return type evaluation**********************************************************************
143 
148  enum { returnExpr = !IsTemporary<RN>::value };
149 
152  //**********************************************************************************************
153 
154  //**Evaluation strategy*************************************************************************
156 
162  enum { useAssign = RequiresEvaluation<MT>::value };
163 
165 
166  template< typename MT2 >
167  struct UseAssign {
168  enum { value = useAssign };
169  };
171  //**********************************************************************************************
172 
173  public:
174  //**Type definitions****************************************************************************
177  typedef typename ResultType::OppositeType OppositeType;
178  typedef typename ResultType::TransposeType TransposeType;
179  typedef typename ResultType::ElementType ElementType;
180 
183 
186 
188  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
189 
192  //**********************************************************************************************
193 
194  //**Compilation flags***************************************************************************
196  enum { vectorizable = 0 };
197 
199  enum { canAlias = CanAlias<MT>::value };
200  //**********************************************************************************************
201 
202  //**Constructor*********************************************************************************
208  explicit inline DMatScalarDivExpr( const MT& matrix, ST scalar )
209  : matrix_( matrix ) // Left-hand side dense matrix of the division expression
210  , scalar_( scalar ) // Right-hand side scalar of the division expression
211  {}
212  //**********************************************************************************************
213 
214  //**Access operator*****************************************************************************
221  inline ReturnType operator()( size_t i, size_t j ) const {
222  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
223  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
224  return matrix_(i,j) / scalar_;
225  }
226  //**********************************************************************************************
227 
228  //**Rows function*******************************************************************************
233  inline size_t rows() const {
234  return matrix_.rows();
235  }
236  //**********************************************************************************************
237 
238  //**Columns function****************************************************************************
243  inline size_t columns() const {
244  return matrix_.columns();
245  }
246  //**********************************************************************************************
247 
248  //**Left operand access*************************************************************************
253  inline LeftOperand leftOperand() const {
254  return matrix_;
255  }
256  //**********************************************************************************************
257 
258  //**Right operand access************************************************************************
263  inline RightOperand rightOperand() const {
264  return scalar_;
265  }
266  //**********************************************************************************************
267 
268  //**********************************************************************************************
274  template< typename T >
275  inline bool isAliased( const T* alias ) const {
276  return CanAlias<MT>::value && matrix_.isAliased( alias );
277  }
278  //**********************************************************************************************
279 
280  private:
281  //**Member variables****************************************************************************
284  //**********************************************************************************************
285 
286  //**Assignment to row-major dense matrices******************************************************
300  template< typename MT2 > // Type of the target dense matrix
301  friend inline typename EnableIf< UseAssign<MT2> >::Type
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  assign( ~lhs, rhs.matrix_ );
308  (~lhs) /= rhs.scalar_;
309  }
311  //**********************************************************************************************
312 
313  //**Assignment to column-major dense matrices***************************************************
327  template< typename MT2 > // Type of the target dense matrix
328  friend inline typename EnableIf< UseAssign<MT2> >::Type
330  {
331  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
332  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
333 
334  assign( ~lhs, rhs.matrix_ );
335  (~lhs) /= rhs.scalar_;
336  }
338  //**********************************************************************************************
339 
340  //**Assignment to row-major sparse matrices*****************************************************
354  template< typename MT2 > // Type of the target sparse matrix
355  friend inline typename EnableIf< UseAssign<MT2> >::Type
357  {
358  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
360 
361  assign( ~lhs, rhs.matrix_ );
362 
363  for( size_t i=0UL; i<(~lhs).rows(); ++i )
364  {
365  typename MT2::Iterator element( (~lhs).begin(i) );
366  const typename MT2::Iterator end( (~lhs).end(i) );
367 
368  for( ; element!=end; ++element )
369  element->value() /= rhs.scalar_;
370  }
371  }
373  //**********************************************************************************************
374 
375  //**Assignment to column-major sparse matrices**************************************************
389  template< typename MT2 > // Type of the target sparse matrix
390  friend inline typename EnableIf< UseAssign<MT2> >::Type
392  {
393  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
394  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
395 
396  assign( ~lhs, rhs.matrix_ );
397 
398  for( size_t j=0UL; j<(~lhs).columns(); ++j )
399  {
400  typename MT2::Iterator element( (~lhs).begin(j) );
401  const typename MT2::Iterator end( (~lhs).end(j) );
402 
403  for( ; element!=end; ++element )
404  element->value() /= rhs.scalar_;
405  }
406  }
408  //**********************************************************************************************
409 
410  //**Addition assignment to dense matrices*******************************************************
424  template< typename MT2 // Type of the target dense matrix
425  , bool SO2 > // Storage order of the target dense matrix
426  friend inline typename EnableIf< UseAssign<MT2> >::Type
427  addAssign( DenseMatrix<MT2,SO2>& lhs, const DMatScalarDivExpr& rhs )
428  {
431  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
432 
433  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
434  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
435 
436  const ResultType tmp( rhs );
437  addAssign( ~lhs, tmp );
438  }
440  //**********************************************************************************************
441 
442  //**Addition assignment to sparse matrices******************************************************
443  // No special implementation for the addition assignment to sparse matrices.
444  //**********************************************************************************************
445 
446  //**Subtraction assignment to dense matrices****************************************************
460  template< typename MT2 // Type of the target dense matrix
461  , bool SO2 > // Storage order of the target dense matrix
462  friend inline typename EnableIf< UseAssign<MT2> >::Type
463  subAssign( DenseMatrix<MT2,SO2>& lhs, const DMatScalarDivExpr& rhs )
464  {
467  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
468 
469  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
470  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
471 
472  const ResultType tmp( rhs );
473  subAssign( ~lhs, tmp );
474  }
476  //**********************************************************************************************
477 
478  //**Subtraction assignment to sparse matrices***************************************************
479  // No special implementation for the subtraction assignment to sparse matrices.
480  //**********************************************************************************************
481 
482  //**Multiplication assignment to dense matrices*************************************************
483  // No special implementation for the multiplication assignment to dense matrices.
484  //**********************************************************************************************
485 
486  //**Multiplication assignment to sparse matrices************************************************
487  // No special implementation for the multiplication assignment to sparse matrices.
488  //**********************************************************************************************
489 
490  //**Compile time checks*************************************************************************
499  //**********************************************************************************************
500 };
501 //*************************************************************************************************
502 
503 
504 
505 
506 //=================================================================================================
507 //
508 // GLOBAL BINARY ARITHMETIC OPERATORS
509 //
510 //=================================================================================================
511 
512 //*************************************************************************************************
534 template< typename T1 // Type of the left-hand side dense matrix
535  , bool SO // Storage order of the left-hand side dense matrix
536  , typename T2 > // Type of the right-hand side scalar
537 inline const typename EnableIf< IsNumeric<T2>
538  , typename DMatScalarDivExprHelper<T1,T2,SO>::Type >::Type
539  operator/( const DenseMatrix<T1,SO>& mat, T2 scalar )
540 {
541  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
542 
543  typedef DMatScalarDivExprHelper<T1,T2,SO> Helper;
544  typedef typename Helper::ScalarType ScalarType;
545 
546  if( Helper::value ) {
547  return typename Helper::Type( ~mat, ScalarType(1)/ScalarType(scalar) );
548  }
549  else {
550  return typename Helper::Type( ~mat, scalar );
551  }
552 }
553 //*************************************************************************************************
554 
555 
556 
557 
558 //=================================================================================================
559 //
560 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
561 //
562 //=================================================================================================
563 
564 //*************************************************************************************************
577 template< typename MT // Type of the dense matrix of the left-hand side expression
578  , typename ST1 // Type of the scalar of the left-hand side expression
579  , bool SO // Storage order of the dense matrix
580  , typename ST2 > // Type of the right-hand side scalar
581 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
582  , typename MultExprTrait< DMatScalarDivExpr<MT,ST1,SO>, ST2 >::Type >::Type
583  operator*( const DMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
584 {
585  return mat.leftOperand() * ( scalar / mat.rightOperand() );
586 }
588 //*************************************************************************************************
589 
590 
591 //*************************************************************************************************
604 template< typename ST1 // Type of the left-hand side scalar
605  , typename MT // Type of the dense matrix of the right-hand side expression
606  , typename ST2 // Type of the scalar of the right-hand side expression
607  , bool SO > // Storage order of the dense matrix
608 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
609  , typename MultExprTrait< ST1, DMatScalarDivExpr<MT,ST2,SO> >::Type >::Type
610  operator*( ST1 scalar, const DMatScalarDivExpr<MT,ST2,SO>& mat )
611 {
612  return mat.leftOperand() * ( scalar / mat.rightOperand() );
613 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
631 template< typename MT // Type of the dense matrix of the left-hand side expression
632  , typename ST1 // Type of the scalar of the left-hand side expression
633  , bool SO // Storage order of the dense matrix
634  , typename ST2 > // Type of the right-hand side scalar
635 inline const typename EnableIf< IsNumeric<ST2>
636  , typename DMatScalarDivExprHelper<MT,typename MultTrait<ST1,ST2>::Type,SO>::Type >::Type
637  operator/( const DMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
638 {
639  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
640 
641  typedef typename MultTrait<ST1,ST2>::Type MultType;
642  typedef DMatScalarDivExprHelper<MT,MultType,SO> Helper;
643 
644  if( Helper::value ) {
645  return typename Helper::Type( mat.leftOperand(), MultType(1)/( mat.rightOperand() * scalar ) );
646  }
647  else {
648  return typename Helper::Type( mat.leftOperand(), mat.rightOperand() * scalar );
649  }
650 }
652 //*************************************************************************************************
653 
654 
655 
656 
657 //=================================================================================================
658 //
659 // DMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
660 //
661 //=================================================================================================
662 
663 //*************************************************************************************************
665 template< typename MT, typename ST1, typename ST2 >
666 struct DMatScalarMultExprTrait< DMatScalarDivExpr<MT,ST1,false>, ST2 >
667 {
668  private:
669  //**********************************************************************************************
670  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
671  //**********************************************************************************************
672 
673  //**********************************************************************************************
674  typedef typename DMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
675  typedef DMatScalarMultExpr< DMatScalarDivExpr<MT,ST1,false>, ST2, false > T2;
676  //**********************************************************************************************
677 
678  public:
679  //**********************************************************************************************
680  typedef typename SelectType< IsDenseMatrix<MT>::value && IsRowMajorMatrix<MT>::value &&
681  IsNumeric<ST1>::value && IsNumeric<ST2>::value
682  , typename SelectType<condition,T1,T2>::Type
683  , INVALID_TYPE >::Type Type;
684  //**********************************************************************************************
685 };
687 //*************************************************************************************************
688 
689 
690 
691 
692 //=================================================================================================
693 //
694 // TDMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
695 //
696 //=================================================================================================
697 
698 //*************************************************************************************************
700 template< typename MT, typename ST1, typename ST2 >
701 struct TDMatScalarMultExprTrait< DMatScalarDivExpr<MT,ST1,true>, ST2 >
702 {
703  private:
704  //**********************************************************************************************
705  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
706  //**********************************************************************************************
707 
708  //**********************************************************************************************
709  typedef typename DMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
710  typedef DMatScalarMultExpr< DMatScalarDivExpr<MT,ST1,true>, ST2, true > T2;
711  //**********************************************************************************************
712 
713  public:
714  //**********************************************************************************************
715  typedef typename SelectType< IsDenseMatrix<MT>::value && IsColumnMajorMatrix<MT>::value &&
716  IsNumeric<ST1>::value && IsNumeric<ST2>::value
717  , typename SelectType<condition,T1,T2>::Type
718  , INVALID_TYPE >::Type Type;
719  //**********************************************************************************************
720 };
722 //*************************************************************************************************
723 
724 } // namespace blaze
725 
726 #endif