1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008-2015 Gael Guennebaud <[email protected]> 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 = int(evaluator<ArgType>::CoeffReadCost) + int(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 protected: 53 typedef typename XprType::Scalar Scalar; 54 typedef typename unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalIterator Base; 55 public: 56 57 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& unaryOp, Index outer) 58 : Base(unaryOp.m_argImpl,outer), m_functor(unaryOp.m_functor) 59 {} 60 61 EIGEN_STRONG_INLINE InnerIterator& operator++() 62 { Base::operator++(); return *this; } 63 64 EIGEN_STRONG_INLINE Scalar value() const { return m_functor(Base::value()); } 65 66 protected: 67 const UnaryOp m_functor; 68 private: 69 Scalar& valueRef(); 70 }; 71 72 template<typename ViewOp, typename ArgType> 73 struct unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased> 74 : public evaluator_base<CwiseUnaryView<ViewOp,ArgType> > 75 { 76 public: 77 typedef CwiseUnaryView<ViewOp, ArgType> XprType; 78 79 class InnerIterator; 80 81 enum { 82 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<ViewOp>::Cost), 83 Flags = XprType::Flags 84 }; 85 86 explicit unary_evaluator(const XprType& op) : m_functor(op.functor()), m_argImpl(op.nestedExpression()) 87 { 88 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<ViewOp>::Cost); 89 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 90 } 91 92 protected: 93 typedef typename evaluator<ArgType>::InnerIterator EvalIterator; 94 95 const ViewOp m_functor; 96 evaluator<ArgType> m_argImpl; 97 }; 98 99 template<typename ViewOp, typename ArgType> 100 class unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::InnerIterator 101 : public unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::EvalIterator 102 { 103 protected: 104 typedef typename XprType::Scalar Scalar; 105 typedef typename unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::EvalIterator Base; 106 public: 107 108 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& unaryOp, Index outer) 109 : Base(unaryOp.m_argImpl,outer), m_functor(unaryOp.m_functor) 110 {} 111 112 EIGEN_STRONG_INLINE InnerIterator& operator++() 113 { Base::operator++(); return *this; } 114 115 EIGEN_STRONG_INLINE Scalar value() const { return m_functor(Base::value()); } 116 EIGEN_STRONG_INLINE Scalar& valueRef() { return m_functor(Base::valueRef()); } 117 118 protected: 119 const ViewOp m_functor; 120 }; 121 122 } // end namespace internal 123 124 template<typename Derived> 125 EIGEN_STRONG_INLINE Derived& 126 SparseMatrixBase<Derived>::operator*=(const Scalar& other) 127 { 128 typedef typename internal::evaluator<Derived>::InnerIterator EvalIterator; 129 internal::evaluator<Derived> thisEval(derived()); 130 for (Index j=0; j<outerSize(); ++j) 131 for (EvalIterator i(thisEval,j); i; ++i) 132 i.valueRef() *= other; 133 return derived(); 134 } 135 136 template<typename Derived> 137 EIGEN_STRONG_INLINE Derived& 138 SparseMatrixBase<Derived>::operator/=(const Scalar& other) 139 { 140 typedef typename internal::evaluator<Derived>::InnerIterator EvalIterator; 141 internal::evaluator<Derived> thisEval(derived()); 142 for (Index j=0; j<outerSize(); ++j) 143 for (EvalIterator i(thisEval,j); i; ++i) 144 i.valueRef() /= other; 145 return derived(); 146 } 147 148 } // end namespace Eigen 149 150 #endif // EIGEN_SPARSE_CWISE_UNARY_OP_H 151