Skip to content

Commit

Permalink
Fix PowExpression::powSimplify
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Sep 19, 2023
1 parent eb11424 commit 7441b35
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 26 deletions.
26 changes: 16 additions & 10 deletions src/fintamath/expressions/binary/PowExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "fintamath/functions/arithmetic/Div.hpp"
#include "fintamath/functions/arithmetic/Mul.hpp"
#include "fintamath/functions/arithmetic/Neg.hpp"
#include "fintamath/functions/comparison/MoreEqv.hpp"
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/functions/powers/Root.hpp"
#include "fintamath/functions/powers/Sqrt.hpp"
Expand Down Expand Up @@ -81,13 +82,6 @@ ArgumentPtr PowExpression::preciseSimplify() const {
return IBinaryExpression::preciseSimplify();
}

PowExpression::SimplifyFunctionsVector PowExpression::getFunctionsForPreSimplify() const {
static const PowExpression::SimplifyFunctionsVector simplifyFunctions = {
&PowExpression::powSimplify,
};
return simplifyFunctions;
}

PowExpression::SimplifyFunctionsVector PowExpression::getFunctionsForPostSimplify() const {
static const PowExpression::SimplifyFunctionsVector simplifyFunctions = {
&PowExpression::constSimplify,
Expand Down Expand Up @@ -182,9 +176,21 @@ ArgumentPtr PowExpression::powSimplify(const IFunction & /*func*/, const Argumen
ArgumentPtr res;

if (auto lhsExpr = cast<IExpression>(lhs); lhsExpr && is<Pow>(lhsExpr->getFunction())) {
ArgumentPtr lhsPow = lhsExpr->getChildren().front();
ArgumentPtr rhsPow = mulExpr(lhsExpr->getChildren().back(), rhs);
res = powExpr(lhsPow, rhsPow);
auto lhsExprLhsChild = lhsExpr->getChildren().front();
auto lhsExprRhsChild = lhsExpr->getChildren().back();

bool canMul = is<Integer>(rhs) && is<Integer>(lhsExprRhsChild);

if (auto lhsExprLhsChildNum = cast<INumber>(lhsExprLhsChild)) {
canMul = canMul ||
*MoreEqv()(*lhsExprLhsChildNum, Integer(0)) == Boolean(true);
}

if (canMul) {
ArgumentPtr newLhs = lhsExprLhsChild;
ArgumentPtr newRhs = mulExpr(lhsExprRhsChild, rhs);
res = powExpr(newLhs, newRhs);
}
}

return res;
Expand Down
2 changes: 0 additions & 2 deletions src/fintamath/expressions/binary/PowExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class PowExpression : public IBinaryExpressionCRTP<PowExpression> {
protected:
ArgumentPtr preciseSimplify() const override;

SimplifyFunctionsVector getFunctionsForPreSimplify() const override;

SimplifyFunctionsVector getFunctionsForPostSimplify() const override;

private:
Expand Down
6 changes: 3 additions & 3 deletions tests/src/expressions/ExpressionFunctionsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ TEST(ExpressionFunctionsTests, factorialTest) {
TEST(ExpressionFunctionsTests, sqrtTest) {
EXPECT_EQ(sqrt(Expression("4")).toString(), "2");
EXPECT_EQ(sqrt(Expression("5")).toString(), "sqrt(5)");
EXPECT_EQ(sqrt(Expression("a^4")).toString(), "a^2");
EXPECT_EQ(sqrt(Expression("a^2*b*b")).toString(), "a b");
EXPECT_EQ(sqrt(Expression("a^4")).toString(), "sqrt(a^4)");
EXPECT_EQ(sqrt(Expression("a^2*b*b")).toString(), "sqrt(a^2) sqrt(b^2)");
EXPECT_EQ(sqrt(Expression("a^2+b^2+2*a*b")).toString(), "sqrt(a^2 + 2 a b + b^2)");
}

TEST(ExpressionFunctionsTests, powTest) {
EXPECT_EQ(pow(Expression("a+b"), Expression("0")).toString(), "1");
EXPECT_EQ(pow(Expression("a^4"), Expression("a")).toString(), "a^(4 a)");
EXPECT_EQ(pow(Expression("a^4"), Expression("a")).toString(), "(a^4)^a");
EXPECT_EQ(pow(Expression("a^4"), Expression("2")).toString(), "a^8");
EXPECT_EQ(pow(Expression("a*b"), Expression("a+3")).toString(), "a^(a + 3) b^(a + 3)");
EXPECT_EQ(pow(Expression("a+2"), Expression("2")).toString(), "a^2 + 4 a + 4");
Expand Down
23 changes: 12 additions & 11 deletions tests/src/expressions/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("2*sqrt((1-cos(2*(Pi/3)))/2)*cos(Pi/3)").toString(), "sqrt(3)/2");
EXPECT_EQ(Expression("-sin(2)").toString(), "-sin(2)");
EXPECT_EQ(Expression("2^(3/2)").toString(), "2 sqrt(2)");
EXPECT_EQ(Expression("sqrt((-1)^2)").toString(), "1");
EXPECT_EQ(Expression("sqrt(sqrt5)").toString(), "root(5, 4)");
EXPECT_EQ(Expression("sqrt(sqrt(-5))").toString(), "sqrt(I) root(5, 4)");
EXPECT_EQ(Expression("sqrt4!").toString(), "2");
EXPECT_EQ(Expression("(sqrt4)!").toString(), "2");
EXPECT_EQ(Expression("sqrt4*2!").toString(), "4");
Expand Down Expand Up @@ -255,9 +257,9 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("x/y/z").toString(), "x/(y z)");
EXPECT_EQ(Expression("x/(y/z)").toString(), "(x z)/y");
EXPECT_EQ(Expression("(x/y)/z").toString(), "x/(y z)");
EXPECT_EQ(Expression("x^y^z").toString(), "x^(y z)");
EXPECT_EQ(Expression("x^y^z").toString(), "(x^y)^z");
EXPECT_EQ(Expression("x^(y^z)").toString(), "x^(y^z)");
EXPECT_EQ(Expression("(x^y)^z").toString(), "x^(y z)");
EXPECT_EQ(Expression("(x^y)^z").toString(), "(x^y)^z");
EXPECT_EQ(Expression("(a+b)^2").toString(), "a^2 + 2 a b + b^2");
EXPECT_EQ(Expression("(a+b)^3").toString(), "a^3 + 3 a^2 b + 3 a b^2 + b^3");
EXPECT_EQ(Expression("1*(a+b)^3").toString(), "a^3 + 3 a^2 b + 3 a b^2 + b^3");
Expand Down Expand Up @@ -362,6 +364,7 @@ TEST(ExpressionTests, stringConstructorTest) {

EXPECT_EQ(Expression("sqrt(x) + x").toString(), "x + sqrt(x)");
EXPECT_EQ(Expression("sqrt(x) - x").toString(), "-x + sqrt(x)");
EXPECT_EQ(Expression("sqrt(x) * sqrt(x)").toString(), "x");
EXPECT_EQ(Expression("x/(sqrt(x) - x)").toString(), "-1 - sqrt(x)/(x - sqrt(x))");
EXPECT_EQ(Expression("x/(2 sqrt(x) - x)").toString(), "-1 - (2 sqrt(x))/(x - 2 sqrt(x))");
EXPECT_EQ(Expression("(x-1)/(sqrt(x) - x)").toString(), "-1 - 1/sqrt(x)");
Expand Down Expand Up @@ -401,15 +404,13 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("log(E^3, E)").toString(), "1/3");
EXPECT_EQ(Expression("log(E^Pi, E)").toString(), "1/Pi");

// TODO! implement this
// EXPECT_EQ(Expression("sqrt((-1)^2)").toString(), "abs(x)");
// EXPECT_EQ(Expression("sqrt((-1)^2)").toString(), "abs(x)");
// 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");
// EXPECT_EQ(Expression("sqrt(x)^2").toString(), "x");
// EXPECT_EQ(Expression("sqrt(x) * sqrt(x)").toString(), "x");
// EXPECT_EQ(Expression("root(x^(-2), )").toString(), "abs(1/x)");
EXPECT_EQ(Expression("sqrt(x^2)").toString(), "sqrt(x^2)");
EXPECT_EQ(Expression("(x^10)^(1/10)").toString(), "root(x^10, 10)");
EXPECT_EQ(Expression("(x^3)^(1/3)").toString(), "root(x^3, 3)");
EXPECT_EQ(Expression("sqrt(x)^2").toString(), "sqrt(x)^2");
EXPECT_EQ(Expression("root(x^(-2), -2)").toString(), "sqrt(x^2)");

// TODO: implement
// EXPECT_EQ(Expression("abs(x)^3").toString(), "abs(x^3)");
// EXPECT_EQ(Expression("abs(x^3)").toString(), "abs(x^3)");
// EXPECT_EQ(Expression("abs(x)^I").toString(), "abs(x)^I");
Expand Down

0 comments on commit 7441b35

Please sign in to comment.