Implement binary cwise operations

See merge request oss/rotgen!27
This commit is contained in:
Joel Falcou 2025-09-21 21:53:03 +02:00
commit 5d8a084070
6 changed files with 233 additions and 0 deletions

View file

@ -231,6 +231,74 @@ namespace rotgen
return lhs.base() / s;
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto min(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseMin(rhs.base()))
{
return lhs.base().cwiseMin(rhs.base());
}
template<typename A, int O, typename S>
auto min(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs.base().cwiseMin(s))
{
return lhs.base().cwiseMin(s);
}
template<typename A, int O, typename S>
auto min(std::convertible_to<typename A::value_type> auto s,ref<A,O,S> rhs) -> decltype(rhs.base().cwiseMin(s))
{
return rhs.base().cwiseMin(s);
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto max(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseMax(rhs.base()))
{
return lhs.base().cwiseMax(rhs.base());
}
template<typename A, int O, typename S>
auto max(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs.base().cwiseMax(s))
{
return lhs.base().cwiseMax(s);
}
template<typename A, int O, typename S>
auto max(std::convertible_to<typename A::value_type> auto s,ref<A,O,S> rhs) -> decltype(rhs.base().cwiseMax(s))
{
return rhs.base().cwiseMax(s);
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto mul(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseProduct(rhs.base()))
{
return lhs.base().cwiseProduct(rhs.base());
}
template<typename A, int O, typename S>
auto mul(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs * s)
{
return lhs * s;
}
template<typename A, int O, typename S>
auto mul(std::convertible_to<typename A::value_type> auto s,ref<A,O,S> rhs) -> decltype(s * rhs)
{
return s * rhs;
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto div(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseQuotient(rhs.base()))
{
return lhs.base().cwiseQuotient(rhs.base());
}
template<typename A, int O, typename S>
auto div(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs / s)
{
return lhs / s;
}
//-------------------------------------------------------------------------------------------
// Convert entity/eigen types to a proper ref so we can write less function overloads
template<typename T> struct generalize;
template<typename T>

View file

@ -136,6 +136,12 @@ namespace rotgen
concrete_type cwiseAbs2() const { return concrete_type(base().cwiseAbs2()); }
concrete_type cwiseInverse() const { return concrete_type(base().cwiseInverse()); }
concrete_type cwiseSqrt() const { return concrete_type(base().cwiseSqrt()); }
concrete_type cwiseMin (map const& rhs) const { return concrete_type(base().cwiseMin(rhs.base())); }
concrete_type cwiseMax (map const& rhs) const { return concrete_type(base().cwiseMax(rhs.base())); }
concrete_type cwiseQuotient (map const& rhs) const { return concrete_type(base().cwiseQuotient(rhs.base())); }
concrete_type cwiseProduct(map const& rhs) const { return concrete_type(base().cwiseProduct(rhs.base())); }
concrete_type cwiseMin(value_type s) const { return concrete_type(base().cwiseMin(s)); }
concrete_type cwiseMax(value_type s) const { return concrete_type(base().cwiseMax(s)); }
void normalize() requires(!is_immutable && IsVectorAtCompileTime)
{

View file

@ -161,6 +161,42 @@ namespace rotgen
return *this;
}
auto cwiseMin(map const& rhs) const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMin(rhs.base())};
else return base().cwiseMin(rhs.base());
}
auto cwiseMin(value_type rhs) const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMin(rhs)};
else return base().cwiseMin(rhs);
}
auto cwiseMax(map const& rhs) const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMax(rhs.base())};
else return base().cwiseMax(rhs.base());
}
auto cwiseMax(value_type rhs) const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMax(rhs)};
else return base().cwiseMax(rhs);
}
auto cwiseProduct(map const& rhs) const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseProduct(rhs.base())};
else return base().cwiseProduct(rhs.base());
}
auto cwiseQuotient(map const& rhs) const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseQuotient(rhs.base())};
else return base().cwiseQuotient(rhs.base());
}
auto cwiseAbs() const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs()};

View file

