10 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H 11 #define EIGEN_SPARSE_CWISE_BINARY_OP_H 35 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
36 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
37 :
public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
40 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
41 typedef SparseMatrixBase<Derived> Base;
42 EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
46 (!internal::is_same<
typename internal::traits<Lhs>::StorageKind,
47 typename internal::traits<Rhs>::StorageKind>::value)
48 || ((Lhs::Flags&
RowMajorBit) == (Rhs::Flags&RowMajorBit))),
49 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
57 template<
typename XprType>
struct binary_sparse_evaluator;
59 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
60 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IteratorBased>
61 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
64 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
65 typedef typename evaluator<Rhs>::InnerIterator RhsIterator;
66 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
67 typedef typename traits<XprType>::Scalar Scalar;
68 typedef typename XprType::StorageIndex StorageIndex;
71 class ReverseInnerIterator;
76 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval,
Index outer)
77 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor)
82 EIGEN_STRONG_INLINE InnerIterator& operator++()
84 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
86 m_id = m_lhsIter.index();
87 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
91 else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
93 m_id = m_lhsIter.index();
94 m_value = m_functor(m_lhsIter.value(), Scalar(0));
97 else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
99 m_id = m_rhsIter.index();
100 m_value = m_functor(Scalar(0), m_rhsIter.value());
111 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
113 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
114 EIGEN_STRONG_INLINE
Index row()
const {
return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
115 EIGEN_STRONG_INLINE
Index col()
const {
return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
117 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id>=0; }
120 LhsIterator m_lhsIter;
121 RhsIterator m_rhsIter;
122 const BinaryOp& m_functor;
129 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
130 Flags = XprType::Flags
133 explicit binary_evaluator(
const XprType& xpr)
134 : m_functor(xpr.functor()),
135 m_lhsImpl(xpr.lhs()),
138 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
139 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
142 inline Index nonZerosEstimate()
const {
143 return m_lhsImpl.nonZerosEstimate() + m_rhsImpl.nonZerosEstimate();
147 const BinaryOp m_functor;
148 evaluator<Lhs> m_lhsImpl;
149 evaluator<Rhs> m_rhsImpl;
153 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
154 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IteratorBased>
155 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
158 typedef typename evaluator<Rhs>::InnerIterator RhsIterator;
159 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
160 typedef typename traits<XprType>::Scalar Scalar;
161 typedef typename XprType::StorageIndex StorageIndex;
164 class ReverseInnerIterator;
170 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval,
Index outer)
171 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor), m_value(0), m_id(-1), m_innerSize(aEval.m_expr.rhs().innerSize())
176 EIGEN_STRONG_INLINE InnerIterator& operator++()
181 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor?m_rhsIter.outer():m_id,
182 IsRowMajor?m_id:m_rhsIter.outer());
183 if(m_rhsIter && m_rhsIter.index()==m_id)
185 m_value = m_functor(lhsVal, m_rhsIter.value());
189 m_value = m_functor(lhsVal, Scalar(0));
195 EIGEN_STRONG_INLINE Scalar value()
const { eigen_internal_assert(m_id<m_innerSize);
return m_value; }
197 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
198 EIGEN_STRONG_INLINE
Index row()
const {
return IsRowMajor ? m_rhsIter.outer() : m_id; }
199 EIGEN_STRONG_INLINE
Index col()
const {
return IsRowMajor ? m_id : m_rhsIter.outer(); }
201 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id<m_innerSize; }
204 const evaluator<Lhs> &m_lhsEval;
205 RhsIterator m_rhsIter;
206 const BinaryOp& m_functor;
209 StorageIndex m_innerSize;
214 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
219 explicit binary_evaluator(
const XprType& xpr)
220 : m_functor(xpr.functor()),
221 m_lhsImpl(xpr.lhs()),
222 m_rhsImpl(xpr.rhs()),
225 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
226 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
229 inline Index nonZerosEstimate()
const {
230 return m_expr.size();
234 const BinaryOp m_functor;
235 evaluator<Lhs> m_lhsImpl;
236 evaluator<Rhs> m_rhsImpl;
237 const XprType &m_expr;
241 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
242 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IndexBased>
243 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
246 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
247 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
248 typedef typename traits<XprType>::Scalar Scalar;
249 typedef typename XprType::StorageIndex StorageIndex;
252 class ReverseInnerIterator;
258 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval,
Index outer)
259 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_value(0), m_id(-1), m_innerSize(aEval.m_expr.lhs().innerSize())
264 EIGEN_STRONG_INLINE InnerIterator& operator++()
269 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor?m_lhsIter.outer():m_id,
270 IsRowMajor?m_id:m_lhsIter.outer());
271 if(m_lhsIter && m_lhsIter.index()==m_id)
273 m_value = m_functor(m_lhsIter.value(), rhsVal);
277 m_value = m_functor(Scalar(0),rhsVal);
283 EIGEN_STRONG_INLINE Scalar value()
const { eigen_internal_assert(m_id<m_innerSize);
return m_value; }
285 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
286 EIGEN_STRONG_INLINE
Index row()
const {
return IsRowMajor ? m_lhsIter.outer() : m_id; }
287 EIGEN_STRONG_INLINE
Index col()
const {
return IsRowMajor ? m_id : m_lhsIter.outer(); }
289 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id<m_innerSize; }
292 LhsIterator m_lhsIter;
293 const evaluator<Rhs> &m_rhsEval;
294 const BinaryOp& m_functor;
297 StorageIndex m_innerSize;
302 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
307 explicit binary_evaluator(
const XprType& xpr)
308 : m_functor(xpr.functor()),
309 m_lhsImpl(xpr.lhs()),
310 m_rhsImpl(xpr.rhs()),
313 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
314 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
317 inline Index nonZerosEstimate()
const {
318 return m_expr.size();
322 const BinaryOp m_functor;
323 evaluator<Lhs> m_lhsImpl;
324 evaluator<Rhs> m_rhsImpl;
325 const XprType &m_expr;
329 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
330 struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs>, IteratorBased, IteratorBased>
331 : evaluator_base<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs> >
334 typedef scalar_product_op<T1,T2> BinaryOp;
335 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
336 typedef typename evaluator<Rhs>::InnerIterator RhsIterator;
337 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
338 typedef typename XprType::StorageIndex StorageIndex;
339 typedef typename traits<XprType>::Scalar Scalar;
342 class ReverseInnerIterator;
347 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval,
Index outer)
348 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor)
350 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
352 if (m_lhsIter.index() < m_rhsIter.index())
359 EIGEN_STRONG_INLINE InnerIterator& operator++()
363 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
365 if (m_lhsIter.index() < m_rhsIter.index())
373 EIGEN_STRONG_INLINE Scalar value()
const {
return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
375 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
376 EIGEN_STRONG_INLINE
Index row()
const {
return m_lhsIter.row(); }
377 EIGEN_STRONG_INLINE
Index col()
const {
return m_lhsIter.col(); }
379 EIGEN_STRONG_INLINE
operator bool()
const {
return (m_lhsIter && m_rhsIter); }
382 LhsIterator m_lhsIter;
383 RhsIterator m_rhsIter;
384 const BinaryOp& m_functor;
389 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
390 Flags = XprType::Flags
393 explicit binary_evaluator(
const XprType& xpr)
394 : m_functor(xpr.functor()),
395 m_lhsImpl(xpr.lhs()),
398 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
399 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
402 inline Index nonZerosEstimate()
const {
403 return (std::min)(m_lhsImpl.nonZerosEstimate(), m_rhsImpl.nonZerosEstimate());
407 const BinaryOp m_functor;
408 evaluator<Lhs> m_lhsImpl;
409 evaluator<Rhs> m_rhsImpl;
413 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
414 struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs>, IndexBased, IteratorBased>
415 : evaluator_base<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs> >
418 typedef scalar_product_op<T1,T2> BinaryOp;
419 typedef evaluator<Lhs> LhsEvaluator;
420 typedef typename evaluator<Rhs>::InnerIterator RhsIterator;
421 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
422 typedef typename XprType::StorageIndex StorageIndex;
423 typedef typename traits<XprType>::Scalar Scalar;
426 class ReverseInnerIterator;
433 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval,
Index outer)
434 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor), m_outer(outer)
437 EIGEN_STRONG_INLINE InnerIterator& operator++()
443 EIGEN_STRONG_INLINE Scalar value()
const 444 {
return m_functor(m_lhsEval.coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
446 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_rhsIter.index(); }
447 EIGEN_STRONG_INLINE
Index row()
const {
return m_rhsIter.row(); }
448 EIGEN_STRONG_INLINE
Index col()
const {
return m_rhsIter.col(); }
450 EIGEN_STRONG_INLINE
operator bool()
const {
return m_rhsIter; }
453 const LhsEvaluator &m_lhsEval;
454 RhsIterator m_rhsIter;
455 const BinaryOp& m_functor;
461 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
466 explicit binary_evaluator(
const XprType& xpr)
467 : m_functor(xpr.functor()),
468 m_lhsImpl(xpr.lhs()),
471 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
472 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
475 inline Index nonZerosEstimate()
const {
476 return m_rhsImpl.nonZerosEstimate();
480 const BinaryOp m_functor;
481 evaluator<Lhs> m_lhsImpl;
482 evaluator<Rhs> m_rhsImpl;
486 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
487 struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs>, IteratorBased, IndexBased>
488 : evaluator_base<CwiseBinaryOp<scalar_product_op<T1,T2>, Lhs, Rhs> >
491 typedef scalar_product_op<T1,T2> BinaryOp;
492 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
493 typedef evaluator<Rhs> RhsEvaluator;
494 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
495 typedef typename XprType::StorageIndex StorageIndex;
496 typedef typename traits<XprType>::Scalar Scalar;
499 class ReverseInnerIterator;
506 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval,
Index outer)
507 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_outer(outer)
510 EIGEN_STRONG_INLINE InnerIterator& operator++()
516 EIGEN_STRONG_INLINE Scalar value()
const 517 {
return m_functor(m_lhsIter.value(),
518 m_rhsEval.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
520 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
521 EIGEN_STRONG_INLINE
Index row()
const {
return m_lhsIter.row(); }
522 EIGEN_STRONG_INLINE
Index col()
const {
return m_lhsIter.col(); }
524 EIGEN_STRONG_INLINE
operator bool()
const {
return m_lhsIter; }
527 LhsIterator m_lhsIter;
528 const evaluator<Rhs> &m_rhsEval;
529 const BinaryOp& m_functor;
535 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
540 explicit binary_evaluator(
const XprType& xpr)
541 : m_functor(xpr.functor()),
542 m_lhsImpl(xpr.lhs()),
545 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
546 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
549 inline Index nonZerosEstimate()
const {
550 return m_lhsImpl.nonZerosEstimate();
554 const BinaryOp m_functor;
555 evaluator<Lhs> m_lhsImpl;
556 evaluator<Rhs> m_rhsImpl;
565 template<
typename Derived>
566 template<
typename OtherDerived>
567 EIGEN_STRONG_INLINE Derived &
568 SparseMatrixBase<Derived>::operator-=(
const SparseMatrixBase<OtherDerived> &other)
570 return derived() = derived() - other.derived();
573 template<
typename Derived>
574 template<
typename OtherDerived>
575 EIGEN_STRONG_INLINE Derived &
576 SparseMatrixBase<Derived>::operator+=(
const SparseMatrixBase<OtherDerived>& other)
578 return derived() = derived() + other.derived();
581 template<
typename Derived>
582 template<
typename OtherDerived>
583 Derived& SparseMatrixBase<Derived>::operator+=(
const DiagonalBase<OtherDerived>& other)
585 call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
589 template<
typename Derived>
590 template<
typename OtherDerived>
591 Derived& SparseMatrixBase<Derived>::operator-=(
const DiagonalBase<OtherDerived>& other)
593 call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
597 template<
typename Derived>
598 template<
typename OtherDerived>
599 EIGEN_STRONG_INLINE
const typename SparseMatrixBase<Derived>::template CwiseProductDenseReturnType<OtherDerived>::Type
600 SparseMatrixBase<Derived>::cwiseProduct(
const MatrixBase<OtherDerived> &other)
const 602 return typename CwiseProductDenseReturnType<OtherDerived>::Type(derived(), other.derived());
605 template<
typename DenseDerived,
typename SparseDerived>
606 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>
607 operator+(
const MatrixBase<DenseDerived> &a,
const SparseMatrixBase<SparseDerived> &b)
609 return CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
612 template<
typename SparseDerived,
typename DenseDerived>
613 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_sum_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>
614 operator+(
const SparseMatrixBase<SparseDerived> &a,
const MatrixBase<DenseDerived> &b)
616 return CwiseBinaryOp<internal::scalar_sum_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
619 template<
typename DenseDerived,
typename SparseDerived>
620 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>
621 operator-(
const MatrixBase<DenseDerived> &a,
const SparseMatrixBase<SparseDerived> &b)
623 return CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
626 template<
typename SparseDerived,
typename DenseDerived>
627 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_difference_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>
628 operator-(
const SparseMatrixBase<SparseDerived> &a,
const MatrixBase<DenseDerived> &b)
630 return CwiseBinaryOp<internal::scalar_difference_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
635 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H Namespace containing all symbols from the Eigen library.
Definition: Core:271
const unsigned int RowMajorBit
Definition: Constants.h:61
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: XprHelper.h:35
Definition: Eigen_Colamd.h:50