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   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 = evaluator<ArgType>::CoeffReadCost + 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