11#ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
12#define EIGEN_SPARSE_CWISE_BINARY_OP_H
15#include "./InternalHeaderCheck.h"
39template <
typename BinaryOp,
typename Lhs,
typename Rhs>
40class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs,
Sparse> :
public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
42 using Derived = CwiseBinaryOp<BinaryOp, Lhs, Rhs>;
43 using Base = SparseMatrixBase<Derived>;
44 EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
45 EIGEN_STATIC_ASSERT(((!std::is_same<
typename internal::traits<Lhs>::StorageKind,
46 typename internal::traits<Rhs>::StorageKind>::value) ||
49 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH)
62template <
typename BinaryOp,
typename Lhs,
typename Rhs>
63struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IteratorBased>
64 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
66 using LhsIterator =
typename evaluator<Lhs>::InnerIterator;
67 using RhsIterator =
typename evaluator<Rhs>::InnerIterator;
68 using XprType = CwiseBinaryOp<BinaryOp, Lhs, Rhs>;
69 using Scalar =
typename traits<XprType>::Scalar;
70 using StorageIndex =
typename XprType::StorageIndex;
75 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval, Index outer)
76 : m_lhsIter(aEval.m_lhsImpl, outer),
77 m_rhsIter(aEval.m_rhsImpl, outer),
78 m_functor(aEval.m_functor),
83 EIGEN_STRONG_INLINE InnerIterator& operator++() {
84 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());
89 }
else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index()))) {
90 m_id = m_lhsIter.index();
91 m_value = m_functor(m_lhsIter.value(), Scalar(0));
93 }
else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index()))) {
94 m_id = m_rhsIter.index();
95 m_value = m_functor(Scalar(0), m_rhsIter.value());
103 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
105 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
106 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
107 EIGEN_STRONG_INLINE Index row()
const {
return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
108 EIGEN_STRONG_INLINE Index col()
const {
return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
110 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id >= 0; }
113 LhsIterator m_lhsIter;
114 RhsIterator m_rhsIter;
115 const BinaryOp& m_functor;
122 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
123 Flags = XprType::Flags
126 explicit binary_evaluator(
const XprType& xpr) : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
127 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
128 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
131 inline Index nonZerosEstimate()
const {
return m_lhsImpl.nonZerosEstimate() + m_rhsImpl.nonZerosEstimate(); }
134 const BinaryOp m_functor;
135 evaluator<Lhs> m_lhsImpl;
136 evaluator<Rhs> m_rhsImpl;
140template <
typename BinaryOp,
typename Lhs,
typename Rhs>
141struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IteratorBased>
142 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
144 using RhsIterator =
typename evaluator<Rhs>::InnerIterator;
145 using XprType = CwiseBinaryOp<BinaryOp, Lhs, Rhs>;
146 using Scalar =
typename traits<XprType>::Scalar;
147 using StorageIndex =
typename XprType::StorageIndex;
150 class InnerIterator {
151 enum { IsRowMajor = (int(Rhs::Flags) &
RowMajorBit) == RowMajorBit };
154 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval, Index outer)
155 : m_lhsEval(aEval.m_lhsImpl),
156 m_rhsIter(aEval.m_rhsImpl, outer),
157 m_functor(aEval.m_functor),
160 m_innerSize(aEval.m_expr.rhs().innerSize()) {
164 EIGEN_STRONG_INLINE InnerIterator& operator++() {
166 if (m_id < m_innerSize) {
167 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor ? m_rhsIter.outer() : m_id, IsRowMajor ? m_id : m_rhsIter.outer());
168 if (m_rhsIter && m_rhsIter.index() == m_id) {
169 m_value = m_functor(lhsVal, m_rhsIter.value());
172 m_value = m_functor(lhsVal, Scalar(0));
178 EIGEN_STRONG_INLINE Scalar value()
const {
179 eigen_internal_assert(m_id < m_innerSize);
183 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
184 EIGEN_STRONG_INLINE Index outer()
const {
return m_rhsIter.outer(); }
185 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_rhsIter.outer() : m_id; }
186 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_rhsIter.outer(); }
188 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
191 const evaluator<Lhs>& m_lhsEval;
192 RhsIterator m_rhsIter;
193 const BinaryOp& m_functor;
196 StorageIndex m_innerSize;
201 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
202 Flags = XprType::Flags
205 explicit binary_evaluator(
const XprType& xpr)
206 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
207 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
208 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
211 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
214 const BinaryOp m_functor;
215 evaluator<Lhs> m_lhsImpl;
216 evaluator<Rhs> m_rhsImpl;
217 const XprType& m_expr;
221template <
typename BinaryOp,
typename Lhs,
typename Rhs>
222struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IndexBased>
223 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
225 using LhsIterator =
typename evaluator<Lhs>::InnerIterator;
226 using XprType = CwiseBinaryOp<BinaryOp, Lhs, Rhs>;
227 using Scalar =
typename traits<XprType>::Scalar;
228 using StorageIndex =
typename XprType::StorageIndex;
231 class InnerIterator {
232 enum { IsRowMajor = (int(Lhs::Flags) &
RowMajorBit) == RowMajorBit };
235 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval, Index outer)
236 : m_lhsIter(aEval.m_lhsImpl, outer),
237 m_rhsEval(aEval.m_rhsImpl),
238 m_functor(aEval.m_functor),
241 m_innerSize(aEval.m_expr.lhs().innerSize()) {
245 EIGEN_STRONG_INLINE InnerIterator& operator++() {
247 if (m_id < m_innerSize) {
248 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor ? m_lhsIter.outer() : m_id, IsRowMajor ? m_id : m_lhsIter.outer());
249 if (m_lhsIter && m_lhsIter.index() == m_id) {
250 m_value = m_functor(m_lhsIter.value(), rhsVal);
253 m_value = m_functor(Scalar(0), rhsVal);
259 EIGEN_STRONG_INLINE Scalar value()
const {
260 eigen_internal_assert(m_id < m_innerSize);
264 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
265 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
266 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_lhsIter.outer() : m_id; }
267 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_lhsIter.outer(); }
269 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
272 LhsIterator m_lhsIter;
273 const evaluator<Rhs>& m_rhsEval;
274 const BinaryOp& m_functor;
277 StorageIndex m_innerSize;
282 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
283 Flags = XprType::Flags
286 explicit binary_evaluator(
const XprType& xpr)
287 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
288 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
289 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
292 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
295 const BinaryOp m_functor;
296 evaluator<Lhs> m_lhsImpl;
297 evaluator<Rhs> m_rhsImpl;
298 const XprType& m_expr;
301template <typename T, typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
302 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
303 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
304 typename RhsScalar =
typename traits<typename T::Rhs>::Scalar>
305struct sparse_conjunction_evaluator;
308template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
309struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>, IteratorBased, IteratorBased>
310 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> > {
311 using XprType = CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>;
312 using Base = sparse_conjunction_evaluator<XprType>;
313 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
316template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
317struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>, IndexBased, IteratorBased>
318 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> > {
319 using XprType = CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>;
320 using Base = sparse_conjunction_evaluator<XprType>;
321 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
324template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
325struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>, IteratorBased, IndexBased>
326 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> > {
327 using XprType = CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>;
328 using Base = sparse_conjunction_evaluator<XprType>;
329 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
333template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
334struct binary_evaluator<CwiseBinaryOp<scalar_quotient_op<T1, T2>, Lhs, Rhs>, IteratorBased, IndexBased>
335 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_quotient_op<T1, T2>, Lhs, Rhs> > {
336 using XprType = CwiseBinaryOp<scalar_quotient_op<T1, T2>, Lhs, Rhs>;
337 using Base = sparse_conjunction_evaluator<XprType>;
338 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
342template <
typename Lhs,
typename Rhs>
343struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>, IteratorBased, IteratorBased>
344 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> > {
345 using XprType = CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>;
346 using Base = sparse_conjunction_evaluator<XprType>;
347 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
350template <
typename Lhs,
typename Rhs>
351struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>, IndexBased, IteratorBased>
352 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> > {
353 using XprType = CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>;
354 using Base = sparse_conjunction_evaluator<XprType>;
355 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
358template <
typename Lhs,
typename Rhs>
359struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>, IteratorBased, IndexBased>
360 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> > {
361 using XprType = CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>;
362 using Base = sparse_conjunction_evaluator<XprType>;
363 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
374template <
typename XprType>
375struct sparse_conjunction_evaluator<XprType, IteratorBased, IteratorBased> : evaluator_base<XprType> {
377 using BinaryOp =
typename XprType::Functor;
378 using LhsArg =
typename XprType::Lhs;
379 using RhsArg =
typename XprType::Rhs;
380 using LhsIterator =
typename evaluator<LhsArg>::InnerIterator;
381 using RhsIterator =
typename evaluator<RhsArg>::InnerIterator;
382 using StorageIndex =
typename XprType::StorageIndex;
383 using Scalar =
typename traits<XprType>::Scalar;
386 class InnerIterator {
388 EIGEN_STRONG_INLINE InnerIterator(
const sparse_conjunction_evaluator& aEval, Index outer)
389 : m_lhsIter(aEval.m_lhsImpl, outer), m_rhsIter(aEval.m_rhsImpl, outer), m_functor(aEval.m_functor) {
390 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) {
391 if (m_lhsIter.index() < m_rhsIter.index())
398 EIGEN_STRONG_INLINE InnerIterator& operator++() {
401 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) {
402 if (m_lhsIter.index() < m_rhsIter.index())
410 EIGEN_STRONG_INLINE Scalar value()
const {
return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
412 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
413 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
414 EIGEN_STRONG_INLINE Index row()
const {
return m_lhsIter.row(); }
415 EIGEN_STRONG_INLINE Index col()
const {
return m_lhsIter.col(); }
417 EIGEN_STRONG_INLINE
operator bool()
const {
return m_lhsIter && m_rhsIter; }
420 LhsIterator m_lhsIter;
421 RhsIterator m_rhsIter;
422 const BinaryOp& m_functor;
426 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
427 int(functor_traits<BinaryOp>::Cost),
428 Flags = XprType::Flags
431 explicit sparse_conjunction_evaluator(
const XprType& xpr)
432 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
433 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
434 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
437 inline Index nonZerosEstimate()
const {
438 return (std::min)(m_lhsImpl.nonZerosEstimate(), m_rhsImpl.nonZerosEstimate());
442 const BinaryOp m_functor;
443 evaluator<LhsArg> m_lhsImpl;
444 evaluator<RhsArg> m_rhsImpl;
448template <
typename XprType>
449struct sparse_conjunction_evaluator<XprType, IndexBased, IteratorBased> : evaluator_base<XprType> {
451 using BinaryOp =
typename XprType::Functor;
452 using LhsArg =
typename XprType::Lhs;
453 using RhsArg =
typename XprType::Rhs;
454 using LhsEvaluator = evaluator<LhsArg>;
455 using RhsIterator =
typename evaluator<RhsArg>::InnerIterator;
456 using StorageIndex =
typename XprType::StorageIndex;
457 using Scalar =
typename traits<XprType>::Scalar;
460 class InnerIterator {
461 enum { IsRowMajor = (int(RhsArg::Flags) &
RowMajorBit) == RowMajorBit };
464 EIGEN_STRONG_INLINE InnerIterator(
const sparse_conjunction_evaluator& aEval, Index outer)
465 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl, outer), m_functor(aEval.m_functor), m_outer(outer) {}
467 EIGEN_STRONG_INLINE InnerIterator& operator++() {
472 EIGEN_STRONG_INLINE Scalar value()
const {
474 m_lhsEval.coeff(IsRowMajor ? m_outer : m_rhsIter.index(), IsRowMajor ? m_rhsIter.index() : m_outer),
478 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_rhsIter.index(); }
479 EIGEN_STRONG_INLINE Index outer()
const {
return m_rhsIter.outer(); }
480 EIGEN_STRONG_INLINE Index row()
const {
return m_rhsIter.row(); }
481 EIGEN_STRONG_INLINE Index col()
const {
return m_rhsIter.col(); }
483 EIGEN_STRONG_INLINE
operator bool()
const {
return m_rhsIter; }
486 const LhsEvaluator& m_lhsEval;
487 RhsIterator m_rhsIter;
488 const BinaryOp& m_functor;
493 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
494 int(functor_traits<BinaryOp>::Cost),
495 Flags = XprType::Flags
498 explicit sparse_conjunction_evaluator(
const XprType& xpr)
499 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
500 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
501 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
504 inline Index nonZerosEstimate()
const {
return m_rhsImpl.nonZerosEstimate(); }
507 const BinaryOp m_functor;
508 evaluator<LhsArg> m_lhsImpl;
509 evaluator<RhsArg> m_rhsImpl;
513template <
typename XprType>
514struct sparse_conjunction_evaluator<XprType, IteratorBased, IndexBased> : evaluator_base<XprType> {
516 using BinaryOp =
typename XprType::Functor;
517 using LhsArg =
typename XprType::Lhs;
518 using RhsArg =
typename XprType::Rhs;
519 using LhsIterator =
typename evaluator<LhsArg>::InnerIterator;
520 using StorageIndex =
typename XprType::StorageIndex;
521 using Scalar =
typename traits<XprType>::Scalar;
524 class InnerIterator {
525 enum { IsRowMajor = (int(LhsArg::Flags) &
RowMajorBit) == RowMajorBit };
528 EIGEN_STRONG_INLINE InnerIterator(
const sparse_conjunction_evaluator& aEval, Index outer)
529 : m_lhsIter(aEval.m_lhsImpl, outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_outer(outer) {}
531 EIGEN_STRONG_INLINE InnerIterator& operator++() {
536 EIGEN_STRONG_INLINE Scalar value()
const {
537 return m_functor(m_lhsIter.value(), m_rhsEval.coeff(IsRowMajor ? m_outer : m_lhsIter.index(),
538 IsRowMajor ? m_lhsIter.index() : m_outer));
541 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
542 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
543 EIGEN_STRONG_INLINE Index row()
const {
return m_lhsIter.row(); }
544 EIGEN_STRONG_INLINE Index col()
const {
return m_lhsIter.col(); }
546 EIGEN_STRONG_INLINE
operator bool()
const {
return m_lhsIter; }
549 LhsIterator m_lhsIter;
550 const evaluator<RhsArg>& m_rhsEval;
551 const BinaryOp& m_functor;
556 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
557 int(functor_traits<BinaryOp>::Cost),
558 Flags = XprType::Flags
561 explicit sparse_conjunction_evaluator(
const XprType& xpr)
562 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
563 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
564 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
567 inline Index nonZerosEstimate()
const {
return m_lhsImpl.nonZerosEstimate(); }
570 const BinaryOp m_functor;
571 evaluator<LhsArg> m_lhsImpl;
572 evaluator<RhsArg> m_rhsImpl;
575template <typename T, typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
576 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
577 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
578 typename RhsScalar =
typename traits<typename T::Rhs>::Scalar>
579struct sparse_disjunction_evaluator;
589template <
typename XprType>
590struct sparse_disjunction_evaluator<XprType, IteratorBased, IteratorBased> : evaluator_base<XprType> {
592 using BinaryOp =
typename XprType::Functor;
593 using LhsArg =
typename XprType::Lhs;
594 using RhsArg =
typename XprType::Rhs;
595 using LhsIterator =
typename evaluator<LhsArg>::InnerIterator;
596 using RhsIterator =
typename evaluator<RhsArg>::InnerIterator;
597 using StorageIndex =
typename XprType::StorageIndex;
598 using Scalar =
typename traits<XprType>::Scalar;
601 class InnerIterator {
603 EIGEN_STRONG_INLINE InnerIterator(
const sparse_disjunction_evaluator& aEval, Index outer)
604 : m_lhsIter(aEval.m_lhsImpl, outer),
605 m_rhsIter(aEval.m_rhsImpl, outer),
606 m_functor(aEval.m_functor),
611 EIGEN_STRONG_INLINE InnerIterator& operator++() {
612 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index())) {
613 m_id = m_lhsIter.index();
614 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
617 }
else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index()))) {
618 m_id = m_lhsIter.index();
619 m_value = m_lhsIter.value();
621 }
else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index()))) {
622 m_id = m_rhsIter.index();
623 m_value = m_rhsIter.value();
631 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
633 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
634 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
635 EIGEN_STRONG_INLINE Index row()
const {
return LhsArg::IsRowMajor ? m_lhsIter.row() : index(); }
636 EIGEN_STRONG_INLINE Index col()
const {
return LhsArg::IsRowMajor ? index() : m_lhsIter.col(); }
638 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id >= 0; }
641 LhsIterator m_lhsIter;
642 RhsIterator m_rhsIter;
643 const BinaryOp& m_functor;
649 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
650 int(functor_traits<BinaryOp>::Cost),
651 Flags = XprType::Flags
654 explicit sparse_disjunction_evaluator(
const XprType& xpr)
655 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
656 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
657 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
660 inline Index nonZerosEstimate()
const {
return m_lhsImpl.nonZerosEstimate() + m_rhsImpl.nonZerosEstimate(); }
663 const BinaryOp m_functor;
664 evaluator<LhsArg> m_lhsImpl;
665 evaluator<RhsArg> m_rhsImpl;
669template <
typename XprType>
670struct sparse_disjunction_evaluator<XprType, IndexBased, IteratorBased> : evaluator_base<XprType> {
672 using BinaryOp =
typename XprType::Functor;
673 using LhsArg =
typename XprType::Lhs;
674 using RhsArg =
typename XprType::Rhs;
675 using RhsIterator =
typename evaluator<RhsArg>::InnerIterator;
676 using StorageIndex =
typename XprType::StorageIndex;
677 using Scalar =
typename traits<XprType>::Scalar;
680 class InnerIterator {
681 enum { IsRowMajor = (int(RhsArg::Flags) &
RowMajorBit) == RowMajorBit };
684 EIGEN_STRONG_INLINE InnerIterator(
const sparse_disjunction_evaluator& aEval, Index outer)
685 : m_lhsEval(aEval.m_lhsImpl),
686 m_rhsIter(aEval.m_rhsImpl, outer),
687 m_functor(aEval.m_functor),
690 m_innerSize(aEval.m_expr.rhs().innerSize()) {
694 EIGEN_STRONG_INLINE InnerIterator& operator++() {
696 if (m_id < m_innerSize) {
697 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor ? m_rhsIter.outer() : m_id, IsRowMajor ? m_id : m_rhsIter.outer());
698 if (m_rhsIter && m_rhsIter.index() == m_id) {
699 m_value = m_functor(lhsVal, m_rhsIter.value());
708 EIGEN_STRONG_INLINE Scalar value()
const {
709 eigen_internal_assert(m_id < m_innerSize);
713 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
714 EIGEN_STRONG_INLINE Index outer()
const {
return m_rhsIter.outer(); }
715 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_rhsIter.outer() : m_id; }
716 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_rhsIter.outer(); }
718 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
721 const evaluator<LhsArg>& m_lhsEval;
722 RhsIterator m_rhsIter;
723 const BinaryOp& m_functor;
726 StorageIndex m_innerSize;
730 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
731 int(functor_traits<BinaryOp>::Cost),
732 Flags = XprType::Flags
735 explicit sparse_disjunction_evaluator(
const XprType& xpr)
736 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
737 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
738 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
741 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
744 const BinaryOp m_functor;
745 evaluator<LhsArg> m_lhsImpl;
746 evaluator<RhsArg> m_rhsImpl;
747 const XprType& m_expr;
751template <
typename XprType>
752struct sparse_disjunction_evaluator<XprType, IteratorBased, IndexBased> : evaluator_base<XprType> {
754 using BinaryOp =
typename XprType::Functor;
755 using LhsArg =
typename XprType::Lhs;
756 using RhsArg =
typename XprType::Rhs;
757 using LhsIterator =
typename evaluator<LhsArg>::InnerIterator;
758 using StorageIndex =
typename XprType::StorageIndex;
759 using Scalar =
typename traits<XprType>::Scalar;
762 class InnerIterator {
763 enum { IsRowMajor = (int(LhsArg::Flags) &
RowMajorBit) == RowMajorBit };
766 EIGEN_STRONG_INLINE InnerIterator(
const sparse_disjunction_evaluator& aEval, Index outer)
767 : m_lhsIter(aEval.m_lhsImpl, outer),
768 m_rhsEval(aEval.m_rhsImpl),
769 m_functor(aEval.m_functor),
772 m_innerSize(aEval.m_expr.lhs().innerSize()) {
776 EIGEN_STRONG_INLINE InnerIterator& operator++() {
778 if (m_id < m_innerSize) {
779 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor ? m_lhsIter.outer() : m_id, IsRowMajor ? m_id : m_lhsIter.outer());
780 if (m_lhsIter && m_lhsIter.index() == m_id) {
781 m_value = m_functor(m_lhsIter.value(), rhsVal);
790 EIGEN_STRONG_INLINE Scalar value()
const {
791 eigen_internal_assert(m_id < m_innerSize);
795 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
796 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
797 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_lhsIter.outer() : m_id; }
798 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_lhsIter.outer(); }
800 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
803 LhsIterator m_lhsIter;
804 const evaluator<RhsArg>& m_rhsEval;
805 const BinaryOp& m_functor;
808 StorageIndex m_innerSize;
812 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
813 int(functor_traits<BinaryOp>::Cost),
814 Flags = XprType::Flags
817 explicit sparse_disjunction_evaluator(
const XprType& xpr)
818 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
819 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
820 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
823 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
826 const BinaryOp m_functor;
827 evaluator<LhsArg> m_lhsImpl;
828 evaluator<RhsArg> m_rhsImpl;
829 const XprType& m_expr;
833template <
typename T1,
typename T2,
typename DupFunc,
typename Lhs,
typename Rhs>
834struct binary_evaluator<CwiseBinaryOp<scalar_disjunction_op<DupFunc, T1, T2>, Lhs, Rhs>, IteratorBased, IteratorBased>
835 : sparse_disjunction_evaluator<CwiseBinaryOp<scalar_disjunction_op<DupFunc, T1, T2>, Lhs, Rhs> > {
836 using XprType = CwiseBinaryOp<scalar_disjunction_op<DupFunc, T1, T2>, Lhs, Rhs>;
837 using Base = sparse_disjunction_evaluator<XprType>;
838 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
846template <
typename Derived>
847template <
typename OtherDerived>
849 call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
853template <
typename Derived>
854template <
typename OtherDerived>
856 call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>());
860template <
typename Derived>
861template <
typename OtherDerived>
863 return derived() = derived() - other.derived();
866template <
typename Derived>
867template <
typename OtherDerived>
869 return derived() = derived() + other.derived();
872template <
typename Derived>
873template <
typename OtherDerived>
875 call_assignment_no_alias(derived(), other.derived(),
876 internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
880template <
typename Derived>
881template <
typename OtherDerived>
883 call_assignment_no_alias(derived(), other.derived(),
884 internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>());
888template <
typename Derived>
889template <
typename OtherDerived>
892 return typename CwiseProductDenseReturnType<OtherDerived>::Type(derived(), other.derived());
895template <
typename DenseDerived,
typename SparseDerived>
896EIGEN_STRONG_INLINE
const
898 const DenseDerived,
const SparseDerived>
901 const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
904template <
typename SparseDerived,
typename DenseDerived>
905EIGEN_STRONG_INLINE
const
907 const SparseDerived,
const DenseDerived>
910 const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
913template <
typename DenseDerived,
typename SparseDerived>
914EIGEN_STRONG_INLINE
const
916 const DenseDerived,
const SparseDerived>
919 const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
922template <
typename SparseDerived,
typename DenseDerived>
923EIGEN_STRONG_INLINE
const
925 const SparseDerived,
const DenseDerived>
928 const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:80
Base class for diagonal matrices and expressions.
Definition DiagonalMatrix.h:34
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:31
constexpr const CwiseBinaryOp< internal::scalar_product_op< Derived ::Scalar, OtherDerived ::Scalar >, const Derived, const OtherDerived > cwiseProduct(const Eigen::SparseMatrixBase< OtherDerived > &other) const
Definition SparseMatrixBase.h:25
constexpr unsigned int RowMajorBit
Definition Constants.h:71
Definition EigenBase.h:34
Definition Constants.h:545