00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
00026 #define EIGEN_SPARSE_CWISE_BINARY_OP_H
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 namespace internal {
00046
00047 template<> struct promote_storage_type<Dense,Sparse>
00048 { typedef Sparse ret; };
00049
00050 template<> struct promote_storage_type<Sparse,Dense>
00051 { typedef Sparse ret; };
00052
00053 template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived,
00054 typename _LhsStorageMode = typename traits<Lhs>::StorageKind,
00055 typename _RhsStorageMode = typename traits<Rhs>::StorageKind>
00056 class sparse_cwise_binary_op_inner_iterator_selector;
00057
00058 }
00059
00060 template<typename BinaryOp, typename Lhs, typename Rhs>
00061 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
00062 : public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
00063 {
00064 public:
00065 class InnerIterator;
00066 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
00067 EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
00068 };
00069
00070 template<typename BinaryOp, typename Lhs, typename Rhs>
00071 class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
00072 : public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator>
00073 {
00074 public:
00075 typedef typename Lhs::Index Index;
00076 typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
00077 BinaryOp,Lhs,Rhs, InnerIterator> Base;
00078
00079 EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer)
00080 : Base(binOp.derived(),outer)
00081 {}
00082 };
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 namespace internal {
00094
00095
00096 template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived>
00097 class sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
00098 {
00099 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
00100 typedef typename traits<CwiseBinaryXpr>::Scalar Scalar;
00101 typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
00102 typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
00103 typedef typename _LhsNested::InnerIterator LhsIterator;
00104 typedef typename _RhsNested::InnerIterator RhsIterator;
00105 typedef typename Lhs::Index Index;
00106
00107 public:
00108
00109 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
00110 : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
00111 {
00112 this->operator++();
00113 }
00114
00115 EIGEN_STRONG_INLINE Derived& operator++()
00116 {
00117 if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
00118 {
00119 m_id = m_lhsIter.index();
00120 m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
00121 ++m_lhsIter;
00122 ++m_rhsIter;
00123 }
00124 else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
00125 {
00126 m_id = m_lhsIter.index();
00127 m_value = m_functor(m_lhsIter.value(), Scalar(0));
00128 ++m_lhsIter;
00129 }
00130 else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
00131 {
00132 m_id = m_rhsIter.index();
00133 m_value = m_functor(Scalar(0), m_rhsIter.value());
00134 ++m_rhsIter;
00135 }
00136 else
00137 {
00138 m_value = 0;
00139 m_id = -1;
00140 }
00141 return *static_cast<Derived*>(this);
00142 }
00143
00144 EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
00145
00146 EIGEN_STRONG_INLINE Index index() const { return m_id; }
00147 EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
00148 EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
00149
00150 EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; }
00151
00152 protected:
00153 LhsIterator m_lhsIter;
00154 RhsIterator m_rhsIter;
00155 const BinaryOp& m_functor;
00156 Scalar m_value;
00157 Index m_id;
00158 };
00159
00160
00161 template<typename T, typename Lhs, typename Rhs, typename Derived>
00162 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
00163 {
00164 typedef scalar_product_op<T> BinaryFunc;
00165 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
00166 typedef typename CwiseBinaryXpr::Scalar Scalar;
00167 typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
00168 typedef typename _LhsNested::InnerIterator LhsIterator;
00169 typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
00170 typedef typename _RhsNested::InnerIterator RhsIterator;
00171 typedef typename Lhs::Index Index;
00172 public:
00173
00174 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
00175 : m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
00176 {
00177 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
00178 {
00179 if (m_lhsIter.index() < m_rhsIter.index())
00180 ++m_lhsIter;
00181 else
00182 ++m_rhsIter;
00183 }
00184 }
00185
00186 EIGEN_STRONG_INLINE Derived& operator++()
00187 {
00188 ++m_lhsIter;
00189 ++m_rhsIter;
00190 while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
00191 {
00192 if (m_lhsIter.index() < m_rhsIter.index())
00193 ++m_lhsIter;
00194 else
00195 ++m_rhsIter;
00196 }
00197 return *static_cast<Derived*>(this);
00198 }
00199
00200 EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
00201
00202 EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
00203 EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
00204 EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
00205
00206 EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); }
00207
00208 protected:
00209 LhsIterator m_lhsIter;
00210 RhsIterator m_rhsIter;
00211 const BinaryFunc& m_functor;
00212 };
00213
00214
00215 template<typename T, typename Lhs, typename Rhs, typename Derived>
00216 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
00217 {
00218 typedef scalar_product_op<T> BinaryFunc;
00219 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
00220 typedef typename CwiseBinaryXpr::Scalar Scalar;
00221 typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
00222 typedef typename traits<CwiseBinaryXpr>::RhsNested RhsNested;
00223 typedef typename _LhsNested::InnerIterator LhsIterator;
00224 typedef typename Lhs::Index Index;
00225 enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit };
00226 public:
00227
00228 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
00229 : m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),outer), m_functor(xpr.functor()), m_outer(outer)
00230 {}
00231
00232 EIGEN_STRONG_INLINE Derived& operator++()
00233 {
00234 ++m_lhsIter;
00235 return *static_cast<Derived*>(this);
00236 }
00237
00238 EIGEN_STRONG_INLINE Scalar value() const
00239 { return m_functor(m_lhsIter.value(),
00240 m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
00241
00242 EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
00243 EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
00244 EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
00245
00246 EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; }
00247
00248 protected:
00249 const RhsNested m_rhs;
00250 LhsIterator m_lhsIter;
00251 const BinaryFunc m_functor;
00252 const Index m_outer;
00253 };
00254
00255
00256 template<typename T, typename Lhs, typename Rhs, typename Derived>
00257 class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
00258 {
00259 typedef scalar_product_op<T> BinaryFunc;
00260 typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
00261 typedef typename CwiseBinaryXpr::Scalar Scalar;
00262 typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
00263 typedef typename _RhsNested::InnerIterator RhsIterator;
00264 typedef typename Lhs::Index Index;
00265
00266 enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit };
00267 public:
00268
00269 EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
00270 : m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
00271 {}
00272
00273 EIGEN_STRONG_INLINE Derived& operator++()
00274 {
00275 ++m_rhsIter;
00276 return *static_cast<Derived*>(this);
00277 }
00278
00279 EIGEN_STRONG_INLINE Scalar value() const
00280 { return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
00281
00282 EIGEN_STRONG_INLINE Index index() const { return m_rhsIter.index(); }
00283 EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); }
00284 EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); }
00285
00286 EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; }
00287
00288 protected:
00289 const CwiseBinaryXpr& m_xpr;
00290 RhsIterator m_rhsIter;
00291 const BinaryFunc& m_functor;
00292 const Index m_outer;
00293 };
00294
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 template<typename Derived>
00312 template<typename OtherDerived>
00313 EIGEN_STRONG_INLINE Derived &
00314 SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &other)
00315 {
00316 return *this = derived() - other.derived();
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 template<typename Derived>
00328 template<typename OtherDerived>
00329 EIGEN_STRONG_INLINE Derived &
00330 SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& other)
00331 {
00332 return *this = derived() + other.derived();
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 template<typename Derived>
00344 template<typename OtherDerived>
00345 EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
00346 SparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) const
00347 {
00348 return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived());
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H