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


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