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 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H
00026 #define EIGEN_SPARSE_CWISE_BINARY_OP_H
00027 
00028 // Here we have to handle 3 cases:
00029 //  1 - sparse op dense
00030 //  2 - dense op sparse
00031 //  3 - sparse op sparse
00032 // We also need to implement a 4th iterator for:
00033 //  4 - dense op dense
00034 // Finally, we also need to distinguish between the product and other operations :
00035 //                configuration      returned mode
00036 //  1 - sparse op dense    product      sparse
00037 //                         generic      dense
00038 //  2 - dense op sparse    product      sparse
00039 //                         generic      dense
00040 //  3 - sparse op sparse   product      sparse
00041 //                         generic      sparse
00042 //  4 - dense op dense     product      dense
00043 //                         generic      dense
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 } // end namespace internal
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 * Implementation of inner-iterators
00086 ***************************************************************************/
00087 
00088 // template<typename T> struct internal::func_is_conjunction { enum { ret = false }; };
00089 // template<typename T> struct internal::func_is_conjunction<internal::scalar_product_op<T> > { enum { ret = true }; };
00090 
00091 // TODO generalize the internal::scalar_product_op specialization to all conjunctions if any !
00092 
00093 namespace internal {
00094 
00095 // sparse - sparse  (generic)
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; // this is to avoid a compilation warning
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 // sparse - sparse  (product)
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 // sparse - dense  (product)
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 // sparse - dense  (product)
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 } // end namespace internal
00296 
00297 /***************************************************************************
00298 * Implementation of SparseMatrixBase and SparseCwise functions/operators
00299 ***************************************************************************/
00300 
00301 // template<typename Derived>
00302 // template<typename OtherDerived>
00303 // EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_difference_op<typename internal::traits<Derived>::Scalar>,
00304 //                                  Derived, OtherDerived>
00305 // SparseMatrixBase<Derived>::operator-(const SparseMatrixBase<OtherDerived> &other) const
00306 // {
00307 //   return CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
00308 //                        Derived, OtherDerived>(derived(), other.derived());
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 // template<typename Derived>
00320 // template<typename OtherDerived>
00321 // EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_sum_op<typename internal::traits<Derived>::Scalar>, Derived, OtherDerived>
00322 // SparseMatrixBase<Derived>::operator+(const SparseMatrixBase<OtherDerived> &other) const
00323 // {
00324 //   return CwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived());
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 // template<typename ExpressionType>
00336 // template<typename OtherDerived>
00337 // EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
00338 // SparseCwise<ExpressionType>::operator*(const SparseMatrixBase<OtherDerived> &other) const
00339 // {
00340 //   return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
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 // template<typename ExpressionType>
00352 // template<typename OtherDerived>
00353 // EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)
00354 // SparseCwise<ExpressionType>::operator/(const SparseMatrixBase<OtherDerived> &other) const
00355 // {
00356 //   return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived());
00357 // }
00358 //
00359 // template<typename ExpressionType>
00360 // template<typename OtherDerived>
00361 // EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)
00362 // SparseCwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
00363 // {
00364 //   return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)(_expression(), other.derived());
00365 // }
00366 
00367 // template<typename ExpressionType>
00368 // template<typename OtherDerived>
00369 // inline ExpressionType& SparseCwise<ExpressionType>::operator*=(const SparseMatrixBase<OtherDerived> &other)
00370 // {
00371 //   return m_matrix.const_cast_derived() = _expression() * other.derived();
00372 // }
00373 
00374 
00375 #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:46