10 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
11 #define EIGEN_SPARSE_CWISE_BINARY_OP_H
34 template<>
struct promote_storage_type<Dense,Sparse>
35 {
typedef Sparse ret; };
37 template<>
struct promote_storage_type<Sparse,Dense>
38 {
typedef Sparse ret; };
40 template<
typename BinaryOp,
typename Lhs,
typename Rhs,
typename Derived,
41 typename _LhsStorageMode =
typename traits<Lhs>::StorageKind,
42 typename _RhsStorageMode =
typename traits<Rhs>::StorageKind>
43 class sparse_cwise_binary_op_inner_iterator_selector;
47 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
48 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
49 :
public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
53 class ReverseInnerIterator;
54 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
55 EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
58 typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind;
59 typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind;
61 (!internal::is_same<LhsStorageKind,RhsStorageKind>::value)
62 || ((Lhs::Flags&
RowMajorBit) == (Rhs::Flags&RowMajorBit))),
63 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
67 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
68 class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
69 :
public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator>
72 typedef typename Lhs::Index Index;
73 typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
74 BinaryOp,Lhs,Rhs, InnerIterator> Base;
77 EIGEN_STRONG_INLINE InnerIterator(
const CwiseBinaryOpImpl& binOp,
typename Lhs::Index outer)
78 : Base(binOp.derived(),outer)
94 template<
typename BinaryOp,
typename Lhs,
typename Rhs,
typename Derived>
95 class sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
97 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
98 typedef typename traits<CwiseBinaryXpr>::Scalar Scalar;
99 typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
100 typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
101 typedef typename _LhsNested::InnerIterator LhsIterator;
102 typedef typename _RhsNested::InnerIterator RhsIterator;
103 typedef typename Lhs::Index Index;
107 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
108 : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
113 EIGEN_STRONG_INLINE Derived& operator++()
115 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
117 m_id = m_lhsIter.index();
118 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
122 else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
124 m_id = m_lhsIter.index();
125 m_value = m_functor(m_lhsIter.value(), Scalar(0));
128 else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
130 m_id = m_rhsIter.index();
131 m_value = m_functor(Scalar(0), m_rhsIter.value());
139 return *
static_cast<Derived*
>(
this);
142 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
144 EIGEN_STRONG_INLINE Index index()
const {
return m_id; }
145 EIGEN_STRONG_INLINE Index row()
const {
return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
146 EIGEN_STRONG_INLINE Index col()
const {
return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
148 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id>=0; }
151 LhsIterator m_lhsIter;
152 RhsIterator m_rhsIter;
153 const BinaryOp& m_functor;
159 template<
typename T,
typename Lhs,
typename Rhs,
typename Derived>
160 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
162 typedef scalar_product_op<T> BinaryFunc;
163 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
164 typedef typename CwiseBinaryXpr::Scalar Scalar;
165 typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
166 typedef typename _LhsNested::InnerIterator LhsIterator;
167 typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
168 typedef typename _RhsNested::InnerIterator RhsIterator;
169 typedef typename Lhs::Index Index;
172 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
173 : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
175 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
177 if (m_lhsIter.index() < m_rhsIter.index())
184 EIGEN_STRONG_INLINE Derived& operator++()
188 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
190 if (m_lhsIter.index() < m_rhsIter.index())
195 return *
static_cast<Derived*
>(
this);
198 EIGEN_STRONG_INLINE Scalar value()
const {
return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
200 EIGEN_STRONG_INLINE Index index()
const {
return m_lhsIter.index(); }
201 EIGEN_STRONG_INLINE Index row()
const {
return m_lhsIter.row(); }
202 EIGEN_STRONG_INLINE Index col()
const {
return m_lhsIter.col(); }
204 EIGEN_STRONG_INLINE
operator bool()
const {
return (m_lhsIter && m_rhsIter); }
207 LhsIterator m_lhsIter;
208 RhsIterator m_rhsIter;
209 const BinaryFunc& m_functor;
213 template<
typename T,
typename Lhs,
typename Rhs,
typename Derived>
214 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
216 typedef scalar_product_op<T> BinaryFunc;
217 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
218 typedef typename CwiseBinaryXpr::Scalar Scalar;
219 typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
220 typedef typename traits<CwiseBinaryXpr>::RhsNested RhsNested;
221 typedef typename _LhsNested::InnerIterator LhsIterator;
222 typedef typename Lhs::Index Index;
226 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
227 : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer)
230 EIGEN_STRONG_INLINE Derived& operator++()
233 return *
static_cast<Derived*
>(
this);
236 EIGEN_STRONG_INLINE Scalar value()
const
237 {
return m_functor(m_lhsIter.value(),
238 m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
240 EIGEN_STRONG_INLINE Index index()
const {
return m_lhsIter.index(); }
241 EIGEN_STRONG_INLINE Index row()
const {
return m_lhsIter.row(); }
242 EIGEN_STRONG_INLINE Index col()
const {
return m_lhsIter.col(); }
244 EIGEN_STRONG_INLINE
operator bool()
const {
return m_lhsIter; }
248 LhsIterator m_lhsIter;
249 const BinaryFunc m_functor;
254 template<
typename T,
typename Lhs,
typename Rhs,
typename Derived>
255 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
257 typedef scalar_product_op<T> BinaryFunc;
258 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
259 typedef typename CwiseBinaryXpr::Scalar Scalar;
260 typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
261 typedef typename _RhsNested::InnerIterator RhsIterator;
262 typedef typename Lhs::Index Index;
267 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
268 : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
271 EIGEN_STRONG_INLINE Derived& operator++()
274 return *
static_cast<Derived*
>(
this);
277 EIGEN_STRONG_INLINE Scalar value()
const
278 {
return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
280 EIGEN_STRONG_INLINE Index index()
const {
return m_rhsIter.index(); }
281 EIGEN_STRONG_INLINE Index row()
const {
return m_rhsIter.row(); }
282 EIGEN_STRONG_INLINE Index col()
const {
return m_rhsIter.col(); }
284 EIGEN_STRONG_INLINE
operator bool()
const {
return m_rhsIter; }
287 const CwiseBinaryXpr& m_xpr;
288 RhsIterator m_rhsIter;
289 const BinaryFunc& m_functor;
299 template<
typename Derived>
300 template<
typename OtherDerived>
301 EIGEN_STRONG_INLINE Derived &
302 SparseMatrixBase<Derived>::operator-=(
const SparseMatrixBase<OtherDerived> &other)
304 return derived() = derived() - other.derived();
307 template<
typename Derived>
308 template<
typename OtherDerived>
309 EIGEN_STRONG_INLINE Derived &
310 SparseMatrixBase<Derived>::operator+=(
const SparseMatrixBase<OtherDerived>& other)
312 return derived() = derived() + other.derived();
315 template<
typename Derived>
316 template<
typename OtherDerived>
317 EIGEN_STRONG_INLINE
const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
320 return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived());
325 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H
const CwiseBinaryOp< internal::scalar_product_op< typename Derived::Scalar, typename OtherDerived::Scalar >, const Derived, const OtherDerived > cwiseProduct(const Eigen::SparseMatrixBase< OtherDerived > &other) const
Definition: SparseMatrixBase.h:23
Definition: Eigen_Colamd.h:54
const unsigned int RowMajorBit
Definition: Constants.h:53