Skip to content

Commit

Permalink
Do not use simplify in DivExpression::toString() and CompExpression::…
Browse files Browse the repository at this point in the history
…toString()
  • Loading branch information
fintarin committed Feb 14, 2024
1 parent 5916a36 commit 4a16b6c
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 12 deletions.
2 changes: 2 additions & 0 deletions include/fintamath/expressions/ExpressionUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ std::pair<ArgumentPtr, ArgumentPtr> splitPowExpr(const ArgumentPtr &rhs);

std::pair<ArgumentPtr, ArgumentPtr> splitRational(const ArgumentPtr &arg);

ArgumentPtr negate(const ArgumentPtr &arg);

ArgumentPtr makePolynom(const IFunction &func, ArgumentPtrVector &&args);

ArgumentPtr makePolynom(const IFunction &func, const ArgumentPtrVector &args);
Expand Down
31 changes: 31 additions & 0 deletions src/fintamath/expressions/ExpressionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,37 @@ std::pair<ArgumentPtr, ArgumentPtr> splitRational(const ArgumentPtr &arg) {
return {arg, Integer(1).clone()};
}

ArgumentPtr negate(const ArgumentPtr &arg) {
if (const auto expr = cast<IExpression>(arg)) {
if (is<Add>(expr->getFunction())) {
auto negChildrenView =
expr->getChildren() |
stdv::transform([](const ArgumentPtr &child) {
return negate(child);
});
return makePolynom(Add{}, ArgumentPtrVector(negChildrenView.begin(), negChildrenView.end())); // TODO: use C++23 stdv::to
}

if (is<Mul>(expr->getFunction())) {
if (const auto firstChildNum = cast<INumber>(expr->getChildren().front())) {
if (*firstChildNum == Integer(-1)) {
ArgumentPtrVector negChildren(expr->getChildren().begin() + 1, expr->getChildren().end());
return makePolynom(Mul(), std::move(negChildren));
}

ArgumentPtrVector negChildren = expr->getChildren();
negChildren.front() = (*firstChildNum) * Integer(-1);
return makePolynom(Mul(), std::move(negChildren));
}
}
}
else if (const auto arithm = cast<IArithmetic>(arg)) {
return (*arithm) * Integer(-1);
}

return mulExpr(Integer(-1).clone(), arg);
}

ArgumentPtr makePolynom(const IFunction &func, ArgumentPtrVector &&args) {
if (args.empty()) {
return {};
Expand Down
11 changes: 3 additions & 8 deletions src/fintamath/expressions/binary/CompExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,12 @@ std::string CompExpression::toString() const {
*lhsExpr->getFunction() == Add{}) {

ArgumentPtrVector sumChildren = lhsExpr->getChildren();
const ArgumentPtr solLhs = sumChildren.front();
ArgumentPtr solLhs = sumChildren.front();

if (is<Variable>(solLhs)) {
sumChildren.erase(sumChildren.begin());

ArgumentPtr solRhs = negExpr(std::move(sumChildren));
simplifyChild(solRhs);

if (!is<IExpression>(solRhs)) {
return CompExpression(cast<IOperator>(*func), solLhs, solRhs).toString();
}
ArgumentPtr solRhs = detail::negate(makePolynom(Add{}, std::move(sumChildren)));
return CompExpression(cast<IOperator>(*func), std::move(solLhs), std::move(solRhs)).toString();
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/fintamath/expressions/binary/DivExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ DivExpression::DivExpression(ArgumentPtr inLhsChild, ArgumentPtr inRhsChild)
}

std::string DivExpression::toString() const {
if (isNegated(lhsChild)) { // TODO! find more efficient solution
ArgumentPtr innerDiv = divExpr(negExpr(lhsChild)->toMinimalObject(), rhsChild);
return negExpr(std::move(innerDiv))->toString();
if (isNegated(lhsChild)) {
return negExpr(divExpr(detail::negate(lhsChild), rhsChild))->toString();
}

return IBinaryExpression::toString();
Expand Down
4 changes: 4 additions & 0 deletions tests/src/expressions/ExpressionUtilsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,7 @@ TEST(ExpressionUtilsTests, isNegativeNumberTest) {
TEST(ExpressionUtilsTests, makePolynomTest) {
// TODO: implement
}

TEST(ExpressionUtilsTests, negateTest) {
// TODO: implement
}
2 changes: 1 addition & 1 deletion tests/src/overall/simplify/SimplifyDerivativeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ TEST(SimplifyDerivativeTests, simplifyTest) {
EXPECT_EQ(Expression("derivative(ln(cos(3x)), x)").toString(),
"-3 tan(3 x)");
EXPECT_EQ(Expression("derivative(log(sin(x^5), tan(x^3)), x)").toString(),
"(3 sec(x^3)^2 x^2 cos(x^3) csc(x^3))/ln(sin(x^5)) - (5 x^4 cot(x^5) ln(tan(x^3)))/(ln(sin(x^5))^2)");
"(3 sec(x^3)^2 x^2 cos(x^3) csc(x^3))/ln(sin(x^5)) - (5 x^4 cos(x^5) csc(x^5) ln(tan(x^3)))/(ln(sin(x^5))^2)");
EXPECT_EQ(Expression("derivative(acos(4x + 5)^5, x)").toString(),
"-(20 acos(4 x + 5)^4)/sqrt(-16 x^2 - 40 x - 24)");
EXPECT_EQ(Expression("derivative(sin(sin(sin(x))), x)").toString(),
Expand Down

0 comments on commit 4a16b6c

Please sign in to comment.