MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2014 Gael Guennebaud <[email protected]> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H 00011 #define EIGEN_SPARSE_CWISE_BINARY_OP_H 00012 00013 namespace Eigen { 00014 00015 // Here we have to handle 3 cases: 00016 // 1 - sparse op dense 00017 // 2 - dense op sparse 00018 // 3 - sparse op sparse 00019 // We also need to implement a 4th iterator for: 00020 // 4 - dense op dense 00021 // Finally, we also need to distinguish between the product and other operations : 00022 // configuration returned mode 00023 // 1 - sparse op dense product sparse 00024 // generic dense 00025 // 2 - dense op sparse product sparse 00026 // generic dense 00027 // 3 - sparse op sparse product sparse 00028 // generic sparse 00029 // 4 - dense op dense product dense 00030 // generic dense 00031 00032 template<typename BinaryOp, typename Lhs, typename Rhs> 00033 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse> 00034 : public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > 00035 { 00036 public: 00037 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived; 00038 typedef SparseMatrixBase<Derived> Base; 00039 EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) 00040 CwiseBinaryOpImpl() 00041 { 00042 EIGEN_STATIC_ASSERT(( 00043 (!internal::is_same<typename internal::traits<Lhs>::StorageKind, 00044 typename internal::traits<Rhs>::StorageKind>::value) 00045 || ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))), 00046 THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH); 00047 } 00048 }; 00049 00050 namespace internal { 00051 00052 00053 // Generic "sparse OP sparse" 00054 template<typename XprType> struct binary_sparse_evaluator; 00055 00056 template<typename BinaryOp, typename Lhs, typename Rhs> 00057 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IteratorBased> 00058 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > 00059 { 00060 protected: 00061 typedef typename evaluator<Lhs>::InnerIterator LhsIterator; 00062 typedef typename evaluator<Rhs>::InnerIterator RhsIterator; 00063 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; 00064 typedef typename traits<XprType>::Scalar Scalar; 00065 typedef typename XprType::StorageIndex StorageIndex; 00066 public: 00067 00068 class ReverseInnerIterator; 00069 class InnerIterator 00070 { 00071 public: 00072 00073 EIGEN_STRONG_INLINE InnerIterator(const binary_evaluator& aEval, Index outer) 00074 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor) 00075 { 00076 this->operator++(); 00077 } 00078 00079 EIGEN_STRONG_INLINE InnerIterator& operator++() 00080 { 00081 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index())) 00082 { 00083 m_id = m_lhsIter.index(); 00084 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value()); 00085 ++m_lhsIter; 00086 ++m_rhsIter; 00087 } 00088 else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index()))) 00089 { 00090 m_id = m_lhsIter.index(); 00091 m_value = m_functor(m_lhsIter.value(), Scalar(0)); 00092 ++m_lhsIter; 00093 } 00094 else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index()))) 00095 { 00096 m_id = m_rhsIter.index(); 00097 m_value = m_functor(Scalar(0), m_rhsIter.value()); 00098 ++m_rhsIter; 00099 } 00100 else 00101 { 00102 m_value = 0; // this is to avoid a compilation warning 00103 m_id = -1; 00104 } 00105 return *this; 00106 } 00107 00108 EIGEN_STRONG_INLINE Scalar value() const { return m_value; } 00109 00110 EIGEN_STRONG_INLINE StorageIndex index() const { return m_id; } 00111 EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); } 00112 EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); } 00113 00114 EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; } 00115 00116 protected: 00117 LhsIterator m_lhsIter; 00118 RhsIterator m_rhsIter; 00119 const BinaryOp& m_functor; 00120 Scalar m_value; 00121 StorageIndex m_id; 00122 }; 00123 00124 00125 enum { 00126 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost, 00127 Flags = XprType::Flags 00128 }; 00129 00130 explicit binary_evaluator(const XprType& xpr) 00131 : m_functor(xpr.functor()), 00132 m_lhsImpl(xpr.lhs()), 00133 m_rhsImpl(xpr.rhs()) 00134 { 00135 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost); 00136 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 00137 } 00138 00139 inline Index nonZerosEstimate() const { 00140 return m_lhsImpl.nonZerosEstimate() + m_rhsImpl.nonZerosEstimate(); 00141 } 00142 00143 protected: 00144 const BinaryOp m_functor; 00145 evaluator<Lhs> m_lhsImpl; 00146 evaluator<Rhs> m_rhsImpl; 00147 }; 00148 00149 // dense op sparse 00150 template<typename BinaryOp, typename Lhs, typename Rhs> 00151 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IteratorBased> 00152 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > 00153 { 00154 protected: 00155 typedef typename evaluator<Rhs>::InnerIterator RhsIterator; 00156 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; 00157 typedef typename traits<XprType>::Scalar Scalar; 00158 typedef typename XprType::StorageIndex StorageIndex; 00159 public: 00160 00161 class ReverseInnerIterator; 00162 class InnerIterator 00163 { 00164 enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit }; 00165 public: 00166 00167 EIGEN_STRONG_INLINE InnerIterator(const binary_evaluator& aEval, Index outer) 00168 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor), m_id(-1), m_innerSize(aEval.m_expr.rhs().innerSize()) 00169 { 00170 this->operator++(); 00171 } 00172 00173 EIGEN_STRONG_INLINE InnerIterator& operator++() 00174 { 00175 ++m_id; 00176 if(m_id<m_innerSize) 00177 { 00178 Scalar lhsVal = m_lhsEval.coeff(IsRowMajor?m_rhsIter.outer():m_id, 00179 IsRowMajor?m_id:m_rhsIter.outer()); 00180 if(m_rhsIter && m_rhsIter.index()==m_id) 00181 { 00182 m_value = m_functor(lhsVal, m_rhsIter.value()); 00183 ++m_rhsIter; 00184 } 00185 else 00186 m_value = m_functor(lhsVal, Scalar(0)); 00187 } 00188 00189 return *this; 00190 } 00191 00192 EIGEN_STRONG_INLINE Scalar value() const { return m_value; } 00193 00194 EIGEN_STRONG_INLINE StorageIndex index() const { return m_id; } 00195 EIGEN_STRONG_INLINE Index row() const { return IsRowMajor ? m_rhsIter.outer() : m_id; } 00196 EIGEN_STRONG_INLINE Index col() const { return IsRowMajor ? m_id : m_rhsIter.outer(); } 00197 00198 EIGEN_STRONG_INLINE operator bool() const { return m_id<m_innerSize; } 00199 00200 protected: 00201 const evaluator<Lhs> &m_lhsEval; 00202 RhsIterator m_rhsIter; 00203 const BinaryOp& m_functor; 00204 Scalar m_value; 00205 StorageIndex m_id; 00206 StorageIndex m_innerSize; 00207 }; 00208 00209 00210 enum { 00211 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost, 00212 // Expose storage order of the sparse expression 00213 Flags = (XprType::Flags & ~RowMajorBit) | (int(Rhs::Flags)&RowMajorBit) 00214 }; 00215 00216 explicit binary_evaluator(const XprType& xpr) 00217 : m_functor(xpr.functor()), 00218 m_lhsImpl(xpr.lhs()), 00219 m_rhsImpl(xpr.rhs()), 00220 m_expr(xpr) 00221 { 00222 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost); 00223 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 00224 } 00225 00226 inline Index nonZerosEstimate() const { 00227 return m_expr.size(); 00228 } 00229 00230 protected: 00231 const BinaryOp m_functor; 00232 evaluator<Lhs> m_lhsImpl; 00233 evaluator<Rhs> m_rhsImpl; 00234 const XprType &m_expr; 00235 }; 00236 00237 // sparse op dense 00238 template<typename BinaryOp, typename Lhs, typename Rhs> 00239 struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IteratorBased, IndexBased> 00240 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > 00241 { 00242 protected: 00243 typedef typename evaluator<Lhs>::InnerIterator LhsIterator; 00244 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; 00245 typedef typename traits<XprType>::Scalar Scalar; 00246 typedef typename XprType::StorageIndex StorageIndex; 00247 public: 00248 00249 class ReverseInnerIterator; 00250 class InnerIterator 00251 { 00252 enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit }; 00253 public: 00254 00255 EIGEN_STRONG_INLINE InnerIterator(const binary_evaluator& aEval, Index outer) 00256 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_id(-1), m_innerSize(aEval.m_expr.lhs().innerSize()) 00257 { 00258 this->operator++(); 00259 } 00260 00261 EIGEN_STRONG_INLINE InnerIterator& operator++() 00262 { 00263 ++m_id; 00264 if(m_id<m_innerSize) 00265 { 00266 Scalar rhsVal = m_rhsEval.coeff(IsRowMajor?m_lhsIter.outer():m_id, 00267 IsRowMajor?m_id:m_lhsIter.outer()); 00268 if(m_lhsIter && m_lhsIter.index()==m_id) 00269 { 00270 m_value = m_functor(m_lhsIter.value(), rhsVal); 00271 ++m_lhsIter; 00272 } 00273 else 00274 m_value = m_functor(Scalar(0),rhsVal); 00275 } 00276 00277 return *this; 00278 } 00279 00280 EIGEN_STRONG_INLINE Scalar value() const { return m_value; } 00281 00282 EIGEN_STRONG_INLINE StorageIndex index() const { return m_id; } 00283 EIGEN_STRONG_INLINE Index row() const { return IsRowMajor ? m_lhsIter.outer() : m_id; } 00284 EIGEN_STRONG_INLINE Index col() const { return IsRowMajor ? m_id : m_lhsIter.outer(); } 00285 00286 EIGEN_STRONG_INLINE operator bool() const { return m_id<m_innerSize; } 00287 00288 protected: 00289 LhsIterator m_lhsIter; 00290 const evaluator<Rhs> &m_rhsEval; 00291 const BinaryOp& m_functor; 00292 Scalar m_value; 00293 StorageIndex m_id; 00294 StorageIndex m_innerSize; 00295 }; 00296 00297 00298 enum { 00299 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost, 00300 // Expose storage order of the sparse expression 00301 Flags = (XprType::Flags & ~RowMajorBit) | (int(Lhs::Flags)&RowMajorBit) 00302 }; 00303 00304 explicit binary_evaluator(const XprType& xpr) 00305 : m_functor(xpr.functor()), 00306 m_lhsImpl(xpr.lhs()), 00307 m_rhsImpl(xpr.rhs()), 00308 m_expr(xpr) 00309 { 00310 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost); 00311 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 00312 } 00313 00314 inline Index nonZerosEstimate() const { 00315 return m_expr.size(); 00316 } 00317 00318 protected: 00319 const BinaryOp m_functor; 00320 evaluator<Lhs> m_lhsImpl; 00321 evaluator<Rhs> m_rhsImpl; 00322 const XprType &m_expr; 00323 }; 00324 00325 // "sparse .* sparse" 00326 template<typename T, typename Lhs, typename Rhs> 00327 struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T>, Lhs, Rhs>, IteratorBased, IteratorBased> 00328 : evaluator_base<CwiseBinaryOp<scalar_product_op<T>, Lhs, Rhs> > 00329 { 00330 protected: 00331 typedef scalar_product_op<T> BinaryOp; 00332 typedef typename evaluator<Lhs>::InnerIterator LhsIterator; 00333 typedef typename evaluator<Rhs>::InnerIterator RhsIterator; 00334 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; 00335 typedef typename XprType::StorageIndex StorageIndex; 00336 typedef typename traits<XprType>::Scalar Scalar; 00337 public: 00338 00339 class ReverseInnerIterator; 00340 class InnerIterator 00341 { 00342 public: 00343 00344 EIGEN_STRONG_INLINE InnerIterator(const binary_evaluator& aEval, Index outer) 00345 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor) 00346 { 00347 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) 00348 { 00349 if (m_lhsIter.index() < m_rhsIter.index()) 00350 ++m_lhsIter; 00351 else 00352 ++m_rhsIter; 00353 } 00354 } 00355 00356 EIGEN_STRONG_INLINE InnerIterator& operator++() 00357 { 00358 ++m_lhsIter; 00359 ++m_rhsIter; 00360 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index())) 00361 { 00362 if (m_lhsIter.index() < m_rhsIter.index()) 00363 ++m_lhsIter; 00364 else 00365 ++m_rhsIter; 00366 } 00367 return *this; 00368 } 00369 00370 EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); } 00371 00372 EIGEN_STRONG_INLINE StorageIndex index() const { return m_lhsIter.index(); } 00373 EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); } 00374 EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); } 00375 00376 EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); } 00377 00378 protected: 00379 LhsIterator m_lhsIter; 00380 RhsIterator m_rhsIter; 00381 const BinaryOp& m_functor; 00382 }; 00383 00384 00385 enum { 00386 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost, 00387 Flags = XprType::Flags 00388 }; 00389 00390 explicit binary_evaluator(const XprType& xpr) 00391 : m_functor(xpr.functor()), 00392 m_lhsImpl(xpr.lhs()), 00393 m_rhsImpl(xpr.rhs()) 00394 { 00395 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost); 00396 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 00397 } 00398 00399 inline Index nonZerosEstimate() const { 00400 return (std::min)(m_lhsImpl.nonZerosEstimate(), m_rhsImpl.nonZerosEstimate()); 00401 } 00402 00403 protected: 00404 const BinaryOp m_functor; 00405 evaluator<Lhs> m_lhsImpl; 00406 evaluator<Rhs> m_rhsImpl; 00407 }; 00408 00409 // "dense .* sparse" 00410 template<typename T, typename Lhs, typename Rhs> 00411 struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T>, Lhs, Rhs>, IndexBased, IteratorBased> 00412 : evaluator_base<CwiseBinaryOp<scalar_product_op<T>, Lhs, Rhs> > 00413 { 00414 protected: 00415 typedef scalar_product_op<T> BinaryOp; 00416 typedef evaluator<Lhs> LhsEvaluator; 00417 typedef typename evaluator<Rhs>::InnerIterator RhsIterator; 00418 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; 00419 typedef typename XprType::StorageIndex StorageIndex; 00420 typedef typename traits<XprType>::Scalar Scalar; 00421 public: 00422 00423 class ReverseInnerIterator; 00424 class InnerIterator 00425 { 00426 enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit }; 00427 00428 public: 00429 00430 EIGEN_STRONG_INLINE InnerIterator(const binary_evaluator& aEval, Index outer) 00431 : m_lhsEval(aEval.m_lhsImpl), m_rhsIter(aEval.m_rhsImpl,outer), m_functor(aEval.m_functor), m_outer(outer) 00432 {} 00433 00434 EIGEN_STRONG_INLINE InnerIterator& operator++() 00435 { 00436 ++m_rhsIter; 00437 return *this; 00438 } 00439 00440 EIGEN_STRONG_INLINE Scalar value() const 00441 { return m_functor(m_lhsEval.coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); } 00442 00443 EIGEN_STRONG_INLINE StorageIndex index() const { return m_rhsIter.index(); } 00444 EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); } 00445 EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); } 00446 00447 EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; } 00448 00449 protected: 00450 const LhsEvaluator &m_lhsEval; 00451 RhsIterator m_rhsIter; 00452 const BinaryOp& m_functor; 00453 const Index m_outer; 00454 }; 00455 00456 00457 enum { 00458 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost, 00459 // Expose storage order of the sparse expression 00460 Flags = (XprType::Flags & ~RowMajorBit) | (int(Rhs::Flags)&RowMajorBit) 00461 }; 00462 00463 explicit binary_evaluator(const XprType& xpr) 00464 : m_functor(xpr.functor()), 00465 m_lhsImpl(xpr.lhs()), 00466 m_rhsImpl(xpr.rhs()) 00467 { 00468 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost); 00469 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 00470 } 00471 00472 inline Index nonZerosEstimate() const { 00473 return m_rhsImpl.nonZerosEstimate(); 00474 } 00475 00476 protected: 00477 const BinaryOp m_functor; 00478 evaluator<Lhs> m_lhsImpl; 00479 evaluator<Rhs> m_rhsImpl; 00480 }; 00481 00482 // "sparse .* dense" 00483 template<typename T, typename Lhs, typename Rhs> 00484 struct binary_evaluator<CwiseBinaryOp<scalar_product_op<T>, Lhs, Rhs>, IteratorBased, IndexBased> 00485 : evaluator_base<CwiseBinaryOp<scalar_product_op<T>, Lhs, Rhs> > 00486 { 00487 protected: 00488 typedef scalar_product_op<T> BinaryOp; 00489 typedef typename evaluator<Lhs>::InnerIterator LhsIterator; 00490 typedef evaluator<Rhs> RhsEvaluator; 00491 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; 00492 typedef typename XprType::StorageIndex StorageIndex; 00493 typedef typename traits<XprType>::Scalar Scalar; 00494 public: 00495 00496 class ReverseInnerIterator; 00497 class InnerIterator 00498 { 00499 enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit }; 00500 00501 public: 00502 00503 EIGEN_STRONG_INLINE InnerIterator(const binary_evaluator& aEval, Index outer) 00504 : m_lhsIter(aEval.m_lhsImpl,outer), m_rhsEval(aEval.m_rhsImpl), m_functor(aEval.m_functor), m_outer(outer) 00505 {} 00506 00507 EIGEN_STRONG_INLINE InnerIterator& operator++() 00508 { 00509 ++m_lhsIter; 00510 return *this; 00511 } 00512 00513 EIGEN_STRONG_INLINE Scalar value() const 00514 { return m_functor(m_lhsIter.value(), 00515 m_rhsEval.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); } 00516 00517 EIGEN_STRONG_INLINE StorageIndex index() const { return m_lhsIter.index(); } 00518 EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); } 00519 EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); } 00520 00521 EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; } 00522 00523 protected: 00524 LhsIterator m_lhsIter; 00525 const evaluator<Rhs> &m_rhsEval; 00526 const BinaryOp& m_functor; 00527 const Index m_outer; 00528 }; 00529 00530 00531 enum { 00532 CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost, 00533 // Expose storage order of the sparse expression 00534 Flags = (XprType::Flags & ~RowMajorBit) | (int(Lhs::Flags)&RowMajorBit) 00535 }; 00536 00537 explicit binary_evaluator(const XprType& xpr) 00538 : m_functor(xpr.functor()), 00539 m_lhsImpl(xpr.lhs()), 00540 m_rhsImpl(xpr.rhs()) 00541 { 00542 EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost); 00543 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); 00544 } 00545 00546 inline Index nonZerosEstimate() const { 00547 return m_lhsImpl.nonZerosEstimate(); 00548 } 00549 00550 protected: 00551 const BinaryOp m_functor; 00552 evaluator<Lhs> m_lhsImpl; 00553 evaluator<Rhs> m_rhsImpl; 00554 }; 00555 00556 } 00557 00558 /*************************************************************************** 00559 * Implementation of SparseMatrixBase and SparseCwise functions/operators 00560 ***************************************************************************/ 00561 00562 template<typename Derived> 00563 template<typename OtherDerived> 00564 EIGEN_STRONG_INLINE Derived & 00565 SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other) 00566 { 00567 return derived() = derived() - other.derived(); 00568 } 00569 00570 template<typename Derived> 00571 template<typename OtherDerived> 00572 EIGEN_STRONG_INLINE Derived & 00573 SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other) 00574 { 00575 return derived() = derived() + other.derived(); 00576 } 00577 00578 template<typename Derived> 00579 template<typename OtherDerived> 00580 Derived& SparseMatrixBase<Derived>::operator+=(const DiagonalBase<OtherDerived>& other) 00581 { 00582 call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar>()); 00583 return derived(); 00584 } 00585 00586 template<typename Derived> 00587 template<typename OtherDerived> 00588 Derived& SparseMatrixBase<Derived>::operator-=(const DiagonalBase<OtherDerived>& other) 00589 { 00590 call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar>()); 00591 return derived(); 00592 } 00593 00594 template<typename Derived> 00595 template<typename OtherDerived> 00596 EIGEN_STRONG_INLINE const typename SparseMatrixBase<Derived>::template CwiseProductDenseReturnType<OtherDerived>::Type 00597 SparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) const 00598 { 00599 return typename CwiseProductDenseReturnType<OtherDerived>::Type(derived(), other.derived()); 00600 } 00601 00602 template<typename DenseDerived, typename SparseDerived> 00603 EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar>, const DenseDerived, const SparseDerived> 00604 operator+(const MatrixBase<DenseDerived> &a, const SparseMatrixBase<SparseDerived> &b) 00605 { 00606 return CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar>, const DenseDerived, const SparseDerived>(a.derived(), b.derived()); 00607 } 00608 00609 template<typename SparseDerived, typename DenseDerived> 00610 EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar>, const SparseDerived, const DenseDerived> 00611 operator+(const SparseMatrixBase<SparseDerived> &a, const MatrixBase<DenseDerived> &b) 00612 { 00613 return CwiseBinaryOp<internal::scalar_sum_op<typename DenseDerived::Scalar>, const SparseDerived, const DenseDerived>(a.derived(), b.derived()); 00614 } 00615 00616 template<typename DenseDerived, typename SparseDerived> 00617 EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar>, const DenseDerived, const SparseDerived> 00618 operator-(const MatrixBase<DenseDerived> &a, const SparseMatrixBase<SparseDerived> &b) 00619 { 00620 return CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar>, const DenseDerived, const SparseDerived>(a.derived(), b.derived()); 00621 } 00622 00623 template<typename SparseDerived, typename DenseDerived> 00624 EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar>, const SparseDerived, const DenseDerived> 00625 operator-(const SparseMatrixBase<SparseDerived> &a, const MatrixBase<DenseDerived> &b) 00626 { 00627 return CwiseBinaryOp<internal::scalar_difference_op<typename DenseDerived::Scalar>, const SparseDerived, const DenseDerived>(a.derived(), b.derived()); 00628 } 00629 00630 } // end namespace Eigen 00631 00632 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H