10#ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
11#define EIGEN_SPARSE_CWISE_BINARY_OP_H
14#include "./InternalHeaderCheck.h"
38template <
typename BinaryOp,
typename Lhs,
typename Rhs>
39class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse> :
public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
41 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
42 typedef SparseMatrixBase<Derived> Base;
43 EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
44 EIGEN_STATIC_ASSERT(((!internal::is_same<
typename internal::traits<Lhs>::StorageKind,
45 typename internal::traits<Rhs>::StorageKind>::value) ||
48 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH)
61template <
typename XprType>
62struct binary_sparse_evaluator;
64template <
typename BinaryOp,
typename Lhs,
typename Rhs>
65struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IteratorBased>
66 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
68 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
69 typedef typename evaluator<Rhs>::InnerIterator RhsIterator;
70 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
71 typedef typename traits<XprType>::Scalar Scalar;
72 typedef typename XprType::StorageIndex StorageIndex;
77 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval, Index outer)
78 : m_lhsIter(aEval.m_lhsImpl, outer),
79 m_rhsIter(aEval.m_rhsImpl, outer),
80 m_functor(aEval.m_functor),
85 EIGEN_STRONG_INLINE InnerIterator& operator++() {
86 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index())) {
87 m_id = m_lhsIter.index();
88 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
91 }
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));
95 }
else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index()))) {
96 m_id = m_rhsIter.index();
97 m_value = m_functor(Scalar(0), m_rhsIter.value());
105 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
107 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
108 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
109 EIGEN_STRONG_INLINE Index row()
const {
return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
110 EIGEN_STRONG_INLINE Index col()
const {
return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
112 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id >= 0; }
115 LhsIterator m_lhsIter;
116 RhsIterator m_rhsIter;
117 const BinaryOp& m_functor;
124 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
125 Flags = XprType::Flags
128 explicit binary_evaluator(
const XprType& xpr) : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
129 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
130 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
133 inline Index nonZerosEstimate()
const {
return m_lhsImpl.nonZerosEstimate() + m_rhsImpl.nonZerosEstimate(); }
136 const BinaryOp m_functor;
137 evaluator<Lhs> m_lhsImpl;
138 evaluator<Rhs> m_rhsImpl;
142template <
typename BinaryOp,
typename Lhs,
typename Rhs>
143struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IteratorBased>
144 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
146 typedef typename evaluator<Rhs>::InnerIterator RhsIterator;
147 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
148 typedef typename traits<XprType>::Scalar Scalar;
149 typedef typename XprType::StorageIndex StorageIndex;
152 class InnerIterator {
153 enum { IsRowMajor = (int(Rhs::Flags) &
RowMajorBit) == RowMajorBit };
156 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval, Index outer)
157 : m_lhsEval(aEval.m_lhsImpl),
158 m_rhsIter(aEval.m_rhsImpl, outer),
159 m_functor(aEval.m_functor),
162 m_innerSize(aEval.m_expr.rhs().innerSize()) {
166 EIGEN_STRONG_INLINE InnerIterator& operator++() {
168 if (m_id < m_innerSize) {
169 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor ? m_rhsIter.outer() : m_id, IsRowMajor ? m_id : m_rhsIter.outer());
170 if (m_rhsIter && m_rhsIter.index() == m_id) {
171 m_value = m_functor(lhsVal, m_rhsIter.value());
174 m_value = m_functor(lhsVal, Scalar(0));
180 EIGEN_STRONG_INLINE Scalar value()
const {
181 eigen_internal_assert(m_id < m_innerSize);
185 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
186 EIGEN_STRONG_INLINE Index outer()
const {
return m_rhsIter.outer(); }
187 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_rhsIter.outer() : m_id; }
188 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_rhsIter.outer(); }
190 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
193 const evaluator<Lhs>& m_lhsEval;
194 RhsIterator m_rhsIter;
195 const BinaryOp& m_functor;
198 StorageIndex m_innerSize;
203 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
204 Flags = XprType::Flags
207 explicit binary_evaluator(
const XprType& xpr)
208 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
209 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
210 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
213 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
216 const BinaryOp m_functor;
217 evaluator<Lhs> m_lhsImpl;
218 evaluator<Rhs> m_rhsImpl;
219 const XprType& m_expr;
223template <
typename BinaryOp,
typename Lhs,
typename Rhs>
224struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IndexBased>
225 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > {
227 typedef typename evaluator<Lhs>::InnerIterator LhsIterator;
228 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
229 typedef typename traits<XprType>::Scalar Scalar;
230 typedef typename XprType::StorageIndex StorageIndex;
233 class InnerIterator {
234 enum { IsRowMajor = (int(Lhs::Flags) &
RowMajorBit) == RowMajorBit };
237 EIGEN_STRONG_INLINE InnerIterator(
const binary_evaluator& aEval, Index outer)
238 : m_lhsIter(aEval.m_lhsImpl, outer),
239 m_rhsEval(aEval.m_rhsImpl),
240 m_functor(aEval.m_functor),
243 m_innerSize(aEval.m_expr.lhs().innerSize()) {
247 EIGEN_STRONG_INLINE InnerIterator& operator++() {
249 if (m_id < m_innerSize) {
250 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor ? m_lhsIter.outer() : m_id, IsRowMajor ? m_id : m_lhsIter.outer());
251 if (m_lhsIter && m_lhsIter.index() == m_id) {
252 m_value = m_functor(m_lhsIter.value(), rhsVal);
255 m_value = m_functor(Scalar(0), rhsVal);
261 EIGEN_STRONG_INLINE Scalar value()
const {
262 eigen_internal_assert(m_id < m_innerSize);
266 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
267 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
268 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_lhsIter.outer() : m_id; }
269 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_lhsIter.outer(); }
271 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
274 LhsIterator m_lhsIter;
275 const evaluator<Rhs>& m_rhsEval;
276 const BinaryOp& m_functor;
279 StorageIndex m_innerSize;
284 int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
285 Flags = XprType::Flags
288 explicit binary_evaluator(
const XprType& xpr)
289 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
290 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
291 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
294 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
297 const BinaryOp m_functor;
298 evaluator<Lhs> m_lhsImpl;
299 evaluator<Rhs> m_rhsImpl;
300 const XprType& m_expr;
303template <typename T, typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
304 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
305 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
306 typename RhsScalar =
typename traits<typename T::Rhs>::Scalar>
307struct sparse_conjunction_evaluator;
310template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
311struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>, IteratorBased, IteratorBased>
312 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> > {
313 typedef CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> XprType;
314 typedef sparse_conjunction_evaluator<XprType> Base;
315 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
318template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
319struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>, IndexBased, IteratorBased>
320 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> > {
321 typedef CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> XprType;
322 typedef sparse_conjunction_evaluator<XprType> Base;
323 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
326template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
327struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs>, IteratorBased, IndexBased>
328 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> > {
329 typedef CwiseBinaryOp<scalar_product_op<T1, T2>, Lhs, Rhs> XprType;
330 typedef sparse_conjunction_evaluator<XprType> Base;
331 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
335template <
typename T1,
typename T2,
typename Lhs,
typename Rhs>
336struct binary_evaluator<CwiseBinaryOp<scalar_quotient_op<T1, T2>, Lhs, Rhs>, IteratorBased, IndexBased>
337 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_quotient_op<T1, T2>, Lhs, Rhs> > {
338 typedef CwiseBinaryOp<scalar_quotient_op<T1, T2>, Lhs, Rhs> XprType;
339 typedef sparse_conjunction_evaluator<XprType> Base;
340 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
344template <
typename Lhs,
typename Rhs>
345struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>, IteratorBased, IteratorBased>
346 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> > {
347 typedef CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> XprType;
348 typedef sparse_conjunction_evaluator<XprType> Base;
349 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
352template <
typename Lhs,
typename Rhs>
353struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>, IndexBased, IteratorBased>
354 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> > {
355 typedef CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> XprType;
356 typedef sparse_conjunction_evaluator<XprType> Base;
357 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
360template <
typename Lhs,
typename Rhs>
361struct binary_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs>, IteratorBased, IndexBased>
362 : sparse_conjunction_evaluator<CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> > {
363 typedef CwiseBinaryOp<scalar_boolean_and_op<bool>, Lhs, Rhs> XprType;
364 typedef sparse_conjunction_evaluator<XprType> Base;
365 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
376template <
typename XprType>
377struct sparse_conjunction_evaluator<XprType, IteratorBased, IteratorBased> : evaluator_base<XprType> {
379 typedef typename XprType::Functor BinaryOp;
380 typedef typename XprType::Lhs LhsArg;
381 typedef typename XprType::Rhs RhsArg;
382 typedef typename evaluator<LhsArg>::InnerIterator LhsIterator;
383 typedef typename evaluator<RhsArg>::InnerIterator RhsIterator;
384 typedef typename XprType::StorageIndex StorageIndex;
385 typedef typename traits<XprType>::Scalar Scalar;
388 class InnerIterator {
390 EIGEN_STRONG_INLINE InnerIterator(
const sparse_conjunction_evaluator& aEval, Index outer)
391 : m_lhsIter(aEval.m_lhsImpl, outer), m_rhsIter(aEval.m_rhsImpl, outer), m_functor(aEval.m_functor) {
392 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) {
393 if (m_lhsIter.index() < m_rhsIter.index())
400 EIGEN_STRONG_INLINE InnerIterator& operator++() {
403 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) {
404 if (m_lhsIter.index() < m_rhsIter.index())
412 EIGEN_STRONG_INLINE Scalar value()
const {
return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
414 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
415 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
416 EIGEN_STRONG_INLINE Index row()
const {
return m_lhsIter.row(); }
417 EIGEN_STRONG_INLINE Index col()
const {
return m_lhsIter.col(); }
419 EIGEN_STRONG_INLINE
operator bool()
const {
return (m_lhsIter && m_rhsIter); }
422 LhsIterator m_lhsIter;
423 RhsIterator m_rhsIter;
424 const BinaryOp& m_functor;
428 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
429 int(functor_traits<BinaryOp>::Cost),
430 Flags = XprType::Flags
433 explicit sparse_conjunction_evaluator(
const XprType& xpr)
434 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
435 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
436 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
439 inline Index nonZerosEstimate()
const {
440 return (std::min)(m_lhsImpl.nonZerosEstimate(), m_rhsImpl.nonZerosEstimate());
444 const BinaryOp m_functor;
445 evaluator<LhsArg> m_lhsImpl;
446 evaluator<RhsArg> m_rhsImpl;
450template <
typename XprType>
451struct sparse_conjunction_evaluator<XprType, IndexBased, IteratorBased> : evaluator_base<XprType> {
453 typedef typename XprType::Functor BinaryOp;
454 typedef typename XprType::Lhs LhsArg;
455 typedef typename XprType::Rhs RhsArg;
456 typedef evaluator<LhsArg> LhsEvaluator;
457 typedef typename evaluator<RhsArg>::InnerIterator RhsIterator;
458 typedef typename XprType::StorageIndex StorageIndex;
459 typedef typename traits<XprType>::Scalar Scalar;
462 class InnerIterator {
463 enum { IsRowMajor = (int(RhsArg::Flags) &
RowMajorBit) == RowMajorBit };
466 EIGEN_STRONG_INLINE InnerIterator(
const sparse_conjunction_evaluator& aEval, Index outer)
467 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl, outer), m_functor(aEval.m_functor), m_outer(outer) {}
469 EIGEN_STRONG_INLINE InnerIterator& operator++() {
474 EIGEN_STRONG_INLINE Scalar value()
const {
476 m_lhsEval.coeff(IsRowMajor ? m_outer : m_rhsIter.index(), IsRowMajor ? m_rhsIter.index() : m_outer),
480 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_rhsIter.index(); }
481 EIGEN_STRONG_INLINE Index outer()
const {
return m_rhsIter.outer(); }
482 EIGEN_STRONG_INLINE Index row()
const {
return m_rhsIter.row(); }
483 EIGEN_STRONG_INLINE Index col()
const {
return m_rhsIter.col(); }
485 EIGEN_STRONG_INLINE
operator bool()
const {
return m_rhsIter; }
488 const LhsEvaluator& m_lhsEval;
489 RhsIterator m_rhsIter;
490 const BinaryOp& m_functor;
495 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
496 int(functor_traits<BinaryOp>::Cost),
497 Flags = XprType::Flags
500 explicit sparse_conjunction_evaluator(
const XprType& xpr)
501 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
502 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
503 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
506 inline Index nonZerosEstimate()
const {
return m_rhsImpl.nonZerosEstimate(); }
509 const BinaryOp m_functor;
510 evaluator<LhsArg> m_lhsImpl;
511 evaluator<RhsArg> m_rhsImpl;
515template <
typename XprType>
516struct sparse_conjunction_evaluator<XprType, IteratorBased, IndexBased> : evaluator_base<XprType> {
518 typedef typename XprType::Functor BinaryOp;
519 typedef typename XprType::Lhs LhsArg;
520 typedef typename XprType::Rhs RhsArg;
521 typedef typename evaluator<LhsArg>::InnerIterator LhsIterator;
522 typedef evaluator<RhsArg> RhsEvaluator;
523 typedef typename XprType::StorageIndex StorageIndex;
524 typedef typename traits<XprType>::Scalar Scalar;
527 class InnerIterator {
528 enum { IsRowMajor = (int(LhsArg::Flags) &
RowMajorBit) == RowMajorBit };
531 EIGEN_STRONG_INLINE InnerIterator(
const sparse_conjunction_evaluator& aEval, Index outer)
532 : m_lhsIter(aEval.m_lhsImpl, outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_outer(outer) {}
534 EIGEN_STRONG_INLINE InnerIterator& operator++() {
539 EIGEN_STRONG_INLINE Scalar value()
const {
540 return m_functor(m_lhsIter.value(), m_rhsEval.coeff(IsRowMajor ? m_outer : m_lhsIter.index(),
541 IsRowMajor ? m_lhsIter.index() : m_outer));
544 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_lhsIter.index(); }
545 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
546 EIGEN_STRONG_INLINE Index row()
const {
return m_lhsIter.row(); }
547 EIGEN_STRONG_INLINE Index col()
const {
return m_lhsIter.col(); }
549 EIGEN_STRONG_INLINE
operator bool()
const {
return m_lhsIter; }
552 LhsIterator m_lhsIter;
553 const evaluator<RhsArg>& m_rhsEval;
554 const BinaryOp& m_functor;
559 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
560 int(functor_traits<BinaryOp>::Cost),
561 Flags = XprType::Flags
564 explicit sparse_conjunction_evaluator(
const XprType& xpr)
565 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
566 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
567 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
570 inline Index nonZerosEstimate()
const {
return m_lhsImpl.nonZerosEstimate(); }
573 const BinaryOp m_functor;
574 evaluator<LhsArg> m_lhsImpl;
575 evaluator<RhsArg> m_rhsImpl;
578template <typename T, typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
579 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
580 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
581 typename RhsScalar =
typename traits<typename T::Rhs>::Scalar>
582struct sparse_disjunction_evaluator;
592template <
typename XprType>
593struct sparse_disjunction_evaluator<XprType, IteratorBased, IteratorBased> : evaluator_base<XprType> {
595 typedef typename XprType::Functor BinaryOp;
596 typedef typename XprType::Lhs LhsArg;
597 typedef typename XprType::Rhs RhsArg;
598 typedef typename evaluator<LhsArg>::InnerIterator LhsIterator;
599 typedef typename evaluator<RhsArg>::InnerIterator RhsIterator;
600 typedef typename XprType::StorageIndex StorageIndex;
601 typedef typename traits<XprType>::Scalar Scalar;
604 class InnerIterator {
606 EIGEN_STRONG_INLINE InnerIterator(
const sparse_disjunction_evaluator& aEval, Index outer)
607 : m_lhsIter(aEval.m_lhsImpl, outer),
608 m_rhsIter(aEval.m_rhsImpl, outer),
609 m_functor(aEval.m_functor),
614 EIGEN_STRONG_INLINE InnerIterator& operator++() {
615 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index())) {
616 m_id = m_lhsIter.index();
617 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
620 }
else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index()))) {
621 m_id = m_lhsIter.index();
622 m_value = m_lhsIter.value();
624 }
else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index()))) {
625 m_id = m_rhsIter.index();
626 m_value = m_rhsIter.value();
634 EIGEN_STRONG_INLINE Scalar value()
const {
return m_value; }
636 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
637 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
638 EIGEN_STRONG_INLINE Index row()
const {
return LhsArg::IsRowMajor ? m_lhsIter.row() : index(); }
639 EIGEN_STRONG_INLINE Index col()
const {
return LhsArg::IsRowMajor ? index() : m_lhsIter.col(); }
641 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id >= 0; }
644 LhsIterator m_lhsIter;
645 RhsIterator m_rhsIter;
646 const BinaryOp& m_functor;
652 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
653 int(functor_traits<BinaryOp>::Cost),
654 Flags = XprType::Flags
657 explicit sparse_disjunction_evaluator(
const XprType& xpr)
658 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) {
659 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
660 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
663 inline Index nonZerosEstimate()
const {
return m_lhsImpl.nonZerosEstimate() + m_rhsImpl.nonZerosEstimate(); }
666 const BinaryOp m_functor;
667 evaluator<LhsArg> m_lhsImpl;
668 evaluator<RhsArg> m_rhsImpl;
672template <
typename XprType>
673struct sparse_disjunction_evaluator<XprType, IndexBased, IteratorBased> : evaluator_base<XprType> {
675 typedef typename XprType::Functor BinaryOp;
676 typedef typename XprType::Lhs LhsArg;
677 typedef typename XprType::Rhs RhsArg;
678 typedef evaluator<LhsArg> LhsEvaluator;
679 typedef typename evaluator<RhsArg>::InnerIterator RhsIterator;
680 typedef typename XprType::StorageIndex StorageIndex;
681 typedef typename traits<XprType>::Scalar Scalar;
684 class InnerIterator {
685 enum { IsRowMajor = (int(RhsArg::Flags) &
RowMajorBit) == RowMajorBit };
688 EIGEN_STRONG_INLINE InnerIterator(
const sparse_disjunction_evaluator& aEval, Index outer)
689 : m_lhsEval(aEval.m_lhsImpl),
690 m_rhsIter(aEval.m_rhsImpl, outer),
691 m_functor(aEval.m_functor),
694 m_innerSize(aEval.m_expr.rhs().innerSize()) {
698 EIGEN_STRONG_INLINE InnerIterator& operator++() {
700 if (m_id < m_innerSize) {
701 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor ? m_rhsIter.outer() : m_id, IsRowMajor ? m_id : m_rhsIter.outer());
702 if (m_rhsIter && m_rhsIter.index() == m_id) {
703 m_value = m_functor(lhsVal, m_rhsIter.value());
712 EIGEN_STRONG_INLINE Scalar value()
const {
713 eigen_internal_assert(m_id < m_innerSize);
717 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
718 EIGEN_STRONG_INLINE Index outer()
const {
return m_rhsIter.outer(); }
719 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_rhsIter.outer() : m_id; }
720 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_rhsIter.outer(); }
722 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
725 const evaluator<LhsArg>& m_lhsEval;
726 RhsIterator m_rhsIter;
727 const BinaryOp& m_functor;
730 StorageIndex m_innerSize;
734 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
735 int(functor_traits<BinaryOp>::Cost),
736 Flags = XprType::Flags
739 explicit sparse_disjunction_evaluator(
const XprType& xpr)
740 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
741 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
742 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
745 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
748 const BinaryOp m_functor;
749 evaluator<LhsArg> m_lhsImpl;
750 evaluator<RhsArg> m_rhsImpl;
751 const XprType& m_expr;
755template <
typename XprType>
756struct sparse_disjunction_evaluator<XprType, IteratorBased, IndexBased> : evaluator_base<XprType> {
758 typedef typename XprType::Functor BinaryOp;
759 typedef typename XprType::Lhs LhsArg;
760 typedef typename XprType::Rhs RhsArg;
761 typedef typename evaluator<LhsArg>::InnerIterator LhsIterator;
762 typedef evaluator<RhsArg> RhsEvaluator;
763 typedef typename XprType::StorageIndex StorageIndex;
764 typedef typename traits<XprType>::Scalar Scalar;
767 class InnerIterator {
768 enum { IsRowMajor = (int(LhsArg::Flags) &
RowMajorBit) == RowMajorBit };
771 EIGEN_STRONG_INLINE InnerIterator(
const sparse_disjunction_evaluator& aEval, Index outer)
772 : m_lhsIter(aEval.m_lhsImpl, outer),
773 m_rhsEval(aEval.m_rhsImpl),
774 m_functor(aEval.m_functor),
777 m_innerSize(aEval.m_expr.lhs().innerSize()) {
781 EIGEN_STRONG_INLINE InnerIterator& operator++() {
783 if (m_id < m_innerSize) {
784 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor ? m_lhsIter.outer() : m_id, IsRowMajor ? m_id : m_lhsIter.outer());
785 if (m_lhsIter && m_lhsIter.index() == m_id) {
786 m_value = m_functor(m_lhsIter.value(), rhsVal);
795 EIGEN_STRONG_INLINE Scalar value()
const {
796 eigen_internal_assert(m_id < m_innerSize);
800 EIGEN_STRONG_INLINE StorageIndex index()
const {
return m_id; }
801 EIGEN_STRONG_INLINE Index outer()
const {
return m_lhsIter.outer(); }
802 EIGEN_STRONG_INLINE Index row()
const {
return IsRowMajor ? m_lhsIter.outer() : m_id; }
803 EIGEN_STRONG_INLINE Index col()
const {
return IsRowMajor ? m_id : m_lhsIter.outer(); }
805 EIGEN_STRONG_INLINE
operator bool()
const {
return m_id < m_innerSize; }
808 LhsIterator m_lhsIter;
809 const evaluator<RhsArg>& m_rhsEval;
810 const BinaryOp& m_functor;
813 StorageIndex m_innerSize;
817 CoeffReadCost = int(evaluator<LhsArg>::CoeffReadCost) + int(evaluator<RhsArg>::CoeffReadCost) +
818 int(functor_traits<BinaryOp>::Cost),
819 Flags = XprType::Flags
822 explicit sparse_disjunction_evaluator(
const XprType& xpr)
823 : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_expr(xpr) {
824 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
825 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
828 inline Index nonZerosEstimate()
const {
return m_expr.size(); }
831 const BinaryOp m_functor;
832 evaluator<LhsArg> m_lhsImpl;
833 evaluator<RhsArg> m_rhsImpl;
834 const XprType& m_expr;
838template <
typename T1,
typename T2,
typename DupFunc,
typename Lhs,
typename Rhs>
839struct binary_evaluator<CwiseBinaryOp<scalar_disjunction_op<DupFunc, T1, T2>, Lhs, Rhs>, IteratorBased, IteratorBased>
840 : sparse_disjunction_evaluator<CwiseBinaryOp<scalar_disjunction_op<DupFunc, T1, T2>, Lhs, Rhs> > {
841 typedef CwiseBinaryOp<scalar_disjunction_op<DupFunc, T1, T2>, Lhs, Rhs> XprType;
842 typedef sparse_disjunction_evaluator<XprType> Base;
843 explicit binary_evaluator(
const XprType& xpr) : Base(xpr) {}
851template <
typename Derived>
852template <
typename OtherDerived>
853Derived& SparseMatrixBase<Derived>::operator+=(
const EigenBase<OtherDerived>& other) {
854 call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
858template <
typename Derived>
859template <
typename OtherDerived>
860Derived& SparseMatrixBase<Derived>::operator-=(
const EigenBase<OtherDerived>& other) {
861 call_assignment(derived(), other.derived(), internal::assign_op<Scalar, typename OtherDerived::Scalar>());
865template <
typename Derived>
866template <
typename OtherDerived>
867EIGEN_STRONG_INLINE Derived& SparseMatrixBase<Derived>::operator-=(
const SparseMatrixBase<OtherDerived>& other) {
868 return derived() = derived() - other.derived();
871template <
typename Derived>
872template <
typename OtherDerived>
873EIGEN_STRONG_INLINE Derived& SparseMatrixBase<Derived>::operator+=(
const SparseMatrixBase<OtherDerived>& other) {
874 return derived() = derived() + other.derived();
877template <
typename Derived>
878template <
typename OtherDerived>
879Derived& SparseMatrixBase<Derived>::operator+=(
const DiagonalBase<OtherDerived>& other) {
880 call_assignment_no_alias(derived(), other.derived(),
881 internal::add_assign_op<Scalar, typename OtherDerived::Scalar>());
885template <
typename Derived>
886template <
typename OtherDerived>
887Derived& SparseMatrixBase<Derived>::operator-=(
const DiagonalBase<OtherDerived>& other) {
888 call_assignment_no_alias(derived(), other.derived(),
889 internal::sub_assign_op<Scalar, typename OtherDerived::Scalar>());
893template <
typename Derived>
894template <
typename OtherDerived>
895EIGEN_STRONG_INLINE
const typename SparseMatrixBase<Derived>::template CwiseProductDenseReturnType<OtherDerived>::Type
896SparseMatrixBase<Derived>::cwiseProduct(
const MatrixBase<OtherDerived>& other)
const {
897 return typename CwiseProductDenseReturnType<OtherDerived>::Type(derived(), other.derived());
900template <
typename DenseDerived,
typename SparseDerived>
901EIGEN_STRONG_INLINE
const
902 CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar, typename SparseDerived::Scalar>,
903 const DenseDerived,
const SparseDerived>
904 operator+(
const MatrixBase<DenseDerived>& a,
const SparseMatrixBase<SparseDerived>& b) {
905 return CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar, typename SparseDerived::Scalar>,
906 const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
909template <
typename SparseDerived,
typename DenseDerived>
910EIGEN_STRONG_INLINE
const
911 CwiseBinaryOp<internal::scalar_sum_op<typename SparseDerived::Scalar, typename DenseDerived::Scalar>,
912 const SparseDerived,
const DenseDerived>
913 operator+(
const SparseMatrixBase<SparseDerived>& a,
const MatrixBase<DenseDerived>& b) {
914 return CwiseBinaryOp<internal::scalar_sum_op<typename SparseDerived::Scalar, typename DenseDerived::Scalar>,
915 const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
918template <
typename DenseDerived,
typename SparseDerived>
919EIGEN_STRONG_INLINE
const
920 CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar, typename SparseDerived::Scalar>,
921 const DenseDerived,
const SparseDerived>
922 operator-(
const MatrixBase<DenseDerived>& a,
const SparseMatrixBase<SparseDerived>& b) {
923 return CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar, typename SparseDerived::Scalar>,
924 const DenseDerived,
const SparseDerived>(a.derived(), b.derived());
927template <
typename SparseDerived,
typename DenseDerived>
928EIGEN_STRONG_INLINE
const
929 CwiseBinaryOp<internal::scalar_difference_op<typename SparseDerived::Scalar, typename DenseDerived::Scalar>,
930 const SparseDerived,
const DenseDerived>
931 operator-(
const SparseMatrixBase<SparseDerived>& a,
const MatrixBase<DenseDerived>& b) {
932 return CwiseBinaryOp<internal::scalar_difference_op<typename SparseDerived::Scalar, typename DenseDerived::Scalar>,
933 const SparseDerived,
const DenseDerived>(a.derived(), b.derived());
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137