SparseDiagonalProduct.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) 2009 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 template<typename Lhs, typename Rhs>
00030 struct traits<SparseDiagonalProduct<Lhs, Rhs> >
00031 {
00032   typedef typename remove_all<Lhs>::type _Lhs;
00033   typedef typename remove_all<Rhs>::type _Rhs;
00034   typedef typename _Lhs::Scalar Scalar;
00035   typedef typename promote_index_type<typename traits<Lhs>::Index,
00036                                          typename traits<Rhs>::Index>::type Index;
00037   typedef Sparse StorageKind;
00038   typedef MatrixXpr XprKind;
00039   enum {
00040     RowsAtCompileTime = _Lhs::RowsAtCompileTime,
00041     ColsAtCompileTime = _Rhs::ColsAtCompileTime,
00042 
00043     MaxRowsAtCompileTime = _Lhs::MaxRowsAtCompileTime,
00044     MaxColsAtCompileTime = _Rhs::MaxColsAtCompileTime,
00045 
00046     SparseFlags = is_diagonal<_Lhs>::ret ? int(_Rhs::Flags) : int(_Lhs::Flags),
00047     Flags = (SparseFlags&RowMajorBit),
00048     CoeffReadCost = Dynamic
00049   };
00050 };
00051 
00052 enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor};
00053 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode>
00054 class sparse_diagonal_product_inner_iterator_selector;
00055 
00056 } // end namespace internal
00057 
00058 template<typename Lhs, typename Rhs>
00059 class SparseDiagonalProduct
00060   : public SparseMatrixBase<SparseDiagonalProduct<Lhs,Rhs> >,
00061     internal::no_assignment_operator
00062 {
00063     typedef typename Lhs::Nested LhsNested;
00064     typedef typename Rhs::Nested RhsNested;
00065 
00066     typedef typename internal::remove_all<LhsNested>::type _LhsNested;
00067     typedef typename internal::remove_all<RhsNested>::type _RhsNested;
00068 
00069     enum {
00070       LhsMode = internal::is_diagonal<_LhsNested>::ret ? internal::SDP_IsDiagonal
00071               : (_LhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor,
00072       RhsMode = internal::is_diagonal<_RhsNested>::ret ? internal::SDP_IsDiagonal
00073               : (_RhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor
00074     };
00075 
00076   public:
00077 
00078     EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct)
00079 
00080     typedef internal::sparse_diagonal_product_inner_iterator_selector
00081                 <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
00082 
00083     EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
00084       : m_lhs(lhs), m_rhs(rhs)
00085     {
00086       eigen_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
00087     }
00088 
00089     EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
00090     EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
00091 
00092     EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
00093     EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
00094 
00095   protected:
00096     LhsNested m_lhs;
00097     RhsNested m_rhs;
00098 };
00099 
00100 namespace internal {
00101 
00102 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00103 class sparse_diagonal_product_inner_iterator_selector
00104 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor>
00105   : public CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator
00106 {
00107     typedef typename CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator Base;
00108     typedef typename Lhs::Index Index;
00109   public:
00110     inline sparse_diagonal_product_inner_iterator_selector(
00111               const SparseDiagonalProductType& expr, Index outer)
00112       : Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer)
00113     {}
00114 };
00115 
00116 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00117 class sparse_diagonal_product_inner_iterator_selector
00118 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
00119   : public CwiseBinaryOp<
00120       scalar_product_op<typename Lhs::Scalar>,
00121       SparseInnerVectorSet<Rhs,1>,
00122       typename Lhs::DiagonalVectorType>::InnerIterator
00123 {
00124     typedef typename CwiseBinaryOp<
00125       scalar_product_op<typename Lhs::Scalar>,
00126       SparseInnerVectorSet<Rhs,1>,
00127       typename Lhs::DiagonalVectorType>::InnerIterator Base;
00128     typedef typename Lhs::Index Index;
00129     Index m_outer;
00130   public:
00131     inline sparse_diagonal_product_inner_iterator_selector(
00132               const SparseDiagonalProductType& expr, Index outer)
00133       : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0), m_outer(outer)
00134     {}
00135     
00136     inline Index outer() const { return m_outer; }
00137     inline Index col() const { return m_outer; }
00138 };
00139 
00140 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00141 class sparse_diagonal_product_inner_iterator_selector
00142 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal>
00143   : public CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator
00144 {
00145     typedef typename CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator Base;
00146     typedef typename Lhs::Index Index;
00147   public:
00148     inline sparse_diagonal_product_inner_iterator_selector(
00149               const SparseDiagonalProductType& expr, Index outer)
00150       : Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer)
00151     {}
00152 };
00153 
00154 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00155 class sparse_diagonal_product_inner_iterator_selector
00156 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
00157   : public CwiseBinaryOp<
00158       scalar_product_op<typename Rhs::Scalar>,
00159       SparseInnerVectorSet<Lhs,1>,
00160       Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
00161 {
00162     typedef typename CwiseBinaryOp<
00163       scalar_product_op<typename Rhs::Scalar>,
00164       SparseInnerVectorSet<Lhs,1>,
00165       Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
00166     typedef typename Lhs::Index Index;
00167     Index m_outer;
00168   public:
00169     inline sparse_diagonal_product_inner_iterator_selector(
00170               const SparseDiagonalProductType& expr, Index outer)
00171       : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0), m_outer(outer)
00172     {}
00173     
00174     inline Index outer() const { return m_outer; }
00175     inline Index row() const { return m_outer; }
00176 };
00177 
00178 } // end namespace internal
00179 
00180 // SparseMatrixBase functions
00181 
00182 template<typename Derived>
00183 template<typename OtherDerived>
00184 const SparseDiagonalProduct<Derived,OtherDerived>
00185 SparseMatrixBase<Derived>::operator*(const DiagonalBase<OtherDerived> &other) const
00186 {
00187   return SparseDiagonalProduct<Derived,OtherDerived>(this->derived(), other.derived());
00188 }
00189 
00190 } // end namespace Eigen
00191 
00192 #endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H


win_eigen
Author(s): Daniel Stonier
autogenerated on Mon Oct 6 2014 12:26:17