Skip to content

Commit

Permalink
Implement Pow(Div, Expr)
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Jul 12, 2023
1 parent 1de0b8b commit 1f0141b
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
28 changes: 25 additions & 3 deletions src/fintamath/expressions/binary/PowExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ PowExpression::PowExpression(const ArgumentPtr &inLhsChild, const ArgumentPtr &i
}

std::string PowExpression::toString() const {
if (auto val = cast<Rational>(rhsChild)) {
const Integer &numerator = val->numerator();
const Integer &denominator = val->denominator();
if (auto rhsChildRat = cast<Rational>(rhsChild)) {
const Integer &numerator = rhsChildRat->numerator();
const Integer &denominator = rhsChildRat->denominator();

if (numerator == 1) {
if (denominator == 2) {
Expand All @@ -33,6 +33,12 @@ std::string PowExpression::toString() const {
}
}

if (auto rhsChildExpr = cast<IExpression>(rhsChild); rhsChildExpr && is<Div>(rhsChildExpr->getFunction())) {
if (*rhsChildExpr->getChildren().front() == Integer(1)) {
return functionToString(Root(), {lhsChild, rhsChildExpr->getChildren().back()});
}
}

return IBinaryExpression::toString();
}

Expand Down Expand Up @@ -219,6 +225,10 @@ ArgumentPtr PowExpression::polynomSimplify(const IFunction & /*func*/, const Arg
return res;
}

if (auto res = divSimplify(lhs, rhs)) {
return res;
}

return {};
}

Expand All @@ -238,6 +248,18 @@ ArgumentPtr PowExpression::mulSimplify(const ArgumentPtr &lhs, const ArgumentPtr
return res;
}

ArgumentPtr PowExpression::divSimplify(const ArgumentPtr &lhs, const ArgumentPtr &rhs) {
ArgumentPtr res;

if (auto divExpr = cast<IExpression>(lhs); divExpr && is<Div>(divExpr->getFunction())) {
ArgumentPtr numerator = makeExpr(Pow(), divExpr->getChildren().front(), rhs);
ArgumentPtr denominator = makeExpr(Pow(), divExpr->getChildren().back(), rhs);
res = makeExpr(Div(), numerator, denominator);
}

return res;
}

ArgumentPtr PowExpression::sumSimplify(const ArgumentPtr &lhs, const ArgumentPtr &rhs) {
if (const auto rhsInt = cast<Integer>(rhs)) {
if (auto sumExpr = sumPolynomSimplify(lhs, *rhsInt)) {
Expand Down
2 changes: 2 additions & 0 deletions src/fintamath/expressions/binary/PowExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class PowExpression : public IBinaryExpressionCRTP<PowExpression> {

static ArgumentPtr mulSimplify(const ArgumentPtr &lhs, const ArgumentPtr &rhs);

static ArgumentPtr divSimplify(const ArgumentPtr &lhs, const ArgumentPtr &rhs);

static ArgumentPtr sumSimplify(const ArgumentPtr &lhs, const ArgumentPtr &rhs);
};

Expand Down
7 changes: 6 additions & 1 deletion tests/src/expressions/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,13 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("(a+b)*(a+b)*(1/(a+b))").toString(), "a + b");
EXPECT_EQ(Expression("(x^2+2x+1)/(x+1)").toString(), "x + 1");

EXPECT_EQ(Expression("(x/y)^2").toString(), "x^2/y^2");
EXPECT_EQ(Expression("(x/y)^(1/2)").toString(), "sqrt(x)/sqrt(y)");
EXPECT_EQ(Expression("(x/y)^(1/3)").toString(), "root(x, 3)/root(y, 3)");
EXPECT_EQ(Expression("(x/y)^x").toString(), "x^x/y^x");
EXPECT_EQ(Expression("(x/y)^(1/x)").toString(), "root(x, x)/root(y, x)");

// TODO! implement this
// EXPECT_EQ(Expression("(x/y)^2").toString(), "(x^2)/(y^2)");
// EXPECT_EQ(Expression("sqrt(x^2)").toString(), "abs(x)");
// EXPECT_EQ(Expression("(x^10)^(1/10))").toString(), "abs(x)");
// EXPECT_EQ(Expression("(x^3)^(1/3)").toString(), "x");
Expand Down
2 changes: 1 addition & 1 deletion tests/src/functions/powers/RootTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ TEST(RootTests, callTest) {
EXPECT_EQ(f(Variable("a"), Integer(2))->toString(), "sqrt(a)");
EXPECT_EQ(f(Variable("a"), Integer(3))->toString(), "root(a, 3)");
EXPECT_EQ(f(Variable("a"), Integer(123))->toString(), "root(a, 123)");
EXPECT_EQ(f(Integer(2), Variable("a"))->toString(), "2^(1/a)");
EXPECT_EQ(f(Integer(2), Variable("a"))->toString(), "root(2, a)");

EXPECT_THROW(f(Integer(-10), Integer(2)), UndefinedException);
EXPECT_THROW(f(Rational(-9289, 10), Rational(2, 3)), UndefinedException);
Expand Down

0 comments on commit 1f0141b

Please sign in to comment.