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 
50 #include <blaze/util/Assert.h>
55 #include <blaze/util/EnableIf.h>
56 #include <blaze/util/InvalidType.h>
58 #include <blaze/util/SelectType.h>
59 #include <blaze/util/Types.h>
62 
63 
64 namespace blaze {
65 
66 //=================================================================================================
67 //
68 // CLASS DMATSCALARDIVEXPR
69 //
70 //=================================================================================================
71 
72 //*************************************************************************************************
79 template< typename MT // Type of the left-hand side dense matrix
80  , typename ST // Type of the right-hand side scalar value
81  , bool SO > // Storage order
82 class DMatScalarDivExpr : public DenseMatrix< DMatScalarDivExpr<MT,ST,SO>, SO >
83  , private MatScalarDivExpr
84  , private Computation
85 {
86  private:
87  //**Type definitions****************************************************************************
88  typedef typename MT::ResultType RT;
89  typedef typename MT::ReturnType RN;
90  typedef typename MT::CompositeType CT;
91  //**********************************************************************************************
92 
93  //**Return type evaluation**********************************************************************
95 
100  enum { returnExpr = !IsTemporary<RN>::value };
101 
104  //**********************************************************************************************
105 
106  //**Evaluation strategy*************************************************************************
108 
114  enum { useAssign = RequiresEvaluation<MT>::value };
115 
117 
118  template< typename MT2 >
119  struct UseAssign {
120  enum { value = useAssign };
121  };
123  //**********************************************************************************************
124 
125  public:
126  //**Type definitions****************************************************************************
129  typedef typename ResultType::OppositeType OppositeType;
130  typedef typename ResultType::TransposeType TransposeType;
131  typedef typename ResultType::ElementType ElementType;
132 
135 
138 
140  typedef typename SelectType< IsExpression<MT>::value, const MT, const MT& >::Type LeftOperand;
141 
143  typedef ST RightOperand;
144  //**********************************************************************************************
145 
146  //**Compilation flags***************************************************************************
148  enum { vectorizable = 0 };
149  //**********************************************************************************************
150 
151  //**Constructor*********************************************************************************
157  explicit inline DMatScalarDivExpr( const MT& matrix, ST scalar )
158  : matrix_( matrix ) // Left-hand side dense matrix of the division expression
159  , scalar_( scalar ) // Right-hand side scalar of the division expression
160  {}
161  //**********************************************************************************************
162 
163  //**Access operator*****************************************************************************
170  inline ReturnType operator()( size_t i, size_t j ) const {
171  BLAZE_INTERNAL_ASSERT( i < matrix_.rows() , "Invalid row access index" );
172  BLAZE_INTERNAL_ASSERT( j < matrix_.columns(), "Invalid column access index" );
173  return matrix_(i,j) / scalar_;
174  }
175  //**********************************************************************************************
176 
177  //**Rows function*******************************************************************************
182  inline size_t rows() const {
183  return matrix_.rows();
184  }
185  //**********************************************************************************************
186 
187  //**Columns function****************************************************************************
192  inline size_t columns() const {
193  return matrix_.columns();
194  }
195  //**********************************************************************************************
196 
197  //**Left operand access*************************************************************************
202  inline LeftOperand leftOperand() const {
203  return matrix_;
204  }
205  //**********************************************************************************************
206 
207  //**Right operand access************************************************************************
212  inline RightOperand rightOperand() const {
213  return scalar_;
214  }
215  //**********************************************************************************************
216 
217  //**********************************************************************************************
223  template< typename T >
224  inline bool canAlias( const T* alias ) const {
225  return matrix_.canAlias( alias );
226  }
227  //**********************************************************************************************
228 
229  //**********************************************************************************************
235  template< typename T >
236  inline bool isAliased( const T* alias ) const {
237  return matrix_.isAliased( alias );
238  }
239  //**********************************************************************************************
240 
241  private:
242  //**Member variables****************************************************************************
245  //**********************************************************************************************
246 
247  //**Assignment to row-major dense matrices******************************************************
261  template< typename MT2 > // Type of the target dense matrix
262  friend inline typename EnableIf< UseAssign<MT2> >::Type
264  {
266 
267  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
268  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
269 
270  assign( ~lhs, rhs.matrix_ );
271  (~lhs) /= rhs.scalar_;
272  }
274  //**********************************************************************************************
275 
276  //**Assignment to column-major dense matrices***************************************************
290  template< typename MT2 > // Type of the target dense matrix
291  friend inline typename EnableIf< UseAssign<MT2> >::Type
293  {
295 
296  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
297  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
298 
299  assign( ~lhs, rhs.matrix_ );
300  (~lhs) /= rhs.scalar_;
301  }
303  //**********************************************************************************************
304 
305  //**Assignment to row-major sparse matrices*****************************************************
319  template< typename MT2 > // Type of the target sparse matrix
320  friend inline typename EnableIf< UseAssign<MT2> >::Type
321  assign( SparseMatrix<MT2,false>& lhs, const DMatScalarDivExpr& rhs )
322  {
324 
325  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
326  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
327 
328  assign( ~lhs, rhs.matrix_ );
329 
330  for( size_t i=0UL; i<(~lhs).rows(); ++i )
331  {
332  typename MT2::Iterator element( (~lhs).begin(i) );
333  const typename MT2::Iterator end( (~lhs).end(i) );
334 
335  for( ; element!=end; ++element )
336  element->value() /= rhs.scalar_;
337  }
338  }
340  //**********************************************************************************************
341 
342  //**Assignment to column-major sparse matrices**************************************************
356  template< typename MT2 > // Type of the target sparse matrix
357  friend inline typename EnableIf< UseAssign<MT2> >::Type
358  assign( SparseMatrix<MT2,true>& lhs, const DMatScalarDivExpr& rhs )
359  {
361 
362  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
363  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
364 
365  assign( ~lhs, rhs.matrix_ );
366 
367  for( size_t j=0UL; j<(~lhs).columns(); ++j )
368  {
369  typename MT2::Iterator element( (~lhs).begin(j) );
370  const typename MT2::Iterator end( (~lhs).end(j) );
371 
372  for( ; element!=end; ++element )
373  element->value() /= rhs.scalar_;
374  }
375  }
377  //**********************************************************************************************
378 
379  //**Addition assignment to dense matrices*******************************************************
393  template< typename MT2 // Type of the target dense matrix
394  , bool SO2 > // Storage order of the target dense matrix
395  friend inline typename EnableIf< UseAssign<MT2> >::Type
396  addAssign( DenseMatrix<MT2,SO2>& lhs, const DMatScalarDivExpr& rhs )
397  {
399 
402  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
403 
404  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
405  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
406 
407  const ResultType tmp( rhs );
408  addAssign( ~lhs, tmp );
409  }
411  //**********************************************************************************************
412 
413  //**Addition assignment to sparse matrices******************************************************
414  // No special implementation for the addition assignment to sparse matrices.
415  //**********************************************************************************************
416 
417  //**Subtraction assignment to dense matrices****************************************************
431  template< typename MT2 // Type of the target dense matrix
432  , bool SO2 > // Storage order of the target dense matrix
433  friend inline typename EnableIf< UseAssign<MT2> >::Type
434  subAssign( DenseMatrix<MT2,SO2>& lhs, const DMatScalarDivExpr& rhs )
435  {
437 
440  BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE( typename ResultType::CompositeType );
441 
442  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
443  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
444 
445  const ResultType tmp( rhs );
446  subAssign( ~lhs, tmp );
447  }
449  //**********************************************************************************************
450 
451  //**Subtraction assignment to sparse matrices***************************************************
452  // No special implementation for the subtraction assignment to sparse matrices.
453  //**********************************************************************************************
454 
455  //**Multiplication assignment to dense matrices*************************************************
456  // No special implementation for the multiplication assignment to dense matrices.
457  //**********************************************************************************************
458 
459  //**Multiplication assignment to sparse matrices************************************************
460  // No special implementation for the multiplication assignment to sparse matrices.
461  //**********************************************************************************************
462 
463  //**Compile time checks*************************************************************************
472  //**********************************************************************************************
473 };
474 //*************************************************************************************************
475 
476 
477 
478 
479 //=================================================================================================
480 //
481 // GLOBAL BINARY ARITHMETIC OPERATORS
482 //
483 //=================================================================================================
484 
485 //*************************************************************************************************
507 template< typename T1 // Type of the left-hand side dense matrix
508  , bool SO // Storage order of the left-hand side dense matrix
509  , typename T2 > // Type of the right-hand side scalar
510 inline const typename EnableIf< IsNumeric<T2>, typename DivExprTrait<T1,T2>::Type >::Type
511  operator/( const DenseMatrix<T1,SO>& mat, T2 scalar )
512 {
514 
515  BLAZE_USER_ASSERT( scalar != T2(0), "Division by zero detected" );
516 
517  typedef typename DivExprTrait<T1,T2>::Type ReturnType;
518  typedef typename ReturnType::RightOperand ScalarType;
519 
521  return ReturnType( ~mat, ScalarType(1)/ScalarType(scalar) );
522  }
523  else {
524  return ReturnType( ~mat, scalar );
525  }
526 }
527 //*************************************************************************************************
528 
529 
530 
531 
532 //=================================================================================================
533 //
534 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
535 //
536 //=================================================================================================
537 
538 //*************************************************************************************************
551 template< typename MT // Type of the dense matrix of the left-hand side expression
552  , typename ST1 // Type of the scalar of the left-hand side expression
553  , bool SO // Storage order of the dense matrix
554  , typename ST2 > // Type of the right-hand side scalar
555 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST2,ST1>::Type >
556  , typename MultExprTrait< DMatScalarDivExpr<MT,ST1,SO>, ST2 >::Type >::Type
557  operator*( const DMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
558 {
560 
561  return mat.leftOperand() * ( scalar / mat.rightOperand() );
562 }
564 //*************************************************************************************************
565 
566 
567 //*************************************************************************************************
580 template< typename ST1 // Type of the left-hand side scalar
581  , typename MT // Type of the dense matrix of the right-hand side expression
582  , typename ST2 // Type of the scalar of the right-hand side expression
583  , bool SO > // Storage order of the dense matrix
584 inline const typename EnableIf< IsFloatingPoint< typename DivTrait<ST1,ST2>::Type >
585  , typename MultExprTrait< ST1, DMatScalarDivExpr<MT,ST2,SO> >::Type >::Type
586  operator*( ST1 scalar, const DMatScalarDivExpr<MT,ST2,SO>& mat )
587 {
589 
590  return mat.leftOperand() * ( scalar / mat.rightOperand() );
591 }
593 //*************************************************************************************************
594 
595 
596 //*************************************************************************************************
609 template< typename MT // Type of the dense matrix of the left-hand side expression
610  , typename ST1 // Type of the scalar of the left-hand side expression
611  , bool SO // Storage order of the dense matrix
612  , typename ST2 > // Type of the right-hand side scalar
613 inline const typename EnableIf< IsNumeric<ST2>
614  , typename DivExprTrait<MT,typename MultTrait<ST1,ST2>::Type>::Type >::Type
615  operator/( const DMatScalarDivExpr<MT,ST1,SO>& mat, ST2 scalar )
616 {
618 
619  BLAZE_USER_ASSERT( scalar != ST2(0), "Division by zero detected" );
620 
621  typedef typename MultTrait<ST1,ST2>::Type MultType;
622  typedef typename DivExprTrait<MT,MultType>::Type ReturnType;
623  typedef typename ReturnType::RightOperand ScalarType;
624 
625  if( IsMultExpr<ReturnType>::value ) {
626  return ReturnType( mat.leftOperand(), ScalarType(1)/( mat.rightOperand() * scalar ) );
627  }
628  else {
629  return ReturnType( mat.leftOperand(), mat.rightOperand() * scalar );
630  }
631 }
633 //*************************************************************************************************
634 
635 
636 
637 
638 //=================================================================================================
639 //
640 // DMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
641 //
642 //=================================================================================================
643 
644 //*************************************************************************************************
646 template< typename MT, typename ST1, typename ST2 >
647 struct DMatScalarMultExprTrait< DMatScalarDivExpr<MT,ST1,false>, ST2 >
648 {
649  private:
650  //**********************************************************************************************
651  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
652  //**********************************************************************************************
653 
654  //**********************************************************************************************
655  typedef typename DMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
656  typedef DMatScalarMultExpr< DMatScalarDivExpr<MT,ST1,false>, ST2, false > T2;
657  //**********************************************************************************************
658 
659  public:
660  //**********************************************************************************************
661  typedef typename SelectType< IsDenseMatrix<MT>::value && IsRowMajorMatrix<MT>::value &&
662  IsNumeric<ST1>::value && IsNumeric<ST2>::value
663  , typename SelectType<condition,T1,T2>::Type
664  , INVALID_TYPE >::Type Type;
665  //**********************************************************************************************
666 };
668 //*************************************************************************************************
669 
670 
671 
672 
673 //=================================================================================================
674 //
675 // TDMATSCALARMULTEXPRTRAIT SPECIALIZATIONS
676 //
677 //=================================================================================================
678 
679 //*************************************************************************************************
681 template< typename MT, typename ST1, typename ST2 >
682 struct TDMatScalarMultExprTrait< DMatScalarDivExpr<MT,ST1,true>, ST2 >
683 {
684  private:
685  //**********************************************************************************************
686  enum { condition = IsFloatingPoint<typename DivTrait<ST1,ST2>::Type>::value };
687  //**********************************************************************************************
688 
689  //**********************************************************************************************
690  typedef typename DMatScalarMultExprTrait<MT,typename DivTrait<ST1,ST2>::Type>::Type T1;
691  typedef DMatScalarMultExpr< DMatScalarDivExpr<MT,ST1,true>, ST2, true > T2;
692  //**********************************************************************************************
693 
694  public:
695  //**********************************************************************************************
696  typedef typename SelectType< IsDenseMatrix<MT>::value && IsColumnMajorMatrix<MT>::value &&
697  IsNumeric<ST1>::value && IsNumeric<ST2>::value
698  , typename SelectType<condition,T1,T2>::Type
699  , INVALID_TYPE >::Type Type;
700  //**********************************************************************************************
701 };
703 //*************************************************************************************************
704 
705 
706 
707 
708 //=================================================================================================
709 //
710 // ROWEXPRTRAIT SPECIALIZATIONS
711 //
712 //=================================================================================================
713 
714 //*************************************************************************************************
716 template< typename MT, typename ST, bool SO >
717 struct RowExprTrait< DMatScalarDivExpr<MT,ST,SO> >
718 {
719  public:
720  //**********************************************************************************************
721  typedef typename DivExprTrait< typename RowExprTrait<const MT>::Type, ST >::Type Type;
722  //**********************************************************************************************
723 };
725 //*************************************************************************************************
726 
727 
728 
729 
730 //=================================================================================================
731 //
732 // COLUMNEXPRTRAIT SPECIALIZATIONS
733 //
734 //=================================================================================================
735 
736 //*************************************************************************************************
738 template< typename MT, typename ST, bool SO >
739 struct ColumnExprTrait< DMatScalarDivExpr<MT,ST,SO> >
740 {
741  public:
742  //**********************************************************************************************
743  typedef typename DivExprTrait< typename ColumnExprTrait<const MT>::Type, ST >::Type Type;
744  //**********************************************************************************************
745 };
747 //*************************************************************************************************
748 
749 } // namespace blaze
750 
751 #endif