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