1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SPARSE_DIAGONAL_PRODUCT_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// The product of a diagonal matrix with a sparse matrix can be easily
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// implemented using expression template.
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// We have two consider very different cases:
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 1 - diag * row-major sparse
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     => each inner vector <=> scalar * sparse vector product
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     => so we can reuse CwiseUnaryOp::InnerIterator
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 2 - diag * col-major sparse
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     => each inner vector <=> densevector * sparse vector cwise product
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//     => again, we can reuse specialization of CwiseBinaryOp::InnerIterator
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//        for that particular case
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// The two other cases are symmetric.
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs>
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<SparseDiagonalProduct<Lhs, Rhs> >
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename remove_all<Lhs>::type _Lhs;
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename remove_all<Rhs>::type _Rhs;
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename _Lhs::Scalar Scalar;
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename promote_index_type<typename traits<Lhs>::Index,
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                         typename traits<Rhs>::Index>::type Index;
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Sparse StorageKind;
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef MatrixXpr XprKind;
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RowsAtCompileTime = _Lhs::RowsAtCompileTime,
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ColsAtCompileTime = _Rhs::ColsAtCompileTime,
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MaxRowsAtCompileTime = _Lhs::MaxRowsAtCompileTime,
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MaxColsAtCompileTime = _Rhs::MaxColsAtCompileTime,
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SparseFlags = is_diagonal<_Lhs>::ret ? int(_Rhs::Flags) : int(_Lhs::Flags),
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Flags = (SparseFlags&RowMajorBit),
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CoeffReadCost = Dynamic
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathenum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor};
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode>
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_diagonal_product_inner_iterator_selector;
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs>
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass SparseDiagonalProduct
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public SparseMatrixBase<SparseDiagonalProduct<Lhs,Rhs> >,
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::no_assignment_operator
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Nested LhsNested;
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Rhs::Nested RhsNested;
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::remove_all<LhsNested>::type _LhsNested;
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::remove_all<RhsNested>::type _RhsNested;
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      LhsMode = internal::is_diagonal<_LhsNested>::ret ? internal::SDP_IsDiagonal
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : (_LhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor,
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      RhsMode = internal::is_diagonal<_RhsNested>::ret ? internal::SDP_IsDiagonal
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : (_RhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct)
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef internal::sparse_diagonal_product_inner_iterator_selector
817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                      <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // We do not want ReverseInnerIterator for diagonal-sparse products,
847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    // but this dummy declaration is needed to make diag * sparse * diag compile.
857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    class ReverseInnerIterator;
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : m_lhs(lhs), m_rhs(rhs)
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    LhsNested m_lhs;
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsNested m_rhs;
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_diagonal_product_inner_iterator_selector
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor>
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator Base;
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline sparse_diagonal_product_inner_iterator_selector(
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              const SparseDiagonalProductType& expr, Index outer)
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer)
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_diagonal_product_inner_iterator_selector
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public CwiseBinaryOp<
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      scalar_product_op<typename Lhs::Scalar>,
1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const typename Rhs::ConstInnerVectorReturnType,
1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const typename Lhs::DiagonalVectorType>::InnerIterator
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryOp<
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      scalar_product_op<typename Lhs::Scalar>,
1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const typename Rhs::ConstInnerVectorReturnType,
1317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const typename Lhs::DiagonalVectorType>::InnerIterator Base;
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
1337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Index m_outer;
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline sparse_diagonal_product_inner_iterator_selector(
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              const SparseDiagonalProductType& expr, Index outer)
1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0), m_outer(outer)
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
1397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    inline Index outer() const { return m_outer; }
1417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    inline Index col() const { return m_outer; }
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_diagonal_product_inner_iterator_selector
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal>
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator Base;
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline sparse_diagonal_product_inner_iterator_selector(
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              const SparseDiagonalProductType& expr, Index outer)
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      : Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer)
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass sparse_diagonal_product_inner_iterator_selector
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public CwiseBinaryOp<
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      scalar_product_op<typename Rhs::Scalar>,
1637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const typename Lhs::ConstInnerVectorReturnType,
1647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename CwiseBinaryOp<
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      scalar_product_op<typename Rhs::Scalar>,
1687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const typename Lhs::ConstInnerVectorReturnType,
1697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename Lhs::Index Index;
1717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    Index m_outer;
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline sparse_diagonal_product_inner_iterator_selector(
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              const SparseDiagonalProductType& expr, Index outer)
1757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0), m_outer(outer)
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
1777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    inline Index outer() const { return m_outer; }
1797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    inline Index row() const { return m_outer; }
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// SparseMatrixBase functions
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathconst SparseDiagonalProduct<Derived,OtherDerived>
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::operator*(const DiagonalBase<OtherDerived> &other) const
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return SparseDiagonalProduct<Derived,OtherDerived>(this->derived(), other.derived());
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H
197