diff options
-rw-r--r-- | Eigen/src/SparseCore/SparseDenseProduct.h | 23 | ||||
-rw-r--r-- | test/sparse_product.cpp | 7 |
2 files changed, 20 insertions, 10 deletions
diff --git a/Eigen/src/SparseCore/SparseDenseProduct.h b/Eigen/src/SparseCore/SparseDenseProduct.h index edb9d5998..731d40f29 100644 --- a/Eigen/src/SparseCore/SparseDenseProduct.h +++ b/Eigen/src/SparseCore/SparseDenseProduct.h @@ -41,7 +41,7 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t typename Res::Scalar tmp(0); for(LhsInnerIterator it(lhsEval,j); it ;++it) tmp += it.value() * rhs.coeff(it.index(),c); - res.coeffRef(j,c) = alpha * tmp; + res.coeffRef(j,c) += alpha * tmp; } } } @@ -128,17 +128,18 @@ namespace internal { template<typename Lhs, typename Rhs, int ProductType> struct generic_product_impl<Lhs, Rhs, SparseShape, DenseShape, ProductType> + : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,SparseShape,DenseShape,ProductType> > { + typedef typename Product<Lhs,Rhs>::Scalar Scalar; + template<typename Dest> - static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) + static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) { typedef typename nested_eval<Lhs,Dynamic>::type LhsNested; typedef typename nested_eval<Rhs,Dynamic>::type RhsNested; LhsNested lhsNested(lhs); RhsNested rhsNested(rhs); - - dst.setZero(); - internal::sparse_time_dense_product(lhsNested, rhsNested, dst, typename Dest::Scalar(1)); + internal::sparse_time_dense_product(lhsNested, rhsNested, dst, alpha); } }; @@ -149,19 +150,21 @@ struct generic_product_impl<Lhs, Rhs, SparseTriangularShape, DenseShape, Product template<typename Lhs, typename Rhs, int ProductType> struct generic_product_impl<Lhs, Rhs, DenseShape, SparseShape, ProductType> + : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,SparseShape,ProductType> > { - template<typename Dest> - static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) + typedef typename Product<Lhs,Rhs>::Scalar Scalar; + + template<typename Dst> + static void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) { typedef typename nested_eval<Lhs,Dynamic>::type LhsNested; typedef typename nested_eval<Rhs,Dynamic>::type RhsNested; LhsNested lhsNested(lhs); RhsNested rhsNested(rhs); - dst.setZero(); // transpose everything - Transpose<Dest> dstT(dst); - internal::sparse_time_dense_product(rhsNested.transpose(), lhsNested.transpose(), dstT, typename Dest::Scalar(1)); + Transpose<Dst> dstT(dst); + internal::sparse_time_dense_product(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha); } }; diff --git a/test/sparse_product.cpp b/test/sparse_product.cpp index 201d5bc49..f1e5b8e4c 100644 --- a/test/sparse_product.cpp +++ b/test/sparse_product.cpp @@ -88,6 +88,10 @@ template<typename SparseMatrixType> void sparse_product() VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3); VERIFY_IS_APPROX(dm4=dm4+m2*refMat3, refMat4=refMat4+refMat2*refMat3); + VERIFY_IS_APPROX(dm4+=m2*refMat3, refMat4+=refMat2*refMat3); + VERIFY_IS_APPROX(dm4-=m2*refMat3, refMat4-=refMat2*refMat3); + VERIFY_IS_APPROX(dm4.noalias()+=m2*refMat3, refMat4+=refMat2*refMat3); + VERIFY_IS_APPROX(dm4.noalias()-=m2*refMat3, refMat4-=refMat2*refMat3); VERIFY_IS_APPROX(dm4=m2*(refMat3+refMat3), refMat4=refMat2*(refMat3+refMat3)); VERIFY_IS_APPROX(dm4=m2t.transpose()*(refMat3+refMat5)*0.5, refMat4=refMat2t.transpose()*(refMat3+refMat5)*0.5); @@ -101,6 +105,9 @@ template<typename SparseMatrixType> void sparse_product() VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3); VERIFY_IS_APPROX(dm4=dm4+refMat2*m3, refMat4=refMat4+refMat2*refMat3); VERIFY_IS_APPROX(dm4+=refMat2*m3, refMat4+=refMat2*refMat3); + VERIFY_IS_APPROX(dm4-=refMat2*m3, refMat4-=refMat2*refMat3); + VERIFY_IS_APPROX(dm4.noalias()+=refMat2*m3, refMat4+=refMat2*refMat3); + VERIFY_IS_APPROX(dm4.noalias()-=refMat2*m3, refMat4-=refMat2*refMat3); VERIFY_IS_APPROX(dm4=refMat2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose()); VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3); VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose()); |