Generalize inverse() to pow<...>()

This commit is contained in:
Chip Hogg
2022-01-08 19:34:21 -05:00
parent 053de8d539
commit 409aaf4636
2 changed files with 30 additions and 10 deletions

View File

@@ -126,11 +126,11 @@ constexpr bool operator==(T t, U u) {
} }
/** /**
* @brief The (multiplicative) inverse of a BasePower. * @brief A BasePower, raised to a rational power E.
*/ */
template<BasePower BP> template<ratio E>
constexpr auto inverse(BP bp) { constexpr auto pow(BasePower auto bp) {
bp.power = -bp.power; bp.power = bp.power * E;
return bp; return bp;
} }
@@ -220,8 +220,8 @@ constexpr bool strictly_increasing(Ts&&... ts) {
/** /**
* @brief A representation for positive real numbers which optimizes taking products and rational powers. * @brief A representation for positive real numbers which optimizes taking products and rational powers.
* *
* Magnitudes can be treated as values. Each type encodes exactly one value. Users can multiply, divide, and compare * Magnitudes can be treated as values. Each type encodes exactly one value. Users can multiply, divide, raise to
* for equality. * rational powers, and compare for equality.
*/ */
template<BasePower auto... BPs> template<BasePower auto... BPs>
requires ((detail::is_valid_base_power(BPs) && ... && detail::strictly_increasing(BPs.get_base()...))) requires ((detail::is_valid_base_power(BPs) && ... && detail::strictly_increasing(BPs.get_base()...)))
@@ -274,10 +274,13 @@ constexpr bool operator==(magnitude<LeftBPs...>, magnitude<RightBPs...>) {
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Magnitude inverse implementation. // Magnitude rational powers implementation.
template<BasePower auto... BPs> template<ratio E, BasePower auto... BPs>
constexpr auto inverse(magnitude<BPs...>) { return magnitude<inverse(BPs)...>{}; } constexpr auto pow(magnitude<BPs...>) {
if constexpr (E == 0) { return magnitude<>{}; }
else { return magnitude<pow<E>(BPs)...>{}; }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Magnitude product implementation. // Magnitude product implementation.
@@ -322,7 +325,7 @@ constexpr auto operator*(magnitude<H1, T1...>, magnitude<H2, T2...>) {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Magnitude quotient implementation. // Magnitude quotient implementation.
constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * inverse(r); } constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1>(r); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// `as_magnitude()` implementation. // `as_magnitude()` implementation.

View File

@@ -181,6 +181,23 @@ TEST_CASE("Division works for magnitudes")
} }
} }
TEST_CASE("Can raise Magnitudes to rational powers")
{
SECTION("Anything to the 0 is 1") {
CHECK(pow<0>(as_magnitude<1>()) == as_magnitude<1>());
CHECK(pow<0>(as_magnitude<123>()) == as_magnitude<1>());
CHECK(pow<0>(as_magnitude<ratio{3, 4}>()) == as_magnitude<1>());
CHECK(pow<0>(pi_to_the<ratio{-1, 2}>()) == as_magnitude<1>());
}
SECTION("Anything to the 1 is itself") {
CHECK(pow<1>(as_magnitude<1>()) == as_magnitude<1>());
CHECK(pow<1>(as_magnitude<123>()) == as_magnitude<123>());
CHECK(pow<1>(as_magnitude<ratio{3, 4}>()) == as_magnitude<ratio{3, 4}>());
CHECK(pow<1>(pi_to_the<ratio{-1, 2}>()) == pi_to_the<ratio{-1, 2}>());
}
}
namespace detail namespace detail
{ {