10 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
11 #define EIGEN_SPARSE_CWISE_BINARY_OP_H
35 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
42 EIGEN_SPARSE_PUBLIC_INTERFACE(
Derived)
49 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
59 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
68 typedef typename XprType::StorageIndex StorageIndex;
76 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor)
83 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
85 m_id = m_lhsIter.index();
86 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
90 else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
92 m_id = m_lhsIter.index();
93 m_value = m_functor(m_lhsIter.value(), Scalar(0));
96 else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
98 m_id = m_rhsIter.index();
99 m_value = m_functor(Scalar(0), m_rhsIter.value());
110 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
112 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
113 EIGEN_STRONG_INLINE
Index outer()
const {
return m_lhsIter.outer(); }
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;
130 Flags = XprType::Flags
134 : m_functor(xpr.functor()),
135 m_lhsImpl(xpr.lhs()),
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>
161 typedef typename XprType::StorageIndex StorageIndex;
170 : 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())
180 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor?m_rhsIter.outer():m_id,
181 IsRowMajor?m_id:m_rhsIter.outer());
182 if(m_rhsIter && m_rhsIter.index()==m_id)
184 m_value = m_functor(lhsVal, m_rhsIter.value());
188 m_value = m_functor(lhsVal, Scalar(0));
194 EIGEN_STRONG_INLINE Scalar value()
const { eigen_internal_assert(m_id<m_innerSize);
return m_value; }
196 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
197 EIGEN_STRONG_INLINE
Index outer()
const {
return m_rhsIter.outer(); }
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; }
205 RhsIterator m_rhsIter;
206 const BinaryOp& m_functor;
209 StorageIndex m_innerSize;
215 Flags = XprType::Flags
219 : m_functor(xpr.functor()),
220 m_lhsImpl(xpr.lhs()),
221 m_rhsImpl(xpr.rhs()),
225 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
228 inline Index nonZerosEstimate()
const {
229 return m_expr.size();
233 const BinaryOp m_functor;
234 evaluator<Lhs> m_lhsImpl;
235 evaluator<Rhs> m_rhsImpl;
236 const XprType &m_expr;
240 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
248 typedef typename XprType::StorageIndex StorageIndex;
257 : 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())
267 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor?m_lhsIter.outer():m_id,
268 IsRowMajor?m_id:m_lhsIter.outer());
269 if(m_lhsIter && m_lhsIter.index()==m_id)
271 m_value = m_functor(m_lhsIter.value(), rhsVal);
275 m_value = m_functor(Scalar(0),rhsVal);
281 EIGEN_STRONG_INLINE Scalar value()
const { eigen_internal_assert(m_id<m_innerSize);
return m_value; }
283 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
284 EIGEN_STRONG_INLINE
Index outer()
const {
return m_lhsIter.outer(); }
285 EIGEN_STRONG_INLINE
Index row()
const {
return IsRowMajor ? m_lhsIter.outer() : m_id; }
286 EIGEN_STRONG_INLINE
Index col()
const {
return IsRowMajor ? m_id : m_lhsIter.outer(); }
288 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id<m_innerSize; }
291 LhsIterator m_lhsIter;
293 const BinaryOp& m_functor;
296 StorageIndex m_innerSize;
302 Flags = XprType::Flags
306 : m_functor(xpr.functor()),
307 m_lhsImpl(xpr.lhs()),
308 m_rhsImpl(xpr.rhs()),
312 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
315 inline Index nonZerosEstimate()
const {
316 return m_expr.size();
320 const BinaryOp m_functor;
321 evaluator<Lhs> m_lhsImpl;
322 evaluator<Rhs> m_rhsImpl;
323 const XprType &m_expr;
327 typename LhsKind =
typename evaluator_traits<typename T::Lhs>::Kind,
328 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
329 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
333 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
342 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
351 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
361 template<
typename T1,
typename T2,
typename Lhs,
typename Rhs>
371 template<
typename Lhs,
typename Rhs>
380 template<
typename Lhs,
typename Rhs>
389 template<
typename Lhs,
typename Rhs>
399 template<
typename XprType>
404 typedef typename XprType::Functor BinaryOp;
405 typedef typename XprType::Lhs LhsArg;
406 typedef typename XprType::Rhs RhsArg;
409 typedef typename XprType::StorageIndex StorageIndex;
418 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor)
420 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
422 if (m_lhsIter.index() < m_rhsIter.index())
433 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
435 if (m_lhsIter.index() < m_rhsIter.index())
443 EIGEN_STRONG_INLINE Scalar value()
const {
return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
445 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
446 EIGEN_STRONG_INLINE
Index outer()
const {
return m_lhsIter.outer(); }
447 EIGEN_STRONG_INLINE
Index row()
const {
return m_lhsIter.row(); }
448 EIGEN_STRONG_INLINE
Index col()
const {
return m_lhsIter.col(); }
450 EIGEN_STRONG_INLINE
operator bool()
const {
return (m_lhsIter && m_rhsIter); }
453 LhsIterator m_lhsIter;
454 RhsIterator m_rhsIter;
455 const BinaryOp& m_functor;
461 Flags = XprType::Flags
465 : m_functor(xpr.functor()),
466 m_lhsImpl(xpr.lhs()),
470 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
473 inline Index nonZerosEstimate()
const {
474 return (std::min)(m_lhsImpl.nonZerosEstimate(), m_rhsImpl.nonZerosEstimate());
478 const BinaryOp m_functor;
479 evaluator<LhsArg> m_lhsImpl;
480 evaluator<RhsArg> m_rhsImpl;
484 template<
typename XprType>
489 typedef typename XprType::Functor BinaryOp;
490 typedef typename XprType::Lhs LhsArg;
491 typedef typename XprType::Rhs RhsArg;
494 typedef typename XprType::StorageIndex StorageIndex;
505 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor), m_outer(outer)
514 EIGEN_STRONG_INLINE Scalar value()
const
515 {
return m_functor(m_lhsEval.coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
517 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_rhsIter.index(); }
518 EIGEN_STRONG_INLINE
Index outer()
const {
return m_rhsIter.outer(); }
519 EIGEN_STRONG_INLINE
Index row()
const {
return m_rhsIter.row(); }
520 EIGEN_STRONG_INLINE
Index col()
const {
return m_rhsIter.col(); }
522 EIGEN_STRONG_INLINE
operator bool()
const {
return m_rhsIter; }
526 RhsIterator m_rhsIter;
527 const BinaryOp& m_functor;
534 Flags = XprType::Flags
538 : m_functor(xpr.functor()),
539 m_lhsImpl(xpr.lhs()),
543 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
546 inline Index nonZerosEstimate()
const {
547 return m_rhsImpl.nonZerosEstimate();
551 const BinaryOp m_functor;
552 evaluator<LhsArg> m_lhsImpl;
553 evaluator<RhsArg> m_rhsImpl;
557 template<
typename XprType>
562 typedef typename XprType::Functor BinaryOp;
563 typedef typename XprType::Lhs LhsArg;
564 typedef typename XprType::Rhs RhsArg;
567 typedef typename XprType::StorageIndex StorageIndex;
578 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_outer(outer)
587 EIGEN_STRONG_INLINE Scalar value()
const
588 {
return m_functor(m_lhsIter.value(),
589 m_rhsEval.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
591 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
592 EIGEN_STRONG_INLINE
Index outer()
const {
return m_lhsIter.outer(); }
593 EIGEN_STRONG_INLINE
Index row()
const {
return m_lhsIter.row(); }
594 EIGEN_STRONG_INLINE
Index col()
const {
return m_lhsIter.col(); }
596 EIGEN_STRONG_INLINE
operator bool()
const {
return m_lhsIter; }
599 LhsIterator m_lhsIter;
601 const BinaryOp& m_functor;
608 Flags = XprType::Flags
612 : m_functor(xpr.functor()),
613 m_lhsImpl(xpr.lhs()),
617 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
620 inline Index nonZerosEstimate()
const {
621 return m_lhsImpl.nonZerosEstimate();
625 const BinaryOp m_functor;
626 evaluator<LhsArg> m_lhsImpl;
627 evaluator<RhsArg> m_rhsImpl;
636 template<
typename Derived>
637 template<
typename OtherDerived>
638 Derived& SparseMatrixBase<Derived>::operator+=(
const EigenBase<OtherDerived> &other)
640 call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
644 template<
typename Derived>
645 template<
typename OtherDerived>
646 Derived& SparseMatrixBase<Derived>::operator-=(
const EigenBase<OtherDerived> &other)
648 call_assignment(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
652 template<
typename Derived>
653 template<
typename OtherDerived>
654 EIGEN_STRONG_INLINE Derived &
655 SparseMatrixBase<Derived>::operator-=(
const SparseMatrixBase<OtherDerived> &other)
657 return derived() = derived() - other.derived();
660 template<
typename Derived>
661 template<
typename OtherDerived>
662 EIGEN_STRONG_INLINE Derived &
663 SparseMatrixBase<Derived>::operator+=(
const SparseMatrixBase<OtherDerived>& other)
665 return derived() = derived() + other.derived();
668 template<
typename Derived>
669 template<
typename OtherDerived>
670 Derived& SparseMatrixBase<Derived>::operator+=(
const DiagonalBase<OtherDerived>& other)
672 call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
676 template<
typename Derived>
677 template<
typename OtherDerived>
678 Derived& SparseMatrixBase<Derived>::operator-=(
const DiagonalBase<OtherDerived>& other)
680 call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
684 template<
typename Derived>
685 template<
typename OtherDerived>
686 EIGEN_STRONG_INLINE
const typename SparseMatrixBase<Derived>::template CwiseProductDenseReturnType<OtherDerived>::Type
687 SparseMatrixBase<Derived>::cwiseProduct(
const MatrixBase<OtherDerived> &other)
const
689 return typename CwiseProductDenseReturnType<OtherDerived>::Type(derived(), other.derived());
692 template<
typename DenseDerived,
typename SparseDerived>
693 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>
694 operator+(
const MatrixBase<DenseDerived> &a,
const SparseMatrixBase<SparseDerived> &b)
696 return CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
699 template<
typename SparseDerived,
typename DenseDerived>
700 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_sum_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>
701 operator+(
const SparseMatrixBase<SparseDerived> &a,
const MatrixBase<DenseDerived> &b)
703 return CwiseBinaryOp<internal::scalar_sum_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
706 template<
typename DenseDerived,
typename SparseDerived>
707 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>
708 operator-(
const MatrixBase<DenseDerived> &a,
const SparseMatrixBase<SparseDerived> &b)
710 return CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar,typename SparseDerived::Scalar>,
const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
713 template<
typename SparseDerived,
typename DenseDerived>
714 EIGEN_STRONG_INLINE
const CwiseBinaryOp<internal::scalar_difference_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>
715 operator-(
const SparseMatrixBase<SparseDerived> &a,
const MatrixBase<DenseDerived> &b)
717 return CwiseBinaryOp<internal::scalar_difference_op<typename SparseDerived::Scalar,typename DenseDerived::Scalar>,
const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
722 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H