1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H 11 #define EIGEN_SPARSE_CWISE_UNARY_OP_H 12 13 namespace Eigen { 14 15 namespace internal { 16 17 template<typename UnaryOp, typename ArgType> 18 struct unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased> 19 : public evaluator_base<CwiseUnaryOp<UnaryOp,ArgType> > 20 { 21 public: 22 typedef CwiseUnaryOp<UnaryOp, ArgType> XprType; 23 24 class InnerIterator; 25 26 enum { 27 CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost, 28 Flags = XprType::Flags 29 }; 30 31 explicit unary_evaluator(const XprType& op) : m_functor(op.functor()), m_argImpl(op.nestedExpression()) 32 { 33 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost); 34 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 35 } 36 37 inline Index nonZerosEstimate() const { 38 return m_argImpl.nonZerosEstimate(); 39 } 40 41 protected: 42 typedef typename evaluator<ArgType>::InnerIterator EvalIterator; 43 44 const UnaryOp m_functor; 45 evaluator<ArgType> m_argImpl; 46 }; 47 48 template<typename UnaryOp, typename ArgType> 49 class unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::InnerIterator 50 : public unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalIterator 51 { 52 typedef typename XprType::Scalar Scalar; 53 typedef typename unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalIterator Base; 54 public: 55 56 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& unaryOp, Index outer) 57 : Base(unaryOp.m_argImpl,outer), m_functor(unaryOp.m_functor) 58 {} 59 60 EIGEN_STRONG_INLINE InnerIterator& operator++() 61 { Base::operator++(); return *this; } 62 63 EIGEN_STRONG_INLINE Scalar value() const { return m_functor(Base::value()); } 64 65 protected: 66 const UnaryOp m_functor; 67 private: 68 Scalar& valueRef(); 69 }; 70 71 template<typename ViewOp, typename ArgType> 72 struct unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased> 73 : public evaluator_base<CwiseUnaryView<ViewOp,ArgType> > 74 { 75 public: 76 typedef CwiseUnaryView<ViewOp, ArgType> XprType; 77 78 class InnerIterator; 79 80 enum { 81 CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<ViewOp>::Cost, 82 Flags = XprType::Flags 83 }; 84 85 explicit unary_evaluator(const XprType& op) : m_functor(op.functor()), m_argImpl(op.nestedExpression()) 86 { 87 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<ViewOp>::Cost); 88 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 89 } 90 91 protected: 92 typedef typename evaluator<ArgType>::InnerIterator EvalIterator; 93 94 const ViewOp m_functor; 95 evaluator<ArgType> m_argImpl; 96 }; 97 98 template<typename ViewOp, typename ArgType> 99 class unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::InnerIterator 100 : public unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::EvalIterator 101 { 102 typedef typename XprType::Scalar Scalar; 103 typedef typename unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::EvalIterator Base; 104 public: 105 106 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& unaryOp, Index outer) 107 : Base(unaryOp.m_argImpl,outer), m_functor(unaryOp.m_functor) 108 {} 109 110 EIGEN_STRONG_INLINE InnerIterator& operator++() 111 { Base::operator++(); return *this; } 112 113 EIGEN_STRONG_INLINE Scalar value() const { return m_functor(Base::value()); } 114 EIGEN_STRONG_INLINE Scalar& valueRef() { return m_functor(Base::valueRef()); } 115 116 protected: 117 const ViewOp m_functor; 118 }; 119 120 } // end namespace internal 121 122 template<typename Derived> 123 EIGEN_STRONG_INLINE Derived& 124 SparseMatrixBase<Derived>::operator*=(const Scalar& other) 125 { 126 typedef typename internal::evaluator<Derived>::InnerIterator EvalIterator; 127 internal::evaluator<Derived> thisEval(derived()); 128 for (Index j=0; j<outerSize(); ++j) 129 for (EvalIterator i(thisEval,j); i; ++i) 130 i.valueRef() *= other; 131 return derived(); 132 } 133 134 template<typename Derived> 135 EIGEN_STRONG_INLINE Derived& 136 SparseMatrixBase<Derived>::operator/=(const Scalar& other) 137 { 138 typedef typename internal::evaluator<Derived>::InnerIterator EvalIterator; 139 internal::evaluator<Derived> thisEval(derived()); 140 for (Index j=0; j<outerSize(); ++j) 141 for (EvalIterator i(thisEval,j); i; ++i) 142 i.valueRef() /= other; 143 return derived(); 144 } 145 146 } // end namespace Eigen 147 148 #endif // EIGEN_SPARSE_CWISE_UNARY_OP_H 149