MOAB  4.9.3pre
SparseCwiseBinaryOp.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines