1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SPARSE_CWISE_BINARY_OP_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Here we have to handle 3 cases:
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  1 - sparse op dense
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  2 - dense op sparse
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  3 - sparse op sparse
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// We also need to implement a 4th iterator for:
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  4 - dense op dense
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Finally, we also need to distinguish between the product and other operations :
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                configuration      returned mode
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  1 - sparse op dense    product      sparse
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                         generic      dense
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  2 - dense op sparse    product      sparse
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                         generic      dense
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  3 - sparse op sparse   product      sparse
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                         generic      sparse
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  4 - dense op dense     product      dense
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                         generic      dense
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct promote_storage_type<Dense,Sparse>
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ typedef Sparse ret; };
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct promote_storage_type<Sparse,Dense>
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ typedef Sparse ret; };
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename BinaryOp, typename Lhs, typename Rhs, typename Derived,
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename _LhsStorageMode = typename traits<Lhs>::StorageKind,
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typename _RhsStorageMode = typename traits<Rhs>::StorageKind>
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector;
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename BinaryOp, typename Lhs, typename Rhs>
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    class InnerIterator;
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    class ReverseInnerIterator;
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CwiseBinaryOpImpl()
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind;
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind;
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_STATIC_ASSERT((
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                (!internal::is_same<LhsStorageKind,RhsStorageKind>::value)
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            ||  ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))),
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename BinaryOp, typename Lhs, typename Rhs>
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator>
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      BinaryOp,Lhs,Rhs, InnerIterator> Base;
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // NOTE: we have to prefix Index by "typename Lhs::" to avoid an ICE with VC11
777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename Lhs::Index outer)
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : Base(binOp.derived(),outer)
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of inner-iterators
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// template<typename T> struct internal::func_is_conjunction { enum { ret = false }; };
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// template<typename T> struct internal::func_is_conjunction<internal::scalar_product_op<T> > { enum { ret = true }; };
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// TODO generalize the internal::scalar_product_op specialization to all conjunctions if any !
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - sparse  (generic)
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename BinaryOp, typename Lhs, typename Rhs, typename Derived>
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::Scalar Scalar;
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _LhsNested::InnerIterator LhsIterator;
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _RhsNested::InnerIterator RhsIterator;
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      this->operator++();
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = m_lhsIter.index();
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_lhsIter;
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_rhsIter;
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = m_lhsIter.index();
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = m_functor(m_lhsIter.value(), Scalar(0));
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_lhsIter;
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = m_rhsIter.index();
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = m_functor(Scalar(0), m_rhsIter.value());
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_rhsIter;
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = 0; // this is to avoid a compilation warning
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = -1;
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_id; }
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; }
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsIterator m_lhsIter;
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsIterator m_rhsIter;
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryOp& m_functor;
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar m_value;
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index m_id;
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - sparse  (product)
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename Lhs, typename Rhs, typename Derived>
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef scalar_product_op<T> BinaryFunc;
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryXpr::Scalar Scalar;
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _LhsNested::InnerIterator LhsIterator;
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _RhsNested::InnerIterator RhsIterator;
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (m_lhsIter.index() < m_rhsIter.index())
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_lhsIter;
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_rhsIter;
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_lhsIter;
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_rhsIter;
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (m_lhsIter.index() < m_rhsIter.index())
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_lhsIter;
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_rhsIter;
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); }
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsIterator m_lhsIter;
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsIterator m_rhsIter;
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryFunc& m_functor;
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - dense  (product)
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename Lhs, typename Rhs, typename Derived>
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef scalar_product_op<T> BinaryFunc;
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryXpr::Scalar Scalar;
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::RhsNested RhsNested;
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _LhsNested::InnerIterator LhsIterator;
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit };
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer)
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_lhsIter;
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_functor(m_lhsIter.value(),
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; }
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsNested m_rhs;
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsIterator m_lhsIter;
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryFunc m_functor;
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index m_outer;
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - dense  (product)
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename Lhs, typename Rhs, typename Derived>
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef scalar_product_op<T> BinaryFunc;
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryXpr::Scalar Scalar;
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _RhsNested::InnerIterator RhsIterator;
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit };
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_rhsIter;
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_rhsIter.index(); }
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); }
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); }
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; }
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const CwiseBinaryXpr& m_xpr;
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsIterator m_rhsIter;
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryFunc& m_functor;
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index m_outer;
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of SparseMatrixBase and SparseCwise functions/operators
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived &
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other)
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
3047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return derived() = derived() - other.derived();
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived &
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other)
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
3127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return derived() = derived() + other.derived();
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) const
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived());
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSE_CWISE_BINARY_OP_H
326