25 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
26 #define EIGEN_SPARSE_CWISE_BINARY_OP_H
49 template<>
struct promote_storage_type<Dense,Sparse>
50 {
typedef Sparse ret; };
52 template<>
struct promote_storage_type<Sparse,Dense>
53 {
typedef Sparse ret; };
55 template<
typename BinaryOp,
typename Lhs,
typename Rhs,
typename Derived,
58 class sparse_cwise_binary_op_inner_iterator_selector;
62 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
68 class ReverseInnerIterator;
73 typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind;
74 typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind;
76 (!internal::is_same<LhsStorageKind,RhsStorageKind>::value)
77 || ((Lhs::Flags&
RowMajorBit) == (Rhs::Flags&RowMajorBit))),
78 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
82 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
84 :
public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator>
87 typedef typename Lhs::Index Index;
88 typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
89 BinaryOp,Lhs,Rhs, InnerIterator> Base;
92 : Base(binOp.derived(),outer)
108 template<
typename BinaryOp,
typename Lhs,
typename Rhs,
typename Derived>
109 class sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
111 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
115 typedef typename _LhsNested::InnerIterator LhsIterator;
116 typedef typename _RhsNested::InnerIterator RhsIterator;
117 typedef typename Lhs::Index Index;
121 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
122 : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
129 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
131 m_id = m_lhsIter.index();
132 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
136 else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
138 m_id = m_lhsIter.index();
139 m_value = m_functor(m_lhsIter.value(), Scalar(0));
142 else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
144 m_id = m_rhsIter.index();
145 m_value = m_functor(Scalar(0), m_rhsIter.value());
153 return *
static_cast<Derived*
>(
this);
165 LhsIterator m_lhsIter;
166 RhsIterator m_rhsIter;
167 const BinaryOp& m_functor;
173 template<
typename T,
typename Lhs,
typename Rhs,
typename Derived>
174 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
176 typedef scalar_product_op<T> BinaryFunc;
177 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
178 typedef typename CwiseBinaryXpr::Scalar Scalar;
180 typedef typename _LhsNested::InnerIterator LhsIterator;
182 typedef typename _RhsNested::InnerIterator RhsIterator;
183 typedef typename Lhs::Index Index;
186 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
187 : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
189 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
191 if (m_lhsIter.index() < m_rhsIter.index())
202 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
204 if (m_lhsIter.index() < m_rhsIter.index())
209 return *
static_cast<Derived*
>(
this);
212 EIGEN_STRONG_INLINE Scalar value()
const {
return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
221 LhsIterator m_lhsIter;
222 RhsIterator m_rhsIter;
223 const BinaryFunc& m_functor;
227 template<
typename T,
typename Lhs,
typename Rhs,
typename Derived>
228 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
230 typedef scalar_product_op<T> BinaryFunc;
231 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
232 typedef typename CwiseBinaryXpr::Scalar Scalar;
235 typedef typename _LhsNested::InnerIterator LhsIterator;
236 typedef typename Lhs::Index Index;
240 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
241 : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer)
247 return *
static_cast<Derived*
>(
this);
251 {
return m_functor(m_lhsIter.value(),
252 m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
262 LhsIterator m_lhsIter;
263 const BinaryFunc m_functor;
268 template<
typename T,
typename Lhs,
typename Rhs,
typename Derived>
269 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
271 typedef scalar_product_op<T> BinaryFunc;
272 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
273 typedef typename CwiseBinaryXpr::Scalar Scalar;
275 typedef typename _RhsNested::InnerIterator RhsIterator;
276 typedef typename Lhs::Index Index;
281 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(
const CwiseBinaryXpr& xpr, Index outer)
282 : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
288 return *
static_cast<Derived*
>(
this);
292 {
return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
301 const CwiseBinaryXpr& m_xpr;
302 RhsIterator m_rhsIter;
303 const BinaryFunc& m_functor;
313 template<
typename Derived>
314 template<
typename OtherDerived>
318 return *
this = derived() - other.
derived();
321 template<
typename Derived>
322 template<
typename OtherDerived>
326 return *
this = derived() + other.
derived();
329 template<
typename Derived>
330 template<
typename OtherDerived>
339 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H