From 9ab4d85f28e97c884912ce43efcffc8cf25190de Mon Sep 17 00:00:00 2001 From: fintarin Date: Sun, 30 Jul 2023 13:45:30 +0300 Subject: [PATCH] Refactor some functions --- .../fintamath/functions/arithmetic/Div.hpp | 3 ++ include/fintamath/functions/powers/Pow.hpp | 2 + include/fintamath/functions/powers/Root.hpp | 2 + src/fintamath/functions/arithmetic/Div.cpp | 26 +++++++----- src/fintamath/functions/powers/Pow.cpp | 30 +++++++------ src/fintamath/functions/powers/Root.cpp | 42 ++++++++++--------- 6 files changed, 62 insertions(+), 43 deletions(-) diff --git a/include/fintamath/functions/arithmetic/Div.hpp b/include/fintamath/functions/arithmetic/Div.hpp index d03d36978..31e7e5430 100644 --- a/include/fintamath/functions/arithmetic/Div.hpp +++ b/include/fintamath/functions/arithmetic/Div.hpp @@ -6,6 +6,7 @@ namespace fintamath { class Integer; +class INumber; class Div : public IOperatorCRTP { public: @@ -24,6 +25,8 @@ class Div : public IOperatorCRTP { std::unique_ptr call(const ArgumentsRefVector &argsVect) const override; private: + static std::unique_ptr multiDivSimpl(const IArithmetic &lhs, const IArithmetic &rhs); + static std::unique_ptr divSimpl(const Integer &lhs, const Integer &rhs); }; diff --git a/include/fintamath/functions/powers/Pow.hpp b/include/fintamath/functions/powers/Pow.hpp index 0a2103a37..15ef2aedc 100644 --- a/include/fintamath/functions/powers/Pow.hpp +++ b/include/fintamath/functions/powers/Pow.hpp @@ -26,6 +26,8 @@ class Pow : public IOperatorCRTP { std::unique_ptr call(const ArgumentsRefVector &argsVect) const override; private: + static std::unique_ptr multiPowSimpl(const INumber &lhs, const INumber &rhs); + static std::unique_ptr powSimpl(const Integer &lhs, const Integer &rhs); static std::unique_ptr powSimpl(const Rational &lhs, const Rational &rhs); diff --git a/include/fintamath/functions/powers/Root.hpp b/include/fintamath/functions/powers/Root.hpp index 05416d588..873978026 100644 --- a/include/fintamath/functions/powers/Root.hpp +++ b/include/fintamath/functions/powers/Root.hpp @@ -25,6 +25,8 @@ class Root : public IFunctionCRTP { std::unique_ptr call(const ArgumentsRefVector &argsVect) const override; private: + static std::unique_ptr multiRootSimpl(const INumber &lhs, const INumber &rhs); + static std::unique_ptr rootSimpl(const Integer &lhs, const Integer &rhs); static std::unique_ptr rootSimpl(const Rational &lhs, const Integer &rhs); diff --git a/src/fintamath/functions/arithmetic/Div.cpp b/src/fintamath/functions/arithmetic/Div.cpp index 61494b050..9d36a7f69 100644 --- a/src/fintamath/functions/arithmetic/Div.cpp +++ b/src/fintamath/functions/arithmetic/Div.cpp @@ -9,16 +9,6 @@ namespace fintamath { std::unique_ptr Div::call(const ArgumentsRefVector &argsVect) const { - static const auto multiPow = [] { - static MultiMethod(const IArithmetic &, const IArithmetic &)> outMultiPow; - - outMultiPow.add([](const Integer &lhs, const Integer &rhs) { - return divSimpl(lhs, rhs); - }); - - return outMultiPow; - }(); - const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); @@ -30,7 +20,21 @@ std::unique_ptr Div::call(const ArgumentsRefVector &argsVect) const return ComplexInf().clone(); } - if (auto res = multiPow(lhs, rhs)) { + return multiDivSimpl(lhs, rhs); +} + +std::unique_ptr Div::multiDivSimpl(const IArithmetic &lhs, const IArithmetic &rhs) { + static const auto multiDiv = [] { + static MultiMethod(const IArithmetic &, const IArithmetic &)> outMultiPow; + + outMultiPow.add([](const Integer &lhs, const Integer &rhs) { + return divSimpl(lhs, rhs); + }); + + return outMultiPow; + }(); + + if (auto res = multiDiv(lhs, rhs)) { return res; } diff --git a/src/fintamath/functions/powers/Pow.cpp b/src/fintamath/functions/powers/Pow.cpp index 1784f260b..9108de423 100644 --- a/src/fintamath/functions/powers/Pow.cpp +++ b/src/fintamath/functions/powers/Pow.cpp @@ -12,6 +12,21 @@ namespace fintamath { std::unique_ptr Pow::call(const ArgumentsRefVector &argsVect) const { + const auto &lhs = cast(argsVect.front().get()); + const auto &rhs = cast(argsVect.back().get()); + + if (lhs == Integer(0) && rhs == Integer(0)) { + return Undefined().clone(); + } + + if (rhs < Integer(0)) { + return multiPowSimpl(*(Rational(1) / lhs), *(-rhs)); + } + + return multiPowSimpl(lhs, rhs); +} + +std::unique_ptr Pow::multiPowSimpl(const INumber &lhs, const INumber &rhs) { static const auto multiPow = [] { static MultiMethod(const INumber &, const INumber &)> outMultiPow; @@ -30,17 +45,6 @@ std::unique_ptr Pow::call(const ArgumentsRefVector &argsVect) const return outMultiPow; }(); - const auto &lhs = cast(argsVect.front().get()); - const auto &rhs = cast(argsVect.back().get()); - - if (lhs == Integer(0) && rhs == Integer(0)) { - return Undefined().clone(); - } - - if (rhs < Integer(0)) { - return Pow()(*(Rational(1) / lhs), *(-rhs)); - } - if (auto rhsConv = cast(convert(lhs, rhs))) { return multiPow(lhs, *rhsConv); } @@ -73,10 +77,10 @@ std::unique_ptr Pow::powSimpl(const Rational &lhs, const Rational & } if (lhsDenominator == 1) { - return Root()(*Pow()(lhsNumerator, rhsNumerator), rhsDenominator); + return Root()(*multiPowSimpl(lhsNumerator, rhsNumerator), rhsDenominator); } - return Root()(*Pow()(lhs, rhsNumerator), rhsDenominator); + return Root()(*multiPowSimpl(lhs, rhsNumerator), rhsDenominator); } std::unique_ptr Pow::powSimpl(const Real &lhs, const Real &rhs) { diff --git a/src/fintamath/functions/powers/Root.cpp b/src/fintamath/functions/powers/Root.cpp index 1f62b0aed..003f2d0b7 100644 --- a/src/fintamath/functions/powers/Root.cpp +++ b/src/fintamath/functions/powers/Root.cpp @@ -13,24 +13,6 @@ namespace fintamath { std::unique_ptr Root::call(const ArgumentsRefVector &argsVect) const { - static const auto multiRoot = [] { - static MultiMethod(const INumber &, const INumber &)> outMultiRoot; - - outMultiRoot.add([](const Integer &lhs, const Integer &rhs) { - return rootSimpl(lhs, rhs); - }); - - outMultiRoot.add([](const Rational &lhs, const Integer &rhs) { - return rootSimpl(lhs, rhs); - }); - - outMultiRoot.add([](const Real &lhs, const Integer &rhs) { - return rootSimpl(lhs, rhs); - }); - - return outMultiRoot; - }(); - const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); @@ -47,13 +29,35 @@ std::unique_ptr Root::call(const ArgumentsRefVector &argsVect) cons throw UndefinedFunctionException(toString(), {lhs.toString(), rhs.toString()}); } - return multiRoot(lhs, rhsInt); + return multiRootSimpl(lhs, rhsInt); } } return Pow()(lhs, *(Rational(1) / rhs)); } +std::unique_ptr Root::multiRootSimpl(const INumber &lhs, const INumber &rhs) { + static const auto multiRoot = [] { + static MultiMethod(const INumber &, const INumber &)> outMultiRoot; + + outMultiRoot.add([](const Integer &lhs, const Integer &rhs) { + return rootSimpl(lhs, rhs); + }); + + outMultiRoot.add([](const Rational &lhs, const Integer &rhs) { + return rootSimpl(lhs, rhs); + }); + + outMultiRoot.add([](const Real &lhs, const Integer &rhs) { + return rootSimpl(lhs, rhs); + }); + + return outMultiRoot; + }(); + + return multiRoot(lhs, rhs); +} + std::unique_ptr Root::rootSimpl(const Integer &lhs, const Integer &rhs) { if (auto res = perfectRoot(lhs, rhs)) { return res;