mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-30 16:52:01 +08:00
Add direct assignment of products
This commit is contained in:
parent
7f917807c6
commit
34ca81b1bf
@ -679,6 +679,11 @@ void call_assignment(const NoAlias<Dst,StorageBase>& dst, const Src& src, const
|
|||||||
{
|
{
|
||||||
Assignment<Dst,Src,Func>::run(dst.expression(), src, func);
|
Assignment<Dst,Src,Func>::run(dst.expression(), src, func);
|
||||||
}
|
}
|
||||||
|
template<typename Dst, template <typename> class StorageBase, typename Src, typename Func>
|
||||||
|
void call_assignment(NoAlias<Dst,StorageBase>& dst, const Src& src, const Func& func)
|
||||||
|
{
|
||||||
|
Assignment<Dst,Src,Func>::run(dst.expression(), src, func);
|
||||||
|
}
|
||||||
|
|
||||||
// Generic Dense to Dense assignment
|
// Generic Dense to Dense assignment
|
||||||
template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
|
template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
|
||||||
|
@ -45,6 +45,12 @@ struct evaluator<Product<Lhs, Rhs, Options> >
|
|||||||
template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value>
|
template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value>
|
||||||
struct dense_product_impl;
|
struct dense_product_impl;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
struct evaluator_traits<Product<Lhs, Rhs, DefaultProduct> >
|
||||||
|
: evaluator_traits_base<Product<Lhs, Rhs, DefaultProduct> >
|
||||||
|
{
|
||||||
|
enum { AssumeAliasing = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
// The evaluator for default dense products creates a temporary and call dense_product_impl
|
// The evaluator for default dense products creates a temporary and call dense_product_impl
|
||||||
template<typename Lhs, typename Rhs, int ProductTag>
|
template<typename Lhs, typename Rhs, int ProductTag>
|
||||||
@ -58,9 +64,7 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, ProductTag, DenseSha
|
|||||||
product_evaluator(const XprType& xpr)
|
product_evaluator(const XprType& xpr)
|
||||||
: m_result(xpr.rows(), xpr.cols())
|
: m_result(xpr.rows(), xpr.cols())
|
||||||
{
|
{
|
||||||
|
|
||||||
::new (static_cast<Base*>(this)) Base(m_result);
|
::new (static_cast<Base*>(this)) Base(m_result);
|
||||||
|
|
||||||
dense_product_impl<Lhs, Rhs>::evalTo(m_result, xpr.lhs(), xpr.rhs());
|
dense_product_impl<Lhs, Rhs>::evalTo(m_result, xpr.lhs(), xpr.rhs());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +72,38 @@ protected:
|
|||||||
PlainObject m_result;
|
PlainObject m_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Dense = Product
|
||||||
|
template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
||||||
|
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
|
{
|
||||||
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
|
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
|
||||||
|
{
|
||||||
|
dense_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Dense += Product
|
||||||
|
template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
||||||
|
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
|
{
|
||||||
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
|
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar> &)
|
||||||
|
{
|
||||||
|
dense_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Dense -= Product
|
||||||
|
template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
|
||||||
|
struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
|
{
|
||||||
|
typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
|
||||||
|
static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar> &)
|
||||||
|
{
|
||||||
|
dense_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
template<typename Lhs, typename Rhs>
|
||||||
struct dense_product_impl<Lhs,Rhs,InnerProduct>
|
struct dense_product_impl<Lhs,Rhs,InnerProduct>
|
||||||
|
@ -47,14 +47,14 @@ namespace Eigen {
|
|||||||
void add_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
void add_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
||||||
{
|
{
|
||||||
typedef typename DstXprType::Scalar Scalar;
|
typedef typename DstXprType::Scalar Scalar;
|
||||||
call_assignment(dst.const_cast_derived(), src.derived(), internal::add_assign_op<Scalar>());
|
call_assignment(const_cast<DstXprType&>(dst), src.derived(), internal::add_assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename DstXprType, typename SrcXprType>
|
template<typename DstXprType, typename SrcXprType>
|
||||||
void subtract_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
void subtract_assign_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
||||||
{
|
{
|
||||||
typedef typename DstXprType::Scalar Scalar;
|
typedef typename DstXprType::Scalar Scalar;
|
||||||
call_assignment(dst.const_cast_derived(), src.derived(), internal::sub_assign_op<Scalar>());
|
call_assignment(const_cast<DstXprType&>(dst), src.derived(), internal::sub_assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename DstXprType, typename SrcXprType>
|
template<typename DstXprType, typename SrcXprType>
|
||||||
@ -151,6 +151,17 @@ void test_evaluators()
|
|||||||
c = a*a;
|
c = a*a;
|
||||||
copy_using_evaluator(a, prod(a,a));
|
copy_using_evaluator(a, prod(a,a));
|
||||||
VERIFY_IS_APPROX(a,c);
|
VERIFY_IS_APPROX(a,c);
|
||||||
|
|
||||||
|
// check compound assignment of products
|
||||||
|
d = c;
|
||||||
|
add_assign_using_evaluator(c.noalias(), prod(a,b));
|
||||||
|
d.noalias() += a*b;
|
||||||
|
VERIFY_IS_APPROX(c, d);
|
||||||
|
|
||||||
|
d = c;
|
||||||
|
subtract_assign_using_evaluator(c.noalias(), prod(a,b));
|
||||||
|
d.noalias() -= a*b;
|
||||||
|
VERIFY_IS_APPROX(c, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user