10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This file is part of Eigen, a lightweight C++ template library 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// for linear algebra. 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This Source Code Form is subject to the terms of the Mozilla 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Public License v. 2.0. If a copy of the MPL was not distributed 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifndef EIGEN_SPARSEPRODUCT_H 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define EIGEN_SPARSEPRODUCT_H 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace Eigen { 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename Lhs, typename Rhs> 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstruct SparseSparseProductReturnType 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{ 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef typename internal::traits<Lhs>::Scalar Scalar; 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef typename internal::traits<Lhs>::Index Index; 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org enum { 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LhsRowMajor = internal::traits<Lhs>::Flags & RowMajorBit, 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RhsRowMajor = internal::traits<Rhs>::Flags & RowMajorBit, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransposeRhs = (!LhsRowMajor) && RhsRowMajor, 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransposeLhs = LhsRowMajor && (!RhsRowMajor) 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org }; 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef typename internal::conditional<TransposeLhs, 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SparseMatrix<Scalar,0,Index>, 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typename internal::nested<Lhs,Rhs::RowsAtCompileTime>::type>::type LhsNested; 30a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef typename internal::conditional<TransposeRhs, 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SparseMatrix<Scalar,0,Index>, 330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type>::type RhsNested; 340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef SparseSparseProduct<LhsNested, RhsNested> Type; 360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace internal { 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename LhsNested, typename RhsNested> 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstruct traits<SparseSparseProduct<LhsNested, RhsNested> > 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{ 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef MatrixXpr XprKind; 432007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org // clean the nested types: 442007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org typedef typename remove_all<LhsNested>::type _LhsNested; 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef typename remove_all<RhsNested>::type _RhsNested; 462007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org typedef typename _LhsNested::Scalar Scalar; 472007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org typedef typename promote_index_type<typename traits<_LhsNested>::Index, 482007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org typename traits<_RhsNested>::Index>::type Index; 492007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org 502007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org enum { 512007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org LhsCoeffReadCost = _LhsNested::CoeffReadCost, 522007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org RhsCoeffReadCost = _RhsNested::CoeffReadCost, 532007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org LhsFlags = _LhsNested::Flags, 542007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org RhsFlags = _RhsNested::Flags, 552007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RowsAtCompileTime = _LhsNested::RowsAtCompileTime, 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ColsAtCompileTime = _RhsNested::ColsAtCompileTime, 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit), 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org | EvalBeforeAssigningBit 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org | EvalBeforeNestingBit, 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CoeffReadCost = Dynamic 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org }; 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef Sparse StorageKind; 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // end namespace internal 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename LhsNested, typename RhsNested> 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass SparseSparseProduct : internal::no_assignment_operator, 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public SparseMatrixBase<SparseSparseProduct<LhsNested, RhsNested> > 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{ 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef SparseMatrixBase<SparseSparseProduct> Base; 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_DENSE_PUBLIC_INTERFACE(SparseSparseProduct) 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private: 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef typename internal::traits<SparseSparseProduct>::_LhsNested _LhsNested; 91e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org typedef typename internal::traits<SparseSparseProduct>::_RhsNested _RhsNested; 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org template<typename Lhs, typename Rhs> 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs) 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : m_lhs(lhs), m_rhs(rhs), m_tolerance(0), m_conservative(true) 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org init(); 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 102e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org template<typename Lhs, typename Rhs> 1032007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance) 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false) 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 1065aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org init(); 1072007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org } 1085aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org 1095aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) const 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org using std::abs; 1122007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org return SparseSparseProduct(m_lhs,m_rhs,abs(reference)*epsilon); 1132007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org } 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org template<typename Dest> 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void evalTo(Dest& result) const 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 1182007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org if(m_conservative) 1192007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result); 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org else 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance); 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1232007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org 1242007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected: 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void init() 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org eigen_assert(m_lhs.cols() == m_rhs.rows()); 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org enum { 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org || _RhsNested::RowsAtCompileTime==Dynamic 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org || int(_LhsNested::ColsAtCompileTime)==int(_RhsNested::RowsAtCompileTime), 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime, 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested,_RhsNested) 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org }; 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // note to the lost user: 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // * for a dot product use: v1.dot(v2) 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // * for a coeff-wise product use: v1.cwise()*v2 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LhsNested m_lhs; 153e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org RhsNested m_rhs; 154e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org RealScalar m_tolerance; 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool m_conservative; 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// sparse = sparse * sparse 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename Derived> 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename Lhs, typename Rhs> 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orginline Derived& SparseMatrixBase<Derived>::operator=(const SparseSparseProduct<Lhs,Rhs>& product) 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{ 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org product.evalTo(derived()); 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return derived(); 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/** \returns an expression of the product of two sparse matrices. 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * By default a conservative product preserving the symbolic non zeros is performed. 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * The automatic pruning of the small values can be achieved by calling the pruned() function 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * in which case a totally different product algorithm is employed: 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * \code 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * C = (A*B).pruned(); // supress numerical zeros (exact) 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * C = (A*B).pruned(ref); 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * C = (A*B).pruned(ref,epsilon); 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * \endcode 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * where \c ref is a meaningful non zero reference value. 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * */ 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename Derived> 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename OtherDerived> 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orginline const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{ 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // end namespace Eigen 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // EIGEN_SPARSEPRODUCT_H 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org