@ -62,6 +62,80 @@ namespace rotgen
auto rec (auto const& arg) requires(requires{arg.cwiseInverse();}) { return arg.cwiseInverse(); }
auto sqrt(auto const& arg) requires(requires{arg.cwiseSqrt();} ) { return arg.cwiseSqrt(); }
template<concepts::entity A, concepts::entity B>
auto min(A const& a, B const& b)
{
if constexpr(!use_expression_templates) return min(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseMin(base_of(b));
}
template<concepts::entity A>
auto min(A const& a, std::convertible_to<typename A::value_type> auto b)
{
if constexpr(!use_expression_templates) return min(generalize_t<A const>(a), b);
else return base_of(a).cwiseMin(b);
}
template<concepts::entity B>
auto min(std::convertible_to<typename B::value_type> auto a, B const& b)
{
if constexpr(!use_expression_templates) return min(a,generalize_t<B const>(b));
else return base_of(b).cwiseMin(a);
}
template<concepts::entity A, concepts::entity B>
auto max(A const& a, B const& b)
{
if constexpr(!use_expression_templates) return max(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseMax(base_of(b));
}
template<concepts::entity A>
auto max(A const& a, std::convertible_to<typename A::value_type> auto b)
{
if constexpr(!use_expression_templates) return max(generalize_t<A const>(a), b);
else return base_of(a).cwiseMax(b);
}
template<concepts::entity B>
auto max(std::convertible_to<typename B::value_type> auto a, B const& b)
{
if constexpr(!use_expression_templates) return max(a, generalize_t<B const>(b));
else return base_of(b).cwiseMax(a);
}
template<concepts::entity A, concepts::entity B>
auto mul(A const& a, B const& b)
{
if constexpr(!use_expression_templates) return mul(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseProduct(base_of(b));
}
template<concepts::entity A>
auto mul(A const& a, std::convertible_to<typename A::value_type> auto b)
{
return a * b;
}
template<concepts::entity B>
auto mul(std::convertible_to<typename B::value_type> auto a, B const& b)
{
return a * b;
}
template<concepts::entity A, concepts::entity B>
auto div(A const& a, B const& b)
{
if constexpr(!use_expression_templates) return div(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).array() / base_of(b).array();
}
template<concepts::entity A>
auto div(A const& a, std::convertible_to<typename A::value_type> auto b)
{
return a / b;
}
//-----------------------------------------------------------------------------------------------
// Reductions
//-----------------------------------------------------------------------------------------------

View file

@ -46,6 +46,13 @@ class ROTGEN_EXPORT CLASSNAME
SOURCENAME cwiseInverse() const;
SOURCENAME cwiseSqrt() const;
SOURCENAME cwiseMax (CLASSNAME const&) const;
SOURCENAME cwiseMin (CLASSNAME const&) const;
SOURCENAME cwiseProduct (CLASSNAME const&) const;
SOURCENAME cwiseQuotient (CLASSNAME const&) const;
SOURCENAME cwiseMax(TYPE) const;
SOURCENAME cwiseMin(TYPE) const;
#if !defined(USE_CONST)
void normalize();
void transposeInPlace();

View file

@ -118,6 +118,48 @@
return result;
}
SOURCENAME CLASSNAME::cwiseMin(CLASSNAME const& rhs) const
{
SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMin(rhs.storage()->data).eval());
return result;
}
SOURCENAME CLASSNAME::cwiseMax(CLASSNAME const& rhs) const
{
SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMax(rhs.storage()->data).eval());
return result;
}
SOURCENAME CLASSNAME::cwiseProduct(CLASSNAME const& rhs) const
{
SOURCENAME result;
result.storage()->assign(storage_->data.cwiseProduct(rhs.storage()->data).eval());
return result;
}
SOURCENAME CLASSNAME::cwiseQuotient(CLASSNAME const& rhs) const
{
SOURCENAME result;
result.storage()->assign(storage_->data.cwiseQuotient(rhs.storage()->data).eval());
return result;
}
SOURCENAME CLASSNAME::cwiseMin(TYPE rhs) const
{
SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMin(rhs).eval());
return result;
}
SOURCENAME CLASSNAME::cwiseMax(TYPE rhs) const
{
SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMax(rhs).eval());
return result;
}
#if !defined(USE_CONST)
void CLASSNAME::normalize()
{