Skip to content

Commit

Permalink
Simplify floor, ceil
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Oct 31, 2023
1 parent fc133ae commit 7dc5b36
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 23 deletions.
1 change: 1 addition & 0 deletions include/fintamath/core/MathObjectTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class MathObjectType {
InvTrigExpression,
HyperbExpression,
InvHyperbExpression,
RoundExpression,

IBinaryExpression = 4000,

Expand Down
12 changes: 12 additions & 0 deletions src/fintamath/config/ExpressionConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "fintamath/expressions/unary/InvHyperbExpression.hpp"
#include "fintamath/expressions/unary/InvTrigExpression.hpp"
#include "fintamath/expressions/unary/NotExpression.hpp"
#include "fintamath/expressions/unary/RoundExpression.hpp"
#include "fintamath/expressions/unary/TrigExpression.hpp"
#include "fintamath/functions/arithmetic/Add.hpp"
#include "fintamath/functions/arithmetic/Div.hpp"
Expand Down Expand Up @@ -58,6 +59,8 @@
#include "fintamath/functions/logic/Nequiv.hpp"
#include "fintamath/functions/logic/Not.hpp"
#include "fintamath/functions/logic/Or.hpp"
#include "fintamath/functions/ntheory/Ceil.hpp"
#include "fintamath/functions/ntheory/Floor.hpp"
#include "fintamath/functions/other/Deg.hpp"
#include "fintamath/functions/other/Index.hpp"
#include "fintamath/functions/other/Percent.hpp"
Expand Down Expand Up @@ -433,8 +436,17 @@ struct ExpressionConfig {
static const ArgumentPtr deg1 = Deg()(Integer(1));
return mulExpr(args.front(), deg1);
});

Expression::registerFunctionExpressionMaker<Floor>([](ArgumentPtrVector &&args) {
return RoundExpression(Floor(), args.front()).clone();
});

Expression::registerFunctionExpressionMaker<Ceil>([](ArgumentPtrVector &&args) {
return RoundExpression(Ceil(), args.front()).clone();
});
}
};

const ExpressionConfig config;

}
6 changes: 3 additions & 3 deletions src/fintamath/expressions/IExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,10 @@ ArgumentPtr IExpression::approximateSimplify() const {
}

if (!containsVar && areNumberChilrenPrecise) {
auto res = callFunction(*approxSimplExpr->getFunction(),
convertToApproximatedNumbers(approxSimplExpr->getChildren()));
if (auto res = callFunction(*approxSimplExpr->getFunction(),
convertToApproximatedNumbers(approxSimplExpr->getChildren()));
is<INumber>(res)) {

if (is<INumber>(res)) {
return res;
}
}
Expand Down
31 changes: 31 additions & 0 deletions src/fintamath/expressions/unary/RoundExpression.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "fintamath/expressions/unary/RoundExpression.hpp"

#include "fintamath/expressions/ExpressionUtils.hpp"
#include "fintamath/functions/ntheory/Ceil.hpp"
#include "fintamath/functions/ntheory/Floor.hpp"

namespace fintamath {

RoundExpression::RoundExpression(const IFunction &inFunc, ArgumentPtr inChild)
: IUnaryExpressionCRTP(inFunc, std::move(inChild)) {
}

RoundExpression::SimplifyFunctionVector RoundExpression::getFunctionsForPostSimplify() const {
static const RoundExpression::SimplifyFunctionVector simplifyFunctions = {
&RoundExpression::intApproximateSimplify,
};
return simplifyFunctions;
}

ArgumentPtr RoundExpression::intApproximateSimplify(const IFunction &func, const ArgumentPtr &rhs) {
if (containsVariable(rhs)) {
return {};
}

ArgumentPtr approx = rhs->clone();
approximateSimplifyChild(approx);

return callFunction(func, {approx});
}

}
24 changes: 24 additions & 0 deletions src/fintamath/expressions/unary/RoundExpression.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "fintamath/expressions/interfaces/IUnaryExpression.hpp"

namespace fintamath {

class Rational;

class RoundExpression : public IUnaryExpressionCRTP<RoundExpression, true> {
public:
explicit RoundExpression(const IFunction &inFunc, ArgumentPtr inChild);

static MathObjectType getTypeStatic() {
return MathObjectType::RoundExpression;
}

protected:
SimplifyFunctionVector getFunctionsForPostSimplify() const override;

private:
static ArgumentPtr intApproximateSimplify(const IFunction &func, const ArgumentPtr &rhs);
};

}
34 changes: 14 additions & 20 deletions tests/src/expressions/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,19 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("log(1000!,1000!)").toString(), "1");
EXPECT_EQ(Expression("log(100000000000!,100000000000!)").toString(), "1");

