Eigen  3.3.3
SparseDiagonalProduct.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
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_DIAGONAL_PRODUCT_H
00011 #define EIGEN_SPARSE_DIAGONAL_PRODUCT_H
00012 
00013 namespace Eigen { 
00014 
00015 // The product of a diagonal matrix with a sparse matrix can be easily
00016 // implemented using expression template.
00017 // We have two consider very different cases:
00018 // 1 - diag * row-major sparse
00019 //     => each inner vector <=> scalar * sparse vector product
00020 //     => so we can reuse CwiseUnaryOp::InnerIterator
00021 // 2 - diag * col-major sparse
00022 //     => each inner vector <=> densevector * sparse vector cwise product
00023 //     => again, we can reuse specialization of CwiseBinaryOp::InnerIterator
00024 //        for that particular case
00025 // The two other cases are symmetric.
00026 
00027 namespace internal {
00028 
00029 enum {
00030   SDP_AsScalarProduct,
00031   SDP_AsCwiseProduct
00032 };
00033   
00034 template<typename SparseXprType, typename DiagonalCoeffType, int SDP_Tag>
00035 struct sparse_diagonal_product_evaluator;
00036 
00037 template<typename Lhs, typename Rhs, int ProductTag>
00038 struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, ProductTag, DiagonalShape, SparseShape>
00039   : public sparse_diagonal_product_evaluator<Rhs, typename Lhs::DiagonalVectorType, Rhs::Flags&RowMajorBit?SDP_AsScalarProduct:SDP_AsCwiseProduct>
00040 {
00041   typedef Product<Lhs, Rhs, DefaultProduct> XprType;
00042   enum { CoeffReadCost = HugeCost, Flags = Rhs::Flags&RowMajorBit, Alignment = 0 }; // FIXME CoeffReadCost & Flags
00043   
00044   typedef sparse_diagonal_product_evaluator<Rhs, typename Lhs::DiagonalVectorType, Rhs::Flags&RowMajorBit?SDP_AsScalarProduct:SDP_AsCwiseProduct> Base;
00045   explicit product_evaluator(const XprType& xpr) : Base(xpr.rhs(), xpr.lhs().diagonal()) {}
00046 };
00047 
00048 template<typename Lhs, typename Rhs, int ProductTag>
00049 struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, ProductTag, SparseShape, DiagonalShape>
00050   : public sparse_diagonal_product_evaluator<Lhs, Transpose<const typename Rhs::DiagonalVectorType>, Lhs::Flags&RowMajorBit?SDP_AsCwiseProduct:SDP_AsScalarProduct>
00051 {
00052   typedef Product<Lhs, Rhs, DefaultProduct> XprType;
00053   enum { CoeffReadCost = HugeCost, Flags = Lhs::Flags&RowMajorBit, Alignment = 0 }; // FIXME CoeffReadCost & Flags
00054   
00055   typedef sparse_diagonal_product_evaluator<Lhs, Transpose<const typename Rhs::DiagonalVectorType>, Lhs::Flags&RowMajorBit?SDP_AsCwiseProduct:SDP_AsScalarProduct> Base;
00056   explicit product_evaluator(const XprType& xpr) : Base(xpr.lhs(), xpr.rhs().diagonal().transpose()) {}
00057 };
00058 
00059 template<typename SparseXprType, typename DiagonalCoeffType>
00060 struct sparse_diagonal_product_evaluator<SparseXprType, DiagonalCoeffType, SDP_AsScalarProduct>
00061 {
00062 protected:
00063   typedef typename evaluator<SparseXprType>::InnerIterator SparseXprInnerIterator;
00064   typedef typename SparseXprType::Scalar Scalar;
00065   
00066 public:
00067   class InnerIterator : public SparseXprInnerIterator
00068   {
00069   public:
00070     InnerIterator(const sparse_diagonal_product_evaluator &xprEval, Index outer)
00071       : SparseXprInnerIterator(xprEval.m_sparseXprImpl, outer),
00072         m_coeff(xprEval.m_diagCoeffImpl.coeff(outer))
00073     {}
00074     
00075     EIGEN_STRONG_INLINE Scalar value() const { return m_coeff * SparseXprInnerIterator::value(); }
00076   protected:
00077     typename DiagonalCoeffType::Scalar m_coeff;
00078   };
00079   
00080   sparse_diagonal_product_evaluator(const SparseXprType &sparseXpr, const DiagonalCoeffType &diagCoeff)
00081     : m_sparseXprImpl(sparseXpr), m_diagCoeffImpl(diagCoeff)
00082   {}
00083 
00084   Index nonZerosEstimate() const { return m_sparseXprImpl.nonZerosEstimate(); }
00085     
00086 protected:
00087   evaluator<SparseXprType> m_sparseXprImpl;
00088   evaluator<DiagonalCoeffType> m_diagCoeffImpl;
00089 };
00090 
00091 
00092 template<typename SparseXprType, typename DiagCoeffType>
00093 struct sparse_diagonal_product_evaluator<SparseXprType, DiagCoeffType, SDP_AsCwiseProduct>
00094 {
00095   typedef typename SparseXprType::Scalar Scalar;
00096   typedef typename SparseXprType::StorageIndex StorageIndex;
00097   
00098   typedef typename nested_eval<DiagCoeffType,SparseXprType::IsRowMajor ? SparseXprType::RowsAtCompileTime
00099                                                                        : SparseXprType::ColsAtCompileTime>::type DiagCoeffNested;
00100   
00101   class InnerIterator
00102   {
00103     typedef typename evaluator<SparseXprType>::InnerIterator SparseXprIter;
00104   public:
00105     InnerIterator(const sparse_diagonal_product_evaluator &xprEval, Index outer)
00106       : m_sparseIter(xprEval.m_sparseXprEval, outer), m_diagCoeffNested(xprEval.m_diagCoeffNested)
00107     {}
00108     
00109     inline Scalar value() const { return m_sparseIter.value() * m_diagCoeffNested.coeff(index()); }
00110     inline StorageIndex index() const  { return m_sparseIter.index(); }
00111     inline Index outer() const  { return m_sparseIter.outer(); }
00112     inline Index col() const    { return SparseXprType::IsRowMajor ? m_sparseIter.index() : m_sparseIter.outer(); }
00113     inline Index row() const    { return SparseXprType::IsRowMajor ? m_sparseIter.outer() : m_sparseIter.index(); }
00114     
00115     EIGEN_STRONG_INLINE InnerIterator& operator++() { ++m_sparseIter; return *this; }
00116     inline operator bool() const  { return m_sparseIter; }
00117     
00118   protected:
00119     SparseXprIter m_sparseIter;
00120     DiagCoeffNested m_diagCoeffNested;
00121   };
00122   
00123   sparse_diagonal_product_evaluator(const SparseXprType &sparseXpr, const DiagCoeffType &diagCoeff)
00124     : m_sparseXprEval(sparseXpr), m_diagCoeffNested(diagCoeff)
00125   {}
00126 
00127   Index nonZerosEstimate() const { return m_sparseXprEval.nonZerosEstimate(); }
00128     
00129 protected:
00130   evaluator<SparseXprType> m_sparseXprEval;
00131   DiagCoeffNested m_diagCoeffNested;
00132 };
00133 
00134 } // end namespace internal
00135 
00136 } // end namespace Eigen
00137 
00138 #endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends