SparseCwiseBinaryOp.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
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
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, typename CwiseBinaryOpImpl::Index outer)
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : Base(binOp.derived(),outer)
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of inner-iterators
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// template<typename T> struct internal::func_is_conjunction { enum { ret = false }; };
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// template<typename T> struct internal::func_is_conjunction<internal::scalar_product_op<T> > { enum { ret = true }; };
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// TODO generalize the internal::scalar_product_op specialization to all conjunctions if any !
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - sparse  (generic)
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename BinaryOp, typename Lhs, typename Rhs, typename Derived>
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::Scalar Scalar;
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _LhsNested::InnerIterator LhsIterator;
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _RhsNested::InnerIterator RhsIterator;
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      this->operator++();
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = m_lhsIter.index();
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_lhsIter;
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_rhsIter;
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = m_lhsIter.index();
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = m_functor(m_lhsIter.value(), Scalar(0));
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_lhsIter;
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = m_rhsIter.index();
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = m_functor(Scalar(0), m_rhsIter.value());
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ++m_rhsIter;
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_value = 0; // this is to avoid a compilation warning
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        m_id = -1;
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_id; }
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; }
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsIterator m_lhsIter;
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsIterator m_rhsIter;
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryOp& m_functor;
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar m_value;
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index m_id;
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - sparse  (product)
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename Lhs, typename Rhs, typename Derived>
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef scalar_product_op<T> BinaryFunc;
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryXpr::Scalar Scalar;
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _LhsNested::InnerIterator LhsIterator;
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _RhsNested::InnerIterator RhsIterator;
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (m_lhsIter.index() < m_rhsIter.index())
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_lhsIter;
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_rhsIter;
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_lhsIter;
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_rhsIter;
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (m_lhsIter.index() < m_rhsIter.index())
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_lhsIter;
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        else
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          ++m_rhsIter;
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); }
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsIterator m_lhsIter;
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsIterator m_rhsIter;
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryFunc& m_functor;
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - dense  (product)
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename Lhs, typename Rhs, typename Derived>
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef scalar_product_op<T> BinaryFunc;
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryXpr::Scalar Scalar;
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::RhsNested RhsNested;
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _LhsNested::InnerIterator LhsIterator;
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit };
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer)
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_lhsIter;
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_functor(m_lhsIter.value(),
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; }
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsNested m_rhs;
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsIterator m_lhsIter;
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryFunc m_functor;
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index m_outer;
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// sparse - dense  (product)
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename Lhs, typename Rhs, typename Derived>
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef scalar_product_op<T> BinaryFunc;
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryXpr::Scalar Scalar;
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename _RhsNested::InnerIterator RhsIterator;
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit };
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Derived& operator++()
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ++m_rhsIter;
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return *static_cast<Derived*>(this);
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Scalar value() const
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index index() const { return m_rhsIter.index(); }
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); }
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); }
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; }
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const CwiseBinaryXpr& m_xpr;
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsIterator m_rhsIter;
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const BinaryFunc& m_functor;
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index m_outer;
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of SparseMatrixBase and SparseCwise functions/operators
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived &
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other)
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return *this = derived() - other.derived();
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived &
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other)
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return *this = derived() + other.derived();
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) const
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived());
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSE_CWISE_BINARY_OP_H
325