EXPECT_EQ(Expression("floor(E)").toString(), "2");
EXPECT_EQ(Expression("ceil(E)").toString(), "3");
EXPECT_EQ(Expression("floor(E^10)").toString(), "22026");
EXPECT_EQ(Expression("ceil(E^10)").toString(), "22027");
EXPECT_EQ(Expression("floor(11^10)").toString(), "25937424601");
EXPECT_EQ(Expression("ceil(11^10)").toString(), "25937424601");
EXPECT_EQ(Expression("tan(floor(E/3))").toString(), "0");
EXPECT_EQ(Expression("tan(ceil(-E/3))").toString(), "0");
EXPECT_EQ(Expression("ln(floor(E/3))").toString(), "-Inf");
EXPECT_EQ(Expression("root(ceil(-E/3), 3)").toString(), "0");
EXPECT_EQ(Expression("floor(E + I)").toString(), "2 + I");
EXPECT_EQ(Expression("floor(E + x)").toString(), "floor(x + E)");

EXPECT_EQ(Expression("-sin(x)").toString(), "-sin(x)");
EXPECT_EQ(Expression("-sin(x) + sin(2)").toString(), "-sin(x) + sin(2)");
EXPECT_EQ(Expression("-3sin(E)").toString(), "-3 sin(E)");
Expand Down Expand Up @@ -547,6 +560,7 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("log(1deg, (1deg)^(1deg)) = 1deg").toString(), "True");
EXPECT_EQ(Expression("E^Pi > Pi^E").toString(), "-Pi^E + E^Pi > 0"); // TODO: True
EXPECT_EQ(Expression("Pi^E < E^Pi").toString(), "-E^Pi + Pi^E < 0"); // TODO: True
EXPECT_EQ(Expression("log(floor(E), E) = lb(E)").toString(), "True");

EXPECT_EQ(Expression("derivative(a, a)").toString(), "1");
EXPECT_EQ(Expression("derivative(a+a, a)").toString(), "derivative(2 a, a)");
Expand Down Expand Up @@ -1849,18 +1863,6 @@ TEST(ExpressionTests, approximateTest) {
"7182818284590452353602874713526624977572470936999595749669676277240766303535476^(2."
"3315043990071954622896899110121376663320174289635168232800545468180794366424973*10^1656520))");

EXPECT_EQ(Expression("floor(E)").approximate().toString(),
"2");
EXPECT_EQ(Expression("ceil(E)").approximate().toString(),
"3");
EXPECT_EQ(Expression("floor(E^10)").approximate().toString(),
"22026");
EXPECT_EQ(Expression("ceil(E^10)").approximate().toString(),
"22027");
EXPECT_EQ(Expression("floor(11^10)").approximate().toString(),
"25937424601");
EXPECT_EQ(Expression("ceil(11^10)").approximate().toString(),
"25937424601");
EXPECT_EQ(Expression("sin(floor(E^10))").approximate().toString(),
"-0.28969263040207500615366554669422425489060452363910610917250538601423874640051459");
EXPECT_EQ(Expression("sin(ceil(E^10))").approximate().toString(),
Expand All @@ -1869,10 +1871,6 @@ TEST(ExpressionTests, approximateTest) {
"-0.4398324432476489878621537810397255512584110903388962591029029773506989984056853");
EXPECT_EQ(Expression("cos(ceil(11^10))").approximate().toString(),
"-0.4398324432476489878621537810397255512584110903388962591029029773506989984056853");
EXPECT_EQ(Expression("tan(floor(E/3))").approximate().toString(),
"0");
EXPECT_EQ(Expression("tan(ceil(-E/3))").approximate().toString(),
"0");
EXPECT_EQ(Expression("ln(floor(E^10))").approximate().toString(),
"9.9999788527248892938130978462467834105024172271892998574080180654845967473754541");
EXPECT_EQ(Expression("root(ceil(E^10), 3)").approximate().toString(),
Expand All @@ -1881,10 +1879,6 @@ TEST(ExpressionTests, approximateTest) {
"23.978952727983705440619435779651292998217068539374171752185677091305736239132367");
EXPECT_EQ(Expression("root(ceil(11^10), 3)").approximate().toString(),
"2960.117500547758958671098654417191228566388539497004587135829271326993708483441");
EXPECT_EQ(Expression("ln(floor(E/3))").approximate().toString(),
"-Inf");
EXPECT_EQ(Expression("root(ceil(-E/3), 3)").approximate().toString(),
"0");

EXPECT_EQ(Expression("(2/3)!").approximate().toString(),
"0.90274529295093361129685868543634252367955151070452913226268164530918864360116169");
Expand Down
10 changes: 10 additions & 0 deletions tests/src/expressions/unary/RoundExpressionTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <gtest/gtest.h>

#include "fintamath/functions/ntheory/Floor.hpp"
#include "fintamath/numbers/Integer.hpp"

using namespace fintamath;

TEST(RoundExpressionTests, getTypeTest) {
EXPECT_EQ(floorExpr(Integer(0).clone())->getType(), MathObjectType::RoundExpression);
}

0 comments on commit 7dc5b36

Please sign in to comment.