![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-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_SPARSEPRODUCT_H 00011 #define EIGEN_SPARSEPRODUCT_H 00012 00013 namespace Eigen { 00014 00026 template<typename Derived> 00027 template<typename OtherDerived> 00028 inline const Product<Derived,OtherDerived,AliasFreeProduct> 00029 SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const 00030 { 00031 return Product<Derived,OtherDerived,AliasFreeProduct>(derived(), other.derived()); 00032 } 00033 00034 namespace internal { 00035 00036 // sparse * sparse 00037 template<typename Lhs, typename Rhs, int ProductType> 00038 struct generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> 00039 { 00040 template<typename Dest> 00041 static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) 00042 { 00043 evalTo(dst, lhs, rhs, typename evaluator_traits<Dest>::Shape()); 00044 } 00045 00046 // dense += sparse * sparse 00047 template<typename Dest,typename ActualLhs> 00048 static void addTo(Dest& dst, const ActualLhs& lhs, const Rhs& rhs, typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type* = 0) 00049 { 00050 typedef typename nested_eval<ActualLhs,Dynamic>::type LhsNested; 00051 typedef typename nested_eval<Rhs,Dynamic>::type RhsNested; 00052 LhsNested lhsNested(lhs); 00053 RhsNested rhsNested(rhs); 00054 internal::sparse_sparse_to_dense_product_selector<typename remove_all<LhsNested>::type, 00055 typename remove_all<RhsNested>::type, Dest>::run(lhsNested,rhsNested,dst); 00056 } 00057 00058 // dense -= sparse * sparse 00059 template<typename Dest> 00060 static void subTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type* = 0) 00061 { 00062 addTo(dst, -lhs, rhs); 00063 } 00064 00065 protected: 00066 00067 // sparse = sparse * sparse 00068 template<typename Dest> 00069 static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, SparseShape) 00070 { 00071 typedef typename nested_eval<Lhs,Dynamic>::type LhsNested; 00072 typedef typename nested_eval<Rhs,Dynamic>::type RhsNested; 00073 LhsNested lhsNested(lhs); 00074 RhsNested rhsNested(rhs); 00075 internal::conservative_sparse_sparse_product_selector<typename remove_all<LhsNested>::type, 00076 typename remove_all<RhsNested>::type, Dest>::run(lhsNested,rhsNested,dst); 00077 } 00078 00079 // dense = sparse * sparse 00080 template<typename Dest> 00081 static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, DenseShape) 00082 { 00083 dst.setZero(); 00084 addTo(dst, lhs, rhs); 00085 } 00086 }; 00087 00088 // sparse * sparse-triangular 00089 template<typename Lhs, typename Rhs, int ProductType> 00090 struct generic_product_impl<Lhs, Rhs, SparseShape, SparseTriangularShape, ProductType> 00091 : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> 00092 {}; 00093 00094 // sparse-triangular * sparse 00095 template<typename Lhs, typename Rhs, int ProductType> 00096 struct generic_product_impl<Lhs, Rhs, SparseTriangularShape, SparseShape, ProductType> 00097 : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> 00098 {}; 00099 00100 // dense = sparse-product (can be sparse*sparse, sparse*perm, etc.) 00101 template< typename DstXprType, typename Lhs, typename Rhs> 00102 struct Assignment<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::assign_op<typename DstXprType::Scalar,typename Product<Lhs,Rhs,AliasFreeProduct>::Scalar>, Sparse2Dense> 00103 { 00104 typedef Product<Lhs,Rhs,AliasFreeProduct> SrcXprType; 00105 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &) 00106 { 00107 Index dstRows = src.rows(); 00108 Index dstCols = src.cols(); 00109 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) 00110 dst.resize(dstRows, dstCols); 00111 00112 generic_product_impl<Lhs, Rhs>::evalTo(dst,src.lhs(),src.rhs()); 00113 } 00114 }; 00115 00116 // dense += sparse-product (can be sparse*sparse, sparse*perm, etc.) 00117 template< typename DstXprType, typename Lhs, typename Rhs> 00118 struct Assignment<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::add_assign_op<typename DstXprType::Scalar,typename Product<Lhs,Rhs,AliasFreeProduct>::Scalar>, Sparse2Dense> 00119 { 00120 typedef Product<Lhs,Rhs,AliasFreeProduct> SrcXprType; 00121 static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &) 00122 { 00123 generic_product_impl<Lhs, Rhs>::addTo(dst,src.lhs(),src.rhs()); 00124 } 00125 }; 00126 00127 // dense -= sparse-product (can be sparse*sparse, sparse*perm, etc.) 00128 template< typename DstXprType, typename Lhs, typename Rhs> 00129 struct Assignment<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::sub_assign_op<typename DstXprType::Scalar,typename Product<Lhs,Rhs,AliasFreeProduct>::Scalar>, Sparse2Dense> 00130 { 00131 typedef Product<Lhs,Rhs,AliasFreeProduct> SrcXprType; 00132 static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &) 00133 { 00134 generic_product_impl<Lhs, Rhs>::subTo(dst,src.lhs(),src.rhs()); 00135 } 00136 }; 00137 00138 template<typename Lhs, typename Rhs, int Options> 00139 struct unary_evaluator<SparseView<Product<Lhs, Rhs, Options> >, IteratorBased> 00140 : public evaluator<typename Product<Lhs, Rhs, DefaultProduct>::PlainObject> 00141 { 00142 typedef SparseView<Product<Lhs, Rhs, Options> > XprType; 00143 typedef typename XprType::PlainObject PlainObject; 00144 typedef evaluator<PlainObject> Base; 00145 00146 explicit unary_evaluator(const XprType& xpr) 00147 : m_result(xpr.rows(), xpr.cols()) 00148 { 00149 using std::abs; 00150 ::new (static_cast<Base*>(this)) Base(m_result); 00151 typedef typename nested_eval<Lhs,Dynamic>::type LhsNested; 00152 typedef typename nested_eval<Rhs,Dynamic>::type RhsNested; 00153 LhsNested lhsNested(xpr.nestedExpression().lhs()); 00154 RhsNested rhsNested(xpr.nestedExpression().rhs()); 00155 00156 internal::sparse_sparse_product_with_pruning_selector<typename remove_all<LhsNested>::type, 00157 typename remove_all<RhsNested>::type, PlainObject>::run(lhsNested,rhsNested,m_result, 00158 abs(xpr.reference())*xpr.epsilon()); 00159 } 00160 00161 protected: 00162 PlainObject m_result; 00163 }; 00164 00165 } // end namespace internal 00166 00167 } // end namespace Eigen 00168 00169 #endif // EIGEN_SPARSEPRODUCT_H