diff --git a/include/rotgen/common/ref.hpp b/include/rotgen/common/ref.hpp index 1dff724..d58dd0d 100644 --- a/include/rotgen/common/ref.hpp +++ b/include/rotgen/common/ref.hpp @@ -231,6 +231,74 @@ namespace rotgen return lhs.base() / s; } + template + auto min(ref lhs, ref rhs) -> decltype(lhs.base().cwiseMin(rhs.base())) + { + return lhs.base().cwiseMin(rhs.base()); + } + + template + auto min(ref lhs, std::convertible_to auto s) -> decltype(lhs.base().cwiseMin(s)) + { + return lhs.base().cwiseMin(s); + } + + template + auto min(std::convertible_to auto s,ref rhs) -> decltype(rhs.base().cwiseMin(s)) + { + return rhs.base().cwiseMin(s); + } + + template + auto max(ref lhs, ref rhs) -> decltype(lhs.base().cwiseMax(rhs.base())) + { + return lhs.base().cwiseMax(rhs.base()); + } + + template + auto max(ref lhs, std::convertible_to auto s) -> decltype(lhs.base().cwiseMax(s)) + { + return lhs.base().cwiseMax(s); + } + + template + auto max(std::convertible_to auto s,ref rhs) -> decltype(rhs.base().cwiseMax(s)) + { + return rhs.base().cwiseMax(s); + } + + template + auto mul(ref lhs, ref rhs) -> decltype(lhs.base().cwiseProduct(rhs.base())) + { + return lhs.base().cwiseProduct(rhs.base()); + } + + template + auto mul(ref lhs, std::convertible_to auto s) -> decltype(lhs * s) + { + return lhs * s; + } + + template + auto mul(std::convertible_to auto s,ref rhs) -> decltype(s * rhs) + { + return s * rhs; + } + + template + auto div(ref lhs, ref rhs) -> decltype(lhs.base().cwiseQuotient(rhs.base())) + { + return lhs.base().cwiseQuotient(rhs.base()); + } + + template + auto div(ref lhs, std::convertible_to auto s) -> decltype(lhs / s) + { + return lhs / s; + } + + //------------------------------------------------------------------------------------------- + // Convert entity/eigen types to a proper ref so we can write less function overloads template struct generalize; template diff --git a/include/rotgen/dynamic/map.hpp b/include/rotgen/dynamic/map.hpp index b7df712..fe45aed 100644 --- a/include/rotgen/dynamic/map.hpp +++ b/include/rotgen/dynamic/map.hpp @@ -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) { diff --git a/include/rotgen/fixed/map.hpp b/include/rotgen/fixed/map.hpp index 071ce07..619734a 100644 --- a/include/rotgen/fixed/map.hpp +++ b/include/rotgen/fixed/map.hpp @@ -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()}; diff --git a/include/rotgen/functions.hpp b/include/rotgen/functions.hpp index 0de28b2..ba6a81e 100644 --- a/include/rotgen/functions.hpp +++ b/include/rotgen/functions.hpp @@ -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 + auto min(A const& a, B const& b) + { + if constexpr(!use_expression_templates) return min(generalize_t(a), generalize_t(b)); + else return base_of(a).cwiseMin(base_of(b)); + } + + template + auto min(A const& a, std::convertible_to auto b) + { + if constexpr(!use_expression_templates) return min(generalize_t(a), b); + else return base_of(a).cwiseMin(b); + } + + template + auto min(std::convertible_to auto a, B const& b) + { + if constexpr(!use_expression_templates) return min(a,generalize_t(b)); + else return base_of(b).cwiseMin(a); + } + + template + auto max(A const& a, B const& b) + { + if constexpr(!use_expression_templates) return max(generalize_t(a), generalize_t(b)); + else return base_of(a).cwiseMax(base_of(b)); + } + + template + auto max(A const& a, std::convertible_to auto b) + { + if constexpr(!use_expression_templates) return max(generalize_t(a), b); + else return base_of(a).cwiseMax(b); + } + + template + auto max(std::convertible_to auto a, B const& b) + { + if constexpr(!use_expression_templates) return max(a, generalize_t(b)); + else return base_of(b).cwiseMax(a); + } + + template + auto mul(A const& a, B const& b) + { + if constexpr(!use_expression_templates) return mul(generalize_t(a), generalize_t(b)); + else return base_of(a).cwiseProduct(base_of(b)); + } + + template + auto mul(A const& a, std::convertible_to auto b) + { + return a * b; + } + + template + auto mul(std::convertible_to auto a, B const& b) + { + return a * b; + } + + template + auto div(A const& a, B const& b) + { + if constexpr(!use_expression_templates) return div(generalize_t(a), generalize_t(b)); + else return base_of(a).array() / base_of(b).array(); + } + + template + auto div(A const& a, std::convertible_to auto b) + { + return a / b; + } + //----------------------------------------------------------------------------------------------- // Reductions //----------------------------------------------------------------------------------------------- diff --git a/include/rotgen/impl/map_model.hpp b/include/rotgen/impl/map_model.hpp index 0819776..7c2c74c 100644 --- a/include/rotgen/impl/map_model.hpp +++ b/include/rotgen/impl/map_model.hpp @@ -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(); diff --git a/src/map_model.cpp b/src/map_model.cpp index 8e78245..c2e1df6 100644 --- a/src/map_model.cpp +++ b/src/map_model.cpp @@ -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() {