Skip to content

Commit

Permalink
Implement ComplexInf
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Jul 28, 2023
1 parent c092e4b commit 3f7e136
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 20 deletions.
1 change: 1 addition & 0 deletions include/fintamath/core/MathObjectTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum class MathObjectType : MathObjectTypeId {
False,
Inf,
NegInf,
ComplexInf,
Undefined,

IFunction = 11000,
Expand Down
22 changes: 22 additions & 0 deletions include/fintamath/literals/constants/ComplexInf.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include "fintamath/literals/constants/IConstant.hpp"
#include "fintamath/numbers/INumber.hpp"

namespace fintamath {

class ComplexInf : public IConstantCRTP<INumber, ComplexInf> {
public:
std::string toString() const override {
return "ComplexInf";
}

static MathObjectTypeId getTypeIdStatic() {
return MathObjectTypeId(MathObjectType::ComplexInf);
}

protected:
std::unique_ptr<IMathObject> call() const override;
};

}
2 changes: 2 additions & 0 deletions src/fintamath/config/ParserConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "fintamath/literals/Boolean.hpp"
#include "fintamath/literals/ILiteral.hpp"
#include "fintamath/literals/Variable.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/E.hpp"
#include "fintamath/literals/constants/False.hpp"
#include "fintamath/literals/constants/IConstant.hpp"
Expand Down Expand Up @@ -170,6 +171,7 @@ struct ParserConfig {
IConstant::registerType<False>();
IConstant::registerType<Inf>();
IConstant::registerType<NegInf>();
IConstant::registerType<ComplexInf>();
IConstant::registerType<Undefined>();

IFunction::registerType<Abs>();
Expand Down
9 changes: 5 additions & 4 deletions src/fintamath/expressions/binary/DivExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "fintamath/functions/arithmetic/Neg.hpp"
#include "fintamath/functions/arithmetic/Sub.hpp"
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/Inf.hpp"
#include "fintamath/literals/constants/NegInf.hpp"
#include "fintamath/literals/constants/Undefined.hpp"
Expand Down Expand Up @@ -53,8 +54,8 @@ DivExpression::SimplifyFunctionsVector DivExpression::getFunctionsForPostSimplif
}

ArgumentPtr DivExpression::constSimplify(const IFunction & /*func*/, const ArgumentPtr &lhs, const ArgumentPtr &rhs) {
if ((*lhs == Integer(0) || is<Inf>(lhs) || is<NegInf>(lhs)) &&
(*rhs == Integer(0) || is<Inf>(rhs) || is<NegInf>(rhs))) {
if ((*lhs == Integer(0) || is<Inf>(lhs) || is<NegInf>(lhs) || is<ComplexInf>(lhs)) &&
(*rhs == Integer(0) || is<Inf>(rhs) || is<NegInf>(rhs) || is<ComplexInf>(rhs))) {

return Undefined().clone();
}
Expand All @@ -64,10 +65,10 @@ ArgumentPtr DivExpression::constSimplify(const IFunction & /*func*/, const Argum
}

if (*rhs == Integer(0)) {
return Inf().clone();
return ComplexInf().clone();
}

if (is<Inf>(rhs) || is<NegInf>(rhs)) {
if (is<Inf>(rhs) || is<NegInf>(rhs) || is<ComplexInf>(rhs)) {
return Integer(0).clone();
}

Expand Down
11 changes: 9 additions & 2 deletions src/fintamath/expressions/binary/PowExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/functions/powers/Root.hpp"
#include "fintamath/functions/powers/Sqrt.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/Inf.hpp"
#include "fintamath/literals/constants/NegInf.hpp"
#include "fintamath/literals/constants/Undefined.hpp"
Expand Down Expand Up @@ -226,7 +227,7 @@ ArgumentPtr PowExpression::constSimplify(const IFunction & /*func*/, const Argum
return makeExpr(Mul(), mulLhs, mulRhs);
}

if (is<Inf>(lhs)) {
if (is<Inf>(lhs) || is<ComplexInf>(lhs)) {
if (*rhs == Integer(0)) {
return Undefined().clone();
}
Expand All @@ -239,13 +240,19 @@ ArgumentPtr PowExpression::constSimplify(const IFunction & /*func*/, const Argum
}

if (*lhs == Integer(1)) {
if (is<Inf>(rhs)) {
if (is<Inf>(rhs) || is<ComplexInf>(rhs)) {
return Undefined().clone();
}

return lhs;
}

if (is<Inf>(rhs) || is<ComplexInf>(rhs)) {
if (const auto lhsNum = cast<INumber>(lhs)) {
// TODO!!!
}
}

if (*rhs == Integer(0)) {
return Integer(1).clone();
}
Expand Down
7 changes: 6 additions & 1 deletion src/fintamath/expressions/polynomial/AddExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "fintamath/functions/logarithms/Log.hpp"
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/literals/Variable.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/IConstant.hpp"
#include "fintamath/literals/constants/Inf.hpp"
#include "fintamath/literals/constants/NegInf.hpp"
Expand Down Expand Up @@ -104,14 +105,18 @@ ArgumentPtr AddExpression::simplifyConst(const IFunction & /*func*/, const Argum
return lhsChild;
}

if (is<NegInf>(lhsChild) && is<Inf>(rhsChild)) {
if ((is<NegInf>(lhsChild) || is<ComplexInf>(lhsChild)) && (is<Inf>(rhsChild) || is<ComplexInf>(rhsChild))) {
return Undefined().clone();
}

if (is<Inf>(lhsChild) || is<NegInf>(lhsChild)) {
return lhsChild;
}

if (is<Inf>(rhsChild) || is<NegInf>(rhsChild)) {
return rhsChild;
}

return {};
}

Expand Down
7 changes: 4 additions & 3 deletions src/fintamath/expressions/polynomial/MulExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "fintamath/functions/arithmetic/Mul.hpp"
#include "fintamath/functions/arithmetic/Neg.hpp"
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/IConstant.hpp"
#include "fintamath/literals/constants/Inf.hpp"
#include "fintamath/literals/constants/NegInf.hpp"
Expand Down Expand Up @@ -92,15 +93,15 @@ std::pair<ArgumentPtr, ArgumentPtr> MulExpression::getRateValuePair(const Argume
ArgumentPtr MulExpression::simplifyConst(const IFunction & /*func*/, const ArgumentPtr &lhsChild,
const ArgumentPtr &rhsChild) {

if (*lhsChild == Integer(0) && (is<Inf>(rhsChild) || is<NegInf>(rhsChild))) {
if (*lhsChild == Integer(0) && (is<Inf>(rhsChild) || is<NegInf>(rhsChild) || is<ComplexInf>(rhsChild))) {
return Undefined().clone();
}

if (is<NegInf>(lhsChild) && is<Inf>(rhsChild)) {
if ((is<NegInf>(lhsChild) || is<ComplexInf>(lhsChild)) && (is<Inf>(rhsChild) || is<ComplexInf>(rhsChild))) {
return lhsChild;
}

if (is<Inf>(rhsChild) || is<NegInf>(rhsChild)) {
if (is<Inf>(rhsChild) || is<NegInf>(rhsChild) || is<ComplexInf>(rhsChild)) {
if (const auto lhsNum = cast<INumber>(lhsChild)) {
return *lhsNum < Integer(0) ? makeExpr(Neg(), rhsChild) : rhsChild;
}
Expand Down
5 changes: 5 additions & 0 deletions src/fintamath/expressions/unary/NegExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "fintamath/functions/arithmetic/Mul.hpp"
#include "fintamath/functions/arithmetic/Neg.hpp"
#include "fintamath/functions/logarithms/Log.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/Inf.hpp"
#include "fintamath/literals/constants/NegInf.hpp"

Expand Down Expand Up @@ -92,6 +93,10 @@ ArgumentPtr NegExpression::simplifyConst(const IFunction & /*func*/, const Argum
return Inf().clone();
}

if (is<ComplexInf>(rhs)) {
return rhs;
}

return {};
}

Expand Down
8 changes: 4 additions & 4 deletions src/fintamath/functions/arithmetic/Div.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "fintamath/literals/constants/Inf.hpp"
#include "fintamath/numbers/INumber.hpp"

#include "fintamath/functions/arithmetic/Div.hpp"

#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/Undefined.hpp"
#include "fintamath/numbers/INumber.hpp"
#include "fintamath/numbers/Integer.hpp"
#include "fintamath/numbers/Rational.hpp"

Expand All @@ -27,7 +27,7 @@ std::unique_ptr<IMathObject> Div::call(const ArgumentsRefVector &argsVect) const
}

if (rhs == Integer(0)) {
return Inf().clone();
return ComplexInf().clone();
}

if (auto res = multiPow(lhs, rhs)) {
Expand Down
11 changes: 11 additions & 0 deletions src/fintamath/literals/constants/ComplexInf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "fintamath/literals/constants/ComplexInf.hpp"

#include "fintamath/numbers/RealFunctions.hpp"

namespace fintamath {

std::unique_ptr<IMathObject> ComplexInf::call() const {
return clone();
}

}
41 changes: 35 additions & 6 deletions tests/src/expressions/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,31 +672,47 @@ TEST(ExpressionTests, stringConstructorTest) {

EXPECT_EQ(Expression("Inf").toString(), "Inf");
EXPECT_EQ(Expression("-Inf").toString(), "-Inf");
EXPECT_EQ(Expression("1/0").toString(), "Inf");
EXPECT_EQ(Expression("a/0").toString(), "Inf");
EXPECT_EQ(Expression("ComplexInf").toString(), "ComplexInf");
EXPECT_EQ(Expression("-ComplexInf").toString(), "ComplexInf");
EXPECT_EQ(Expression("1/0").toString(), "ComplexInf");
EXPECT_EQ(Expression("a/0").toString(), "ComplexInf");
EXPECT_EQ(Expression("1/Inf").toString(), "0");
EXPECT_EQ(Expression("1/-Inf").toString(), "0");
EXPECT_EQ(Expression("a/Inf").toString(), "0");
EXPECT_EQ(Expression("a/-Inf").toString(), "0");
EXPECT_EQ(Expression("1/ComplexInf").toString(), "0");
EXPECT_EQ(Expression("a/ComplexInf").toString(), "0");
EXPECT_EQ(Expression("Inf + Inf").toString(), "Inf");
EXPECT_EQ(Expression("-Inf - Inf").toString(), "-Inf");
EXPECT_EQ(Expression("10 + Inf").toString(), "Inf");
EXPECT_EQ(Expression("-10 + Inf").toString(), "Inf");
EXPECT_EQ(Expression("10 - Inf").toString(), "-Inf");
EXPECT_EQ(Expression("-10 - Inf").toString(), "-Inf");
EXPECT_EQ(Expression("a + Inf").toString(), "Inf");
EXPECT_EQ(Expression("-a - Inf").toString(), "-Inf");
EXPECT_EQ(Expression("10 * Inf").toString(), "Inf");
EXPECT_EQ(Expression("-10 * Inf").toString(), "-Inf");
EXPECT_EQ(Expression("-2/3 * Inf").toString(), "-Inf");
EXPECT_EQ(Expression("a * Inf").toString(), "Inf a");
EXPECT_EQ(Expression("Inf * Inf").toString(), "Inf");
EXPECT_EQ(Expression("Inf * -Inf").toString(), "-Inf");
EXPECT_EQ(Expression("-Inf * -Inf").toString(), "Inf");
EXPECT_EQ(Expression("ComplexInf*ComplexInf").toString(), "ComplexInf");
EXPECT_EQ(Expression("ComplexInf*Inf").toString(), "ComplexInf");
EXPECT_EQ(Expression("ComplexInf*-Inf").toString(), "ComplexInf");
EXPECT_EQ(Expression("Inf^2").toString(), "Inf");
EXPECT_EQ(Expression("Inf^(2/3)").toString(), "Inf");
EXPECT_EQ(Expression("(-Inf)^2").toString(), "Inf");
EXPECT_EQ(Expression("(-Inf)^3").toString(), "-Inf");
// EXPECT_EQ(Expression("(-Inf)^(2/3)").toString(), "-Inf"); // TODO! complex numbers
EXPECT_EQ(Expression("0^Inf").toString(), "0");
EXPECT_EQ(Expression("0^-Inf").toString(), "Inf");
EXPECT_EQ(Expression("2^Inf").toString(), "ComplexInf");
EXPECT_EQ(Expression("2^-Inf").toString(), "0");
EXPECT_EQ(Expression("2^ComplexInf").toString(), "ComplexInf");
EXPECT_EQ(Expression("0.2^Inf").toString(), "0");
EXPECT_EQ(Expression("0.2^-Inf").toString(), "ComplexInf");
EXPECT_EQ(Expression("0.2^ComplexInf").toString(), "0");
EXPECT_EQ(Expression("sqrt(2) * Inf").toString(), "Inf sqrt(2)"); // TODO! Inf
EXPECT_EQ(Expression("-sqrt(2) * Inf").toString(), "-Inf sqrt(2)"); // TODO! -Inf
EXPECT_EQ(Expression("sin(Inf)").toString(), "sin(Inf)"); // TODO: [-1, 1]
Expand All @@ -705,7 +721,12 @@ TEST(ExpressionTests, stringConstructorTest) {

EXPECT_EQ(Expression("0*Inf").toString(), "Undefined");
EXPECT_EQ(Expression("0*-Inf").toString(), "Undefined");
EXPECT_EQ(Expression("0*ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("Inf - Inf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf - ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf + ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf + Inf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf - Inf").toString(), "Undefined");
EXPECT_EQ(Expression("0/0").toString(), "Undefined");
EXPECT_EQ(Expression("Inf/Inf").toString(), "Undefined");
EXPECT_EQ(Expression("0/Inf").toString(), "Undefined");
Expand All @@ -715,16 +736,20 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("-Inf/0").toString(), "Undefined");
EXPECT_EQ(Expression("Inf/-Inf").toString(), "Undefined");
EXPECT_EQ(Expression("-Inf/Inf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf/ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("0/ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf/0").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf/Inf").toString(), "Undefined");
EXPECT_EQ(Expression("ComplexInf/-Inf").toString(), "Undefined");
EXPECT_EQ(Expression("Inf/ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("-Inf/ComplexInf").toString(), "Undefined");
EXPECT_EQ(Expression("-Inf + Inf").toString(), "Undefined");
EXPECT_EQ(Expression("Inf - Inf").toString(), "Undefined");
EXPECT_EQ(Expression("0^0").toString(), "Undefined");
EXPECT_EQ(Expression("Inf^0").toString(), "Undefined");
EXPECT_EQ(Expression("1^Inf").toString(), "Undefined");
EXPECT_EQ(Expression("1^-Inf").toString(), "Undefined");
EXPECT_EQ(Expression("Inf = Inf").toString(), "Undefined");
EXPECT_EQ(Expression("Inf - Inf = 0").toString(), "Undefined");
EXPECT_EQ(Expression("Inf - Inf = 0 | a").toString(), "Undefined");
EXPECT_EQ(Expression("~Undefined").toString(), "Undefined");
EXPECT_EQ(Expression("1^ComplexInf").toString(), "Undefined");

EXPECT_EQ(Expression("Undefined").toString(), "Undefined");
EXPECT_EQ(Expression("-Undefined").toString(), "Undefined");
Expand All @@ -740,6 +765,10 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("0^((2^2 - 4)^0)").toString(), "Undefined");
EXPECT_EQ(Expression("-((2^2 - 4)^0)").toString(), "Undefined");
EXPECT_EQ(Expression("Undefined = Undefined").toString(), "Undefined");
EXPECT_EQ(Expression("Inf = Inf").toString(), "Undefined");
EXPECT_EQ(Expression("Inf - Inf = 0").toString(), "Undefined");
EXPECT_EQ(Expression("Inf - Inf = 0 | a").toString(), "Undefined");
EXPECT_EQ(Expression("~Undefined").toString(), "Undefined");
EXPECT_EQ(Expression("0/0 = 0/0").toString(), "Undefined");
}

Expand Down
1 change: 1 addition & 0 deletions tests/src/functions/arithmetic/DivTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ TEST(DivTests, callTest) {

EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "3/a");

EXPECT_EQ(f(Integer(1), Integer(0))->toString(), "ComplexInf");
EXPECT_EQ(f(Integer(0), Integer(0))->toString(), "Undefined");

EXPECT_THROW(f(Integer(1)), InvalidInputFunctionException);
Expand Down
2 changes: 2 additions & 0 deletions tests/src/parser/ParserTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "fintamath/literals/Boolean.hpp"
#include "fintamath/literals/ILiteral.hpp"
#include "fintamath/literals/Variable.hpp"
#include "fintamath/literals/constants/ComplexInf.hpp"
#include "fintamath/literals/constants/E.hpp"
#include "fintamath/literals/constants/False.hpp"
#include "fintamath/literals/constants/IConstant.hpp"
Expand Down Expand Up @@ -183,6 +184,7 @@ TEST(ParseTests, parseConstantTest) {
EXPECT_TRUE(is<False>(IConstant::parse("False")));
EXPECT_TRUE(is<Inf>(IConstant::parse("Inf")));
EXPECT_TRUE(is<NegInf>(IConstant::parse("-Inf")));
EXPECT_TRUE(is<ComplexInf>(IConstant::parse("ComplexInf")));
EXPECT_TRUE(is<Undefined>(IConstant::parse("Undefined")));

EXPECT_EQ(IConstant::parse("a"), nullptr);
Expand Down

0 comments on commit 3f7e136

Please sign in to comment.