diff --git a/include/fintamath/expressions/ExpressionUtils.hpp b/include/fintamath/expressions/ExpressionUtils.hpp index 59bb03b8e..31d8ac736 100644 --- a/include/fintamath/expressions/ExpressionUtils.hpp +++ b/include/fintamath/expressions/ExpressionUtils.hpp @@ -15,6 +15,8 @@ std::string putInSpaces(const std::string &str); std::string functionToString(const IFunction &func, const ArgumentsPtrVector &args); +std::string operatorChildToString(const IOperator &oper, const ArgumentPtr &child); + std::string binaryOperatorToString(const IOperator &oper, const ArgumentPtr &lhs, const ArgumentPtr &rhs); std::string prefixUnaryOperatorToString(const IOperator &oper, const ArgumentPtr &rhs); @@ -27,6 +29,8 @@ bool hasVariable(const ArgumentPtr &arg, const Variable &var); bool hasInfinity(const ArgumentPtr &arg); +bool hasComplex(const ArgumentPtr &arg); + bool isInfinity(const ArgumentPtr &arg); bool isNegated(const ArgumentPtr &arg); diff --git a/include/fintamath/expressions/interfaces/IPolynomExpression.hpp b/include/fintamath/expressions/interfaces/IPolynomExpression.hpp index 2794c1169..5ba38d2a1 100644 --- a/include/fintamath/expressions/interfaces/IPolynomExpression.hpp +++ b/include/fintamath/expressions/interfaces/IPolynomExpression.hpp @@ -43,7 +43,7 @@ class IPolynomExpression : public IExpression { virtual SimplifyFunctionsVector getFunctionsForPostSimplify() const; - virtual std::string operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const; + virtual std::string childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const; /** * @brief diff --git a/include/fintamath/functions/powers/Pow.hpp b/include/fintamath/functions/powers/Pow.hpp index e5abea176..9596918c8 100644 --- a/include/fintamath/functions/powers/Pow.hpp +++ b/include/fintamath/functions/powers/Pow.hpp @@ -8,6 +8,7 @@ namespace fintamath { class Integer; class Rational; class Real; +class Complex; class Pow : public IOperatorCRTP { public: @@ -33,6 +34,8 @@ class Pow : public IOperatorCRTP { static std::unique_ptr powSimplify(const Rational &lhs, const Rational &rhs); static std::unique_ptr powSimplify(const Real &lhs, const Real &rhs); + + static std::unique_ptr powSimplify(const Complex &lhs, const Complex &rhs); }; FINTAMATH_FUNCTION_EXPRESSION(Pow, powExpr); diff --git a/src/fintamath/expressions/ExpressionUtils.cpp b/src/fintamath/expressions/ExpressionUtils.cpp index 3bb02b72c..9c25a50f6 100644 --- a/src/fintamath/expressions/ExpressionUtils.cpp +++ b/src/fintamath/expressions/ExpressionUtils.cpp @@ -6,11 +6,13 @@ #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" #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" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -47,7 +49,20 @@ std::string operatorChildToString(const IOperator &oper, const ArgumentPtr &chil if (const auto childExpr = cast(child)) { childOper = cast(childExpr->getOutputFunction()); } - else if (operPriority <= IOperator::Priority::PrefixUnary && childStr.front() == Neg().toString().front()) { + else if (const auto childComplex = cast(child)) { + if (childComplex->real() != Integer(0)) { + childOper = std::make_shared(); + } + else if (childComplex->imag() != Integer(1)) { + if (childComplex->imag() == Integer(-1)) { + childOper = std::make_shared(); + } + else { + childOper = std::make_shared(); + } + } + } + else if (childStr.front() == Neg().toString().front()) { childOper = std::make_shared(); } else if (is(child)) { @@ -62,12 +77,11 @@ std::string operatorChildToString(const IOperator &oper, const ArgumentPtr &chil if (childOper) { IOperator::Priority lhsOperPriority = childOper->getOperatorPriority(); - if (operPriority == IOperator::Priority::Multiplication) { - return putInBrackets(childStr); - } - - if (lhsOperPriority >= operPriority || - (lhsOperPriority == operPriority && !oper.isAssociative())) { + if (lhsOperPriority > operPriority || + (lhsOperPriority == operPriority && + childOper->getFunctionType() == IFunction::Type::Unary) || + (!oper.isAssociative() && + childOper->getFunctionType() != IFunction::Type::Unary)) { return putInBrackets(childStr); } @@ -169,6 +183,29 @@ bool hasInfinity(const ArgumentPtr &arg) { }); } +bool hasComplex(const ArgumentPtr &arg) { + if (const auto num = cast(arg); num && num->isComplex()) { + return true; + } + + auto expr = cast(arg); + if (!expr) { + return false; + } + + ArgumentsPtrVector children = expr->getChildren(); + + return std::any_of(children.begin(), children.end(), [](const auto &child) { + bool res = false; + + if (hasComplex(child)) { + res = true; + } + + return res; + }); +} + bool isInfinity(const ArgumentPtr &arg) { return is(arg) || is(arg) || is(arg); } diff --git a/src/fintamath/expressions/IExpression.cpp b/src/fintamath/expressions/IExpression.cpp index 61a071aa9..049261310 100644 --- a/src/fintamath/expressions/IExpression.cpp +++ b/src/fintamath/expressions/IExpression.cpp @@ -142,13 +142,7 @@ ArgumentPtr IExpression::callFunction(const IFunction &func, const ArgumentsPtrV return {}; } - ArgumentPtr res; - try { - res = func(args); - } - catch (const UndefinedException &) { - return {}; - } + ArgumentPtr res = func(args); if (areArgumentsPrecise) { if (const auto num = cast(res); num && !num->isPrecise()) { diff --git a/src/fintamath/expressions/binary/CompExpression.cpp b/src/fintamath/expressions/binary/CompExpression.cpp index 4bb0711d0..06989e3c1 100644 --- a/src/fintamath/expressions/binary/CompExpression.cpp +++ b/src/fintamath/expressions/binary/CompExpression.cpp @@ -55,6 +55,12 @@ ArgumentPtr CompExpression::preSimplify() const { if (!simplExpr->isSolution && (!is(rhsChild) || *rhsChild != Integer(0))) { + if (*func != Eqv() && *func != Neqv() && + (hasComplex(lhsChild) || hasComplex(rhsChild))) { + + return simpl; + } + if (!hasInfinity(lhsChild) && !hasInfinity(rhsChild)) { ArgumentPtr resLhs = subExpr(simplExpr->lhsChild, simplExpr->rhsChild); preSimplifyChild(resLhs); diff --git a/src/fintamath/expressions/interfaces/IPolynomExpression.cpp b/src/fintamath/expressions/interfaces/IPolynomExpression.cpp index 1dc513719..2e984c048 100644 --- a/src/fintamath/expressions/interfaces/IPolynomExpression.cpp +++ b/src/fintamath/expressions/interfaces/IPolynomExpression.cpp @@ -26,10 +26,10 @@ std::string IPolynomExpression::toString() const { std::string result; - result += operatorChildToString(children.front(), {}); + result += childToString(children.front(), {}); for (size_t i = 1; i < children.size(); i++) { - result += operatorChildToString(children[i], children[i - 1]); + result += childToString(children[i], children[i - 1]); } return result; @@ -180,22 +180,16 @@ ArgumentPtr IPolynomExpression::preciseSimplify() const { return preciseExpr; } -std::string IPolynomExpression::operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { - std::string result = inChild->toString(); - - if (const auto exprChild = cast(inChild)) { - const auto oper = cast(func); - const auto childOper = cast(exprChild->getFunction()); - - if (oper && - childOper && - oper->getOperatorPriority() <= childOper->getOperatorPriority()) { - - result = putInBrackets(result); - } +std::string IPolynomExpression::childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { + std::string childStr; + if (const auto oper = cast(func)) { + childStr = operatorChildToString(*oper, inChild); + } + else { + childStr = inChild->toString(); } - return prevChild ? (putInSpaces(func->toString()) + result) : result; + return prevChild ? (putInSpaces(func->toString()) + childStr) : childStr; } bool IPolynomExpression::isTermsOrderInversed() const { diff --git a/src/fintamath/expressions/polynomial/AddExpression.cpp b/src/fintamath/expressions/polynomial/AddExpression.cpp index 77455d7e7..76f4f0538 100644 --- a/src/fintamath/expressions/polynomial/AddExpression.cpp +++ b/src/fintamath/expressions/polynomial/AddExpression.cpp @@ -22,11 +22,10 @@ AddExpression::AddExpression(const ArgumentsPtrVector &inChildren) : IPolynomExpressionCRTP(Add(), inChildren) { } -std::string AddExpression::operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { +std::string AddExpression::childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { + std::string result = operatorChildToString(Add(), inChild); bool isChildNegated = false; - std::string result = inChild->toString(); - if (result.size() > 1 && result.front() == Neg().toString().front()) { diff --git a/src/fintamath/expressions/polynomial/AddExpression.hpp b/src/fintamath/expressions/polynomial/AddExpression.hpp index 0ba978d46..2bfe7e71f 100644 --- a/src/fintamath/expressions/polynomial/AddExpression.hpp +++ b/src/fintamath/expressions/polynomial/AddExpression.hpp @@ -17,7 +17,7 @@ class AddExpression : public IPolynomExpressionCRTP { SimplifyFunctionsVector getFunctionsForPostSimplify() const override; - std::string operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const override; + std::string childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const override; /** * @brief diff --git a/src/fintamath/expressions/polynomial/MulExpression.cpp b/src/fintamath/expressions/polynomial/MulExpression.cpp index e9b020687..cfd068e0d 100644 --- a/src/fintamath/expressions/polynomial/MulExpression.cpp +++ b/src/fintamath/expressions/polynomial/MulExpression.cpp @@ -50,7 +50,7 @@ std::string MulExpression::toString() const { return IPolynomExpression::toString(); } -std::string MulExpression::operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { +std::string MulExpression::childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { if (!prevChild && *inChild == Integer(-1)) { return Neg().toString(); } @@ -65,7 +65,7 @@ std::string MulExpression::operatorChildToString(const ArgumentPtr &inChild, con } } - return operStr + inChild->toString(); + return operStr + operatorChildToString(Mul(), inChild); } MulExpression::SimplifyFunctionsVector MulExpression::getFunctionsForPreSimplify() const { diff --git a/src/fintamath/expressions/polynomial/MulExpression.hpp b/src/fintamath/expressions/polynomial/MulExpression.hpp index cb237b77e..7ff619410 100644 --- a/src/fintamath/expressions/polynomial/MulExpression.hpp +++ b/src/fintamath/expressions/polynomial/MulExpression.hpp @@ -14,7 +14,7 @@ class MulExpression : public IPolynomExpressionCRTP { } protected: - std::string operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const override; + std::string childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const override; SimplifyFunctionsVector getFunctionsForPreSimplify() const override; diff --git a/src/fintamath/expressions/polynomial/OrExpression.cpp b/src/fintamath/expressions/polynomial/OrExpression.cpp index 00ce5d3f0..0c69ec287 100644 --- a/src/fintamath/expressions/polynomial/OrExpression.cpp +++ b/src/fintamath/expressions/polynomial/OrExpression.cpp @@ -11,8 +11,8 @@ OrExpression::OrExpression(const ArgumentsPtrVector &inChildren) : IPolynomExpressionCRTP(Or(), inChildren) { } -std::string OrExpression::operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { - std::string result = inChild->toString(); +std::string OrExpression::childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const { + std::string result = operatorChildToString(Or(), inChild); if (const auto &childExpr = cast(inChild); childExpr && is(childExpr->getFunction())) { diff --git a/src/fintamath/expressions/polynomial/OrExpression.hpp b/src/fintamath/expressions/polynomial/OrExpression.hpp index 8f8e1b561..1c622a71a 100644 --- a/src/fintamath/expressions/polynomial/OrExpression.hpp +++ b/src/fintamath/expressions/polynomial/OrExpression.hpp @@ -13,7 +13,7 @@ class OrExpression : public IPolynomExpressionCRTP { } protected: - std::string operatorChildToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const override; + std::string childToString(const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const override; ArgumentPtr postSimplify() const override; diff --git a/src/fintamath/functions/calculus/Max.cpp b/src/fintamath/functions/calculus/Max.cpp index 5ea435e28..cf656793e 100644 --- a/src/fintamath/functions/calculus/Max.cpp +++ b/src/fintamath/functions/calculus/Max.cpp @@ -1,5 +1,7 @@ #include "fintamath/functions/calculus/Max.hpp" +#include "fintamath/numbers/Complex.hpp" + namespace fintamath { std::unique_ptr Max::call(const ArgumentsRefVector &argsVect) const { @@ -8,10 +10,9 @@ std::unique_ptr Max::call(const ArgumentsRefVector &argsVect) const for (size_t i = 1; i < argsVect.size(); i++) { std::reference_wrapper arg = cast(argsVect[i].get()); - // TODO! uncomment - // if (is(arg)) { - // return {}; - // } + if (is(arg)) { + return {}; + } if (res < arg) { res = arg; diff --git a/src/fintamath/functions/calculus/Min.cpp b/src/fintamath/functions/calculus/Min.cpp index 8141f81ab..eb241e6ff 100644 --- a/src/fintamath/functions/calculus/Min.cpp +++ b/src/fintamath/functions/calculus/Min.cpp @@ -1,4 +1,5 @@ #include "fintamath/functions/calculus/Min.hpp" +#include "fintamath/numbers/Complex.hpp" namespace fintamath { @@ -8,10 +9,9 @@ std::unique_ptr Min::call(const ArgumentsRefVector &argsVect) const for (size_t i = 1; i < argsVect.size(); i++) { std::reference_wrapper arg = cast(argsVect[i].get()); - // TODO! uncomment - // if (is(arg)) { - // return {}; - // } + if (is(arg)) { + return {}; + } if (res > arg) { res = arg; diff --git a/src/fintamath/functions/comparison/Less.cpp b/src/fintamath/functions/comparison/Less.cpp index 73c680c49..f1e08da8b 100644 --- a/src/fintamath/functions/comparison/Less.cpp +++ b/src/fintamath/functions/comparison/Less.cpp @@ -1,6 +1,6 @@ #include "fintamath/functions/comparison/Less.hpp" -#include "fintamath/literals/constants/Undefined.hpp" +#include "fintamath/numbers/Complex.hpp" namespace fintamath { @@ -8,10 +8,9 @@ std::unique_ptr Less::call(const ArgumentsRefVector &argsVect) cons const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); - // TODO! uncomment - // if (is(lhs) || is(rhs)) { - // return {}; - // } + if (is(lhs) || is(rhs)) { + return {}; + } return Boolean(lhs < rhs).clone(); } diff --git a/src/fintamath/functions/comparison/LessEqv.cpp b/src/fintamath/functions/comparison/LessEqv.cpp index 5ad193ec6..3d0bfc7e6 100644 --- a/src/fintamath/functions/comparison/LessEqv.cpp +++ b/src/fintamath/functions/comparison/LessEqv.cpp @@ -1,15 +1,16 @@ #include "fintamath/functions/comparison/LessEqv.hpp" +#include "fintamath/numbers/Complex.hpp" + namespace fintamath { std::unique_ptr LessEqv::call(const ArgumentsRefVector &argsVect) const { const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); - // TODO! uncomment - // if (is(lhs) || is(rhs)) { - // return {}; - // } + if (is(lhs) || is(rhs)) { + return {}; + } return Boolean(lhs <= rhs).clone(); } diff --git a/src/fintamath/functions/comparison/More.cpp b/src/fintamath/functions/comparison/More.cpp index e34dd84a8..0c4d175f3 100644 --- a/src/fintamath/functions/comparison/More.cpp +++ b/src/fintamath/functions/comparison/More.cpp @@ -1,15 +1,16 @@ #include "fintamath/functions/comparison/More.hpp" +#include "fintamath/numbers/Complex.hpp" + namespace fintamath { std::unique_ptr More::call(const ArgumentsRefVector &argsVect) const { const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); - // TODO! uncomment - // if (is(lhs) || is(rhs)) { - // return {}; - // } + if (is(lhs) || is(rhs)) { + return {}; + } return Boolean(lhs > rhs).clone(); } diff --git a/src/fintamath/functions/comparison/MoreEqv.cpp b/src/fintamath/functions/comparison/MoreEqv.cpp index 3d80ba1b4..f9200b809 100644 --- a/src/fintamath/functions/comparison/MoreEqv.cpp +++ b/src/fintamath/functions/comparison/MoreEqv.cpp @@ -1,15 +1,16 @@ #include "fintamath/functions/comparison/MoreEqv.hpp" +#include "fintamath/numbers/Complex.hpp" + namespace fintamath { std::unique_ptr MoreEqv::call(const ArgumentsRefVector &argsVect) const { const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); - // TODO! uncomment - // if (is(lhs) || is(rhs)) { - // return {}; - // } + if (is(lhs) || is(rhs)) { + return {}; + } return Boolean(lhs >= rhs).clone(); } diff --git a/src/fintamath/functions/hyperbolic/Acosh.cpp b/src/fintamath/functions/hyperbolic/Acosh.cpp index 8f67652f7..0ee8ad6fc 100644 --- a/src/fintamath/functions/hyperbolic/Acosh.cpp +++ b/src/fintamath/functions/hyperbolic/Acosh.cpp @@ -1,6 +1,10 @@ #include "fintamath/functions/hyperbolic/Acosh.hpp" #include "fintamath/exceptions/UndefinedException.hpp" +#include "fintamath/functions/arithmetic/Div.hpp" +#include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/literals/constants/I.hpp" +#include "fintamath/literals/constants/Pi.hpp" #include "fintamath/numbers/RealFunctions.hpp" namespace fintamath { @@ -8,15 +12,15 @@ namespace fintamath { std::unique_ptr Acosh::call(const ArgumentsRefVector &argsVect) const { const auto &rhs = cast(argsVect.front().get()); - // TODO! uncomment - // if (rhs == Integer(-1)) { - // return I Pi; - // } + if (rhs == Integer(-1)) { + static const auto res = mulExpr(I(), Pi())->toMinimalObject(); + return res->clone(); + } - // TODO! uncomment - // if (rhs == Integer(0)) { - // return I Pi / 2; - // } + if (rhs == Integer(0)) { + static const auto res = divExpr(mulExpr(I(), Pi()), Integer(2).clone())->toMinimalObject(); + return res->clone(); + } if (rhs == Integer(1)) { return Integer(0).clone(); diff --git a/src/fintamath/functions/hyperbolic/Acoth.cpp b/src/fintamath/functions/hyperbolic/Acoth.cpp index 72e500bf9..9fe9c8773 100644 --- a/src/fintamath/functions/hyperbolic/Acoth.cpp +++ b/src/fintamath/functions/hyperbolic/Acoth.cpp @@ -1,8 +1,12 @@ #include "fintamath/functions/hyperbolic/Acoth.hpp" #include "fintamath/exceptions/UndefinedException.hpp" +#include "fintamath/functions/arithmetic/Div.hpp" +#include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/literals/constants/I.hpp" #include "fintamath/literals/constants/Inf.hpp" #include "fintamath/literals/constants/NegInf.hpp" +#include "fintamath/literals/constants/Pi.hpp" #include "fintamath/numbers/RealFunctions.hpp" namespace fintamath { @@ -14,10 +18,10 @@ std::unique_ptr Acoth::call(const ArgumentsRefVector &argsVect) con return NegInf().clone(); } - // TODO! uncomment - // if (rhs == Integer(0)) { - // return I Pi / 2; - // } + if (rhs == Integer(0)) { + static const auto res = divExpr(mulExpr(I(), Pi()), Integer(2).clone())->toMinimalObject(); + return res->clone(); + } if (rhs == Integer(1)) { return Inf().clone(); diff --git a/src/fintamath/functions/logarithms/Ln.cpp b/src/fintamath/functions/logarithms/Ln.cpp index d4b521cb9..0470485c4 100644 --- a/src/fintamath/functions/logarithms/Ln.cpp +++ b/src/fintamath/functions/logarithms/Ln.cpp @@ -1,5 +1,6 @@ #include "fintamath/functions/logarithms/Ln.hpp" +#include "fintamath/exceptions/UndefinedException.hpp" #include "fintamath/functions/logarithms/Log.hpp" #include "fintamath/literals/constants/E.hpp" #include "fintamath/literals/constants/NegInf.hpp" @@ -34,7 +35,12 @@ std::unique_ptr Ln::multiLnSimplify(const INumber &rhs) { }); outMultiLn.add([](const Real &inRhs) { - return ln(inRhs).toMinimalObject(); + try { + return ln(inRhs).toMinimalObject(); + } + catch (const UndefinedException &) { + return std::unique_ptr{}; + } }); return outMultiLn; diff --git a/src/fintamath/functions/logarithms/Log.cpp b/src/fintamath/functions/logarithms/Log.cpp index a97d7fe0a..4101e4637 100644 --- a/src/fintamath/functions/logarithms/Log.cpp +++ b/src/fintamath/functions/logarithms/Log.cpp @@ -22,11 +22,6 @@ std::unique_ptr Log::call(const ArgumentsRefVector &argsVect) const return ComplexInf().clone(); } - if (lhs < Integer(0) || rhs < Integer(0)) { - // TODO: cast to Complex, when it is implemented - throw UndefinedFunctionException(toString(), {lhs.toString(), rhs.toString()}); - } - if (lhs == Integer(0)) { if (rhs == Integer(0)) { return Undefined().clone(); @@ -51,6 +46,11 @@ std::unique_ptr Log::call(const ArgumentsRefVector &argsVect) const return Integer(1).clone(); } + if (lhs < Integer(0) || rhs < Integer(0)) { + // TODO: complex log + return {}; + } + if (lhs < Integer(1)) { auto newLhs = Rational(1) / lhs; @@ -59,12 +59,16 @@ std::unique_ptr Log::call(const ArgumentsRefVector &argsVect) const return multiLogSimplify(*newLhs, *newRhs); } - return Neg()(*multiLogSimplify(*newLhs, rhs)); + if (auto res = multiLogSimplify(*newLhs, rhs)) { + return negExpr(std::move(res))->toMinimalObject(); + } } if (rhs < Integer(1)) { auto newRhs = Rational(1) / rhs; - return Neg()(*multiLogSimplify(lhs, *newRhs)); + if (auto res = multiLogSimplify(lhs, *newRhs)) { + return negExpr(std::move(res))->toMinimalObject(); + } } return multiLogSimplify(lhs, rhs); @@ -126,7 +130,12 @@ std::unique_ptr Log::logSimplify(const Rational &lhs, const Rationa } std::unique_ptr Log::logSimplify(const Real &lhs, const Real &rhs) { - return log(lhs, rhs).toMinimalObject(); + try { + return log(lhs, rhs).toMinimalObject(); + } + catch (const UndefinedException &) { + return {}; + } } } diff --git a/src/fintamath/functions/powers/Pow.cpp b/src/fintamath/functions/powers/Pow.cpp index 210cca7d7..4a1b148f7 100644 --- a/src/fintamath/functions/powers/Pow.cpp +++ b/src/fintamath/functions/powers/Pow.cpp @@ -4,6 +4,7 @@ #include "fintamath/functions/powers/Sqrt.hpp" #include "fintamath/literals/constants/ComplexInf.hpp" #include "fintamath/literals/constants/Undefined.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Integer.hpp" #include "fintamath/numbers/IntegerFunctions.hpp" #include "fintamath/numbers/Rational.hpp" @@ -47,6 +48,10 @@ std::unique_ptr Pow::multiPowSimplify(const INumber &lhs, const INu return powSimplify(inLhs, inRhs); }); + outMultiPow.add([](const Complex &inLhs, const Complex &inRhs) { + return powSimplify(inLhs, inRhs); + }); + return outMultiPow; }(); @@ -77,8 +82,8 @@ std::unique_ptr Pow::powSimplify(const Rational &lhs, const Rationa return pow(lhs, rhsNumerator).toMinimalObject(); } - if (lhs < Integer(0)) { - // TODO: complex numbers + // TODO: complex nth roots + if (lhs < Integer(0) && rhsDenominator != Integer(2)) { return {}; } @@ -98,4 +103,14 @@ std::unique_ptr Pow::powSimplify(const Real &lhs, const Real &rhs) } } +std::unique_ptr Pow::powSimplify(const Complex &lhs, const Complex &rhs) { + if (rhs.imag() == Integer(0)) { + if (const auto *rhsInt = cast(&rhs.real())) { + return pow(lhs, *rhsInt).toMinimalObject(); + } + } + + return {}; +} + } diff --git a/src/fintamath/functions/powers/Root.cpp b/src/fintamath/functions/powers/Root.cpp index 4c2881071..eec9a489d 100644 --- a/src/fintamath/functions/powers/Root.cpp +++ b/src/fintamath/functions/powers/Root.cpp @@ -3,7 +3,9 @@ #include "fintamath/functions/arithmetic/Add.hpp" #include "fintamath/functions/arithmetic/Div.hpp" #include "fintamath/functions/arithmetic/Mul.hpp" +#include "fintamath/functions/arithmetic/Neg.hpp" #include "fintamath/functions/powers/Pow.hpp" +#include "fintamath/literals/constants/I.hpp" #include "fintamath/numbers/Integer.hpp" #include "fintamath/numbers/IntegerFunctions.hpp" #include "fintamath/numbers/Rational.hpp" @@ -16,21 +18,27 @@ std::unique_ptr Root::call(const ArgumentsRefVector &argsVect) cons const auto &lhs = cast(argsVect.front().get()); const auto &rhs = cast(argsVect.back().get()); - if (lhs == Integer(1)) { + if (lhs == Integer(1) || rhs == Integer(1)) { return lhs.clone(); } if (const auto *rhsIntPtr = cast(&rhs)) { const auto &rhsInt = *rhsIntPtr; - if (rhsInt > Integer(1)) { - if (lhs < Integer(0)) { - // TODO: complex numbers - return {}; + if (!lhs.isComplex() && lhs < Integer(0)) { + if (rhsInt % 2 == 1) { + return Neg()(*multiRootSimplify(*(-lhs), rhsInt)); } - return multiRootSimplify(lhs, rhsInt); + if (rhsInt == Integer(2)) { + return Mul()(*multiRootSimplify(*(-lhs), rhsInt), I()); + } + + // TODO: solve complex nth roots + return {}; } + + return multiRootSimplify(lhs, rhsInt); } return Pow()(lhs, *(Rational(1) / rhs)); diff --git a/tests/src/expressions/ExpressionFunctionsTests.cpp b/tests/src/expressions/ExpressionFunctionsTests.cpp index 047ae998b..5fe0a4154 100644 --- a/tests/src/expressions/ExpressionFunctionsTests.cpp +++ b/tests/src/expressions/ExpressionFunctionsTests.cpp @@ -225,12 +225,13 @@ TEST(ExpressionFunctionsTests, orTest) { TEST(ExpressionFunctionsTests, solveTest) { EXPECT_EQ(solve(Expression("x - 10 = 0")).toString(), "x = 10"); EXPECT_EQ(solve(Expression("-10 - x = 0")).toString(), "x = -10"); - EXPECT_EQ(solve(Expression("x = x sqrt(x)")).toString(), "x^(3/2) - x = 0"); + + EXPECT_EQ(solve(Expression("z - 10 - I = 0")).toString(), "z = 10 + I"); + EXPECT_EQ(solve(Expression("(6 + 3I)^2 = 4I - 30z")).toString(), "z = -9/10 - 16/15 I"); EXPECT_EQ(solve(Expression("x^2 - 10 = 39")).toString(), "x = -7 | x = 7"); EXPECT_EQ(solve(Expression("x^2 = 0")).toString(), "x = 0"); EXPECT_EQ(solve(Expression("x^2 = 1")).toString(), "x = -1 | x = 1"); - EXPECT_EQ(solve(Expression("x^2 = -1")).toString(), "x = -sqrt(-4)/2 | x = sqrt(-4)/2"); EXPECT_EQ(solve(Expression("x^2 - 2x - 3 = 0")).toString(), "x = -1 | x = 3"); EXPECT_EQ(solve(Expression("15 - 2x - x^2 = 0")).toString(), "x = -5 | x = 3"); EXPECT_EQ(solve(Expression("x^2 + 12x + 36 = 0")).toString(), "x = -6"); @@ -241,6 +242,11 @@ TEST(ExpressionFunctionsTests, solveTest) { EXPECT_EQ(solve(Expression("-33x^2 - x + 34 = 0")).toString(), "x = -34/33 | x = 1"); EXPECT_EQ(solve(Expression("2x^2 + 2sqrt(2)x + 1 = 0")).toString(), "x = -sqrt(2)/2"); + EXPECT_EQ(solve(Expression("x^2 = -1")).toString(), "x = -I | x = I"); + EXPECT_EQ(solve(Expression("x^2 + 4x + 5 = 0")).toString(), "x = -I - 2 | x = I - 2"); + EXPECT_EQ(solve(Expression("2x^2 + x + 1 = 0")).toString(), "x = -(I sqrt(7))/4 - 1/4 | x = (I sqrt(7))/4 - 1/4"); + EXPECT_EQ(solve(Expression("x^2 + 3x + 5 = 0")).toString(), "x = -(I sqrt(11))/2 - 3/2 | x = (I sqrt(11))/2 - 3/2"); + // TODO: implement cubic equations EXPECT_EQ(solve(Expression("x^3 - 3x^2 + 3x - 1 = 0")).toString(), "x^3 - 3 x^2 + 3 x - 1 = 0"); // TODO: x = 1 // EXPECT_EQ(solve(Expression("x^3 - 6x^2 + 11x - 6 = 0")).toString(), "x = 1 | x = 2 | x = 3"); @@ -272,6 +278,7 @@ TEST(ExpressionFunctionsTests, solveTest) { EXPECT_EQ(solve(Expression("x^b a = 0")).toString(), "a x^b = 0"); EXPECT_EQ(solve(Expression("x/y = 0")).toString(), "x = 0"); EXPECT_EQ(solve(Expression("x^2 - 2*sin(2) = 0")).toString(), "x = -sqrt(2) sqrt(sin(2)) | x = sqrt(2) sqrt(sin(2))"); + EXPECT_EQ(solve(Expression("x = x sqrt(x)")).toString(), "x^(3/2) - x = 0"); EXPECT_EQ(solve(Expression("E >= Ey")).toString(), "E y - E <= 0"); EXPECT_EQ(solve(Expression("x >= x sqrt(x)")).toString(), "x^(3/2) - x <= 0"); diff --git a/tests/src/expressions/ExpressionTests.cpp b/tests/src/expressions/ExpressionTests.cpp index a9754458e..1f80db01f 100644 --- a/tests/src/expressions/ExpressionTests.cpp +++ b/tests/src/expressions/ExpressionTests.cpp @@ -918,17 +918,94 @@ TEST(ExpressionTests, stringConstructorTest) { // EXPECT_EQ(Expression("tan(x)*cot(x)").toString(), "1"); // TODO: implement // EXPECT_EQ(Expression("tanh(x)*coth(x)").toString(), "1"); // TODO: implement - EXPECT_EQ(Expression("sqrt(-1)").toString(), "sqrt(-1)"); - EXPECT_EQ(Expression("sqrt(-1)").toString(), "sqrt(-1)"); + EXPECT_EQ(Expression("(1 + 2I) + (2 + 3I)").toString(), "3 + 5 I"); + EXPECT_EQ(Expression("(1 + 2I) - (2 + 3I)").toString(), "-1 - I"); + EXPECT_EQ(Expression("(1 + 2I) * (2 + 3I)").toString(), "-4 + 7 I"); + EXPECT_EQ(Expression("(1 + 2I) / (2 + 3I)").toString(), "8/13 + 1/13 I"); + EXPECT_EQ(Expression("-(2 + 3I)").toString(), "-2 - 3 I"); + EXPECT_EQ(Expression("+(2 + 3I)").toString(), "2 + 3 I"); + + EXPECT_EQ(Expression("(-5 + 2I)^0").toString(), "1"); + EXPECT_EQ(Expression("(-5 + 2I)^1").toString(), "-5 + 2 I"); + EXPECT_EQ(Expression("(-5 + 2I)^2").toString(), "21 - 20 I"); + EXPECT_EQ(Expression("(-5 + 2I)^3").toString(), "-65 + 142 I"); + EXPECT_EQ(Expression("(-5 + 2I)^4").toString(), "41 - 840 I"); + EXPECT_EQ(Expression("(-5 + 2I)^5").toString(), "1475 + 4282 I"); + EXPECT_EQ(Expression("(-5 + 2I)^6").toString(), "-15939 - 18460 I"); + EXPECT_EQ(Expression("(-5 + 2I)^7").toString(), "116615 + 60422 I"); + EXPECT_EQ(Expression("(-5 + 2I)^8").toString(), "-703919 - 68880 I"); + EXPECT_EQ(Expression("(-5 + 2I)^32").toString(), "231439382100320515840321 + 95179357018581597343680 I"); + EXPECT_EQ(Expression("(-5 + 2I)^-1").toString(), "-5/29 - 2/29 I"); + EXPECT_EQ(Expression("(-5 + 2I)^-5").toString(), "1475/20511149 - 4282/20511149 I"); + EXPECT_EQ(Expression("(-5 + 2I)^-6").toString(), "-15939/594823321 + 18460/594823321 I"); + EXPECT_EQ(Expression("(-5 + 2I)^-32").toString(), "231439382100320515840321/62623297589448778360828428329074752308805325441 - 95179357018581597343680/62623297589448778360828428329074752308805325441 I"); + + EXPECT_EQ(Expression("sqrt(-1)").toString(), "I"); EXPECT_EQ(Expression("(-1)^(2/3)").toString(), "(-1)^(2/3)"); + // TODO: solve this EXPECT_EQ(Expression("ln(-1)").toString(), "ln(-1)"); EXPECT_EQ(Expression("lb(-1)").toString(), "log(2, -1)"); EXPECT_EQ(Expression("lg(-1)").toString(), "log(10, -1)"); + // TODO: solve this EXPECT_EQ(Expression("asin(2)").toString(), "asin(2)"); EXPECT_EQ(Expression("acos(2)").toString(), "acos(2)"); + // TODO! implement abs + EXPECT_EQ(Expression("abs(I)").toString(), "abs(I)"); + EXPECT_EQ(Expression("abs(I + 1)").toString(), "abs(1 + I)"); + EXPECT_EQ(Expression("abs(3I + 2)").toString(), "abs(2 + 3 I)"); + + // TODO: implement + EXPECT_EQ(Expression("sin(I + 1)").toString(), "sin(1 + I)"); + EXPECT_EQ(Expression("cos(I + 1)").toString(), "cos(1 + I)"); + EXPECT_EQ(Expression("tan(I + 1)").toString(), "tan(1 + I)"); + EXPECT_EQ(Expression("cot(I + 1)").toString(), "cot(1 + I)"); + EXPECT_EQ(Expression("asin(I + 1)").toString(), "asin(1 + I)"); + EXPECT_EQ(Expression("acos(I + 1)").toString(), "acos(1 + I)"); + EXPECT_EQ(Expression("atan(I + 1)").toString(), "atan(1 + I)"); + EXPECT_EQ(Expression("acot(I + 1)").toString(), "acot(1 + I)"); + EXPECT_EQ(Expression("sinh(I + 1)").toString(), "sinh(1 + I)"); + EXPECT_EQ(Expression("cosh(I + 1)").toString(), "cosh(1 + I)"); + EXPECT_EQ(Expression("tanh(I + 1)").toString(), "tanh(1 + I)"); + EXPECT_EQ(Expression("coth(I + 1)").toString(), "coth(1 + I)"); + EXPECT_EQ(Expression("asinh(I + 1)").toString(), "asinh(1 + I)"); + EXPECT_EQ(Expression("acosh(I + 1)").toString(), "acosh(1 + I)"); + EXPECT_EQ(Expression("atanh(I + 1)").toString(), "atanh(1 + I)"); + EXPECT_EQ(Expression("acoth(I + 1)").toString(), "acoth(1 + I)"); + + EXPECT_EQ(Expression("I = I").toString(), "True"); + EXPECT_EQ(Expression("I = 2 I").toString(), "False"); + EXPECT_EQ(Expression("I = I x").toString(), "x - 1 = 0"); + + EXPECT_EQ(Expression("I != I").toString(), "False"); + EXPECT_EQ(Expression("I != 2 I").toString(), "True"); + EXPECT_EQ(Expression("I != I x").toString(), "x - 1 != 0"); + + EXPECT_EQ(Expression("I < I").toString(), "I < I"); + EXPECT_EQ(Expression("I < 2 I").toString(), "I < 2 I"); + EXPECT_EQ(Expression("I < I x").toString(), "I < I x"); + + EXPECT_EQ(Expression("I > I").toString(), "I > I"); + EXPECT_EQ(Expression("I > 2 I").toString(), "I > 2 I"); + EXPECT_EQ(Expression("I > I x").toString(), "I > I x"); + + EXPECT_EQ(Expression("I <= I").toString(), "I <= I"); + EXPECT_EQ(Expression("I <= 2 I").toString(), "I <= 2 I"); + EXPECT_EQ(Expression("I <= I x").toString(), "I <= I x"); + + EXPECT_EQ(Expression("I >= I").toString(), "I >= I"); + EXPECT_EQ(Expression("I >= 2 I").toString(), "I >= 2 I"); + EXPECT_EQ(Expression("I >= I x").toString(), "I >= I x"); + + EXPECT_EQ(Expression("x (2 + I)").toString(), "(2 + I) x"); // TODO! simplify + EXPECT_EQ(Expression("sqrt(3) (2/3 + 1/2 I)").toString(), "(2/3 + 1/2 I) sqrt(3)"); // TODO! simplify + EXPECT_EQ(Expression("I / x").toString(), "I/x"); + EXPECT_EQ(Expression("-I / x").toString(), "-I/x"); + EXPECT_EQ(Expression("2I / x").toString(), "(2 I)/x"); + EXPECT_EQ(Expression("-2I / x").toString(), "(-2 I)/x"); // TODO! -(2 I)/x + EXPECT_EQ(Expression("Inf").toString(), "Inf"); EXPECT_EQ(Expression("-Inf").toString(), "-Inf"); EXPECT_EQ(Expression("ComplexInf").toString(), "ComplexInf"); @@ -1385,7 +1462,7 @@ TEST(ExpressionTests, stringConstructorNegativeTest) { EXPECT_THROW(Expression("Inf - Inf = 0"), InvalidInputException); EXPECT_THROW(Expression("Inf - Inf = 0 | a"), InvalidInputException); EXPECT_THROW(Expression("0/0 = 0/0"), InvalidInputException); - EXPECT_THROW(Expression("Undefined = Undefined"),InvalidInputException); + EXPECT_THROW(Expression("Undefined = Undefined"), InvalidInputException); EXPECT_THROW(Expression("min()"), InvalidInputException); EXPECT_THROW(Expression("min(True, False)"), InvalidInputException); @@ -1513,7 +1590,6 @@ TEST(ExpressionTests, preciseTest) { EXPECT_EQ(Expression("root(x, 33)").precise().toString(), "x^0.03030303030303030303030303030303030303030303030303030303030303030303030303030303"); - // TODO: move to str constructor tests EXPECT_EQ(Expression("derivative(sqrt((1-cos(2*(Pi/3)))/2), x)").precise().toString(), "0"); } diff --git a/tests/src/expressions/ExpressionUtilsTests.cpp b/tests/src/expressions/ExpressionUtilsTests.cpp index 177ff552c..5a333a24a 100644 --- a/tests/src/expressions/ExpressionUtilsTests.cpp +++ b/tests/src/expressions/ExpressionUtilsTests.cpp @@ -101,6 +101,10 @@ TEST(ExpressionUtilsTests, hasInfinityTest) { // TODO: implement } +TEST(ExpressionUtilsTests, hasComplexTest) { + // TODO: implement +} + TEST(ExpressionUtilsTests, isInfinityTest) { // TODO: implement } diff --git a/tests/src/expressions/IExpressionTests.cpp b/tests/src/expressions/IExpressionTests.cpp index c701a777a..c98ac181f 100644 --- a/tests/src/expressions/IExpressionTests.cpp +++ b/tests/src/expressions/IExpressionTests.cpp @@ -85,6 +85,7 @@ TEST(IExpressionTests, setVariablesTest) { TEST(IExpressionTests, toMinimalObjectTest) { TestIExpression a; EXPECT_EQ(*a.toMinimalObject(), a); + // TODO: implement more tests } diff --git a/tests/src/functions/arithmetic/AbsTests.cpp b/tests/src/functions/arithmetic/AbsTests.cpp index f4427df8a..4da89b0fd 100644 --- a/tests/src/functions/arithmetic/AbsTests.cpp +++ b/tests/src/functions/arithmetic/AbsTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/trigonometry/Sin.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -34,6 +35,19 @@ TEST(AbsTests, callTest) { EXPECT_EQ(f(Real("8465132.321651651"))->toString(), "8465132.321651651"); EXPECT_EQ(f(Real("-98465136846516354684651.351"))->toString(), "98465136846516354684651.351"); + // TODO! implement + EXPECT_EQ(f(Complex(2, 0))->toString(), "abs(2)"); + EXPECT_EQ(f(Complex(0, 2))->toString(), "abs(2 I)"); + EXPECT_EQ(f(Complex(2, 2))->toString(), "abs(2 + 2 I)"); + EXPECT_EQ(f(Complex(3, 2))->toString(), "abs(3 + 2 I)"); + EXPECT_EQ(f(Complex(2, 3))->toString(), "abs(2 + 3 I)"); + EXPECT_EQ(f(Complex(-2, 0))->toString(), "abs(-2)"); + EXPECT_EQ(f(Complex(0, -2))->toString(), "abs(-2 I)"); + EXPECT_EQ(f(Complex(2, -2))->toString(), "abs(2 - 2 I)"); + EXPECT_EQ(f(Complex(-3, 2))->toString(), "abs(-3 + 2 I)"); + EXPECT_EQ(f(Complex(2, -3))->toString(), "abs(2 - 3 I)"); + EXPECT_EQ(f(Complex(-2, -3))->toString(), "abs(-2 - 3 I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "abs(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/arithmetic/SignTests.cpp b/tests/src/functions/arithmetic/SignTests.cpp index 1e5f48b2b..d9fd60ad9 100644 --- a/tests/src/functions/arithmetic/SignTests.cpp +++ b/tests/src/functions/arithmetic/SignTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -24,6 +25,7 @@ TEST(SignTests, callTest) { EXPECT_EQ(f(Integer(10))->toString(), "1"); EXPECT_EQ(f(Rational(-10))->toString(), "-1"); EXPECT_EQ(f(Real(0))->toString(), "0"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "sign(1 + I)"); EXPECT_EQ(f(Variable("a"))->toString(), "sign(a)"); diff --git a/tests/src/functions/calculus/MaxTests.cpp b/tests/src/functions/calculus/MaxTests.cpp index dd22f1cc5..5baf64960 100644 --- a/tests/src/functions/calculus/MaxTests.cpp +++ b/tests/src/functions/calculus/MaxTests.cpp @@ -8,6 +8,7 @@ #include "fintamath/functions/calculus/Min.hpp" #include "fintamath/literals/Boolean.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -28,6 +29,9 @@ TEST(MaxTests, callTest) { EXPECT_EQ(f(Integer(1), Integer(-1), Rational(-5, 2))->toString(), "1"); EXPECT_EQ(f(Integer(1), Rational(5, 2), Rational(-5, 2), Integer(-1))->toString(), "5/2"); + EXPECT_EQ(f(Integer(1), Rational(5, 2), Complex(1, 1))->toString(), "max(1, 5/2, 1 + I)"); + EXPECT_EQ(f(Integer(1), Complex(1, 1), Rational(5, 2))->toString(), "max(1, 1 + I, 5/2)"); + EXPECT_EQ(f(Rational(-1), Variable("x"), Variable("y"), Integer(1))->toString(), "max(x, y, 1)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/calculus/MinTests.cpp b/tests/src/functions/calculus/MinTests.cpp index 9a0c3213c..e9adc900f 100644 --- a/tests/src/functions/calculus/MinTests.cpp +++ b/tests/src/functions/calculus/MinTests.cpp @@ -2,12 +2,13 @@ #include "fintamath/functions/calculus/Min.hpp" +#include "fintamath/expressions/Expression.hpp" #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/functions/calculus/Max.hpp" -#include "fintamath/expressions/Expression.hpp" #include "fintamath/literals/Boolean.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -28,6 +29,9 @@ TEST(MinTests, callTest) { EXPECT_EQ(f(Integer(1), Integer(-1), Rational(-5, 2))->toString(), "-5/2"); EXPECT_EQ(f(Integer(1), Rational(5, 2), Rational(-5, 2), Integer(-1))->toString(), "-5/2"); + EXPECT_EQ(f(Integer(1), Rational(5, 2), Complex(1, 1))->toString(), "min(1, 5/2, 1 + I)"); + EXPECT_EQ(f(Integer(1), Complex(1, 1), Rational(5, 2))->toString(), "min(1, 1 + I, 5/2)"); + EXPECT_EQ(f(Rational(-1), Variable("x"), Variable("y"), Integer(1))->toString(), "min(x, y, -1)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/comparison/EqvTests.cpp b/tests/src/functions/comparison/EqvTests.cpp index 9987c1e8d..9072499b3 100644 --- a/tests/src/functions/comparison/EqvTests.cpp +++ b/tests/src/functions/comparison/EqvTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -30,6 +31,11 @@ TEST(EqvTests, callTest) { EXPECT_EQ(f(Integer(3), Rational(3, 1))->toString(), "True"); EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "False"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "True"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "False"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 1))->toString(), "False"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 2))->toString(), "False"); + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a - 3 = 0"); EXPECT_EQ(f(Variable("a"), Variable("a"))->toString(), "True"); diff --git a/tests/src/functions/comparison/LessEqvTests.cpp b/tests/src/functions/comparison/LessEqvTests.cpp index 25d546a60..c24981d5c 100644 --- a/tests/src/functions/comparison/LessEqvTests.cpp +++ b/tests/src/functions/comparison/LessEqvTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -30,6 +31,11 @@ TEST(LessEqvTests, callTest) { EXPECT_EQ(f(Integer(3), Rational(3, 1))->toString(), "True"); EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "False"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "1 + I <= 1 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "1 + I <= 1 + 2 I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 1))->toString(), "1 + I <= 2 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 2))->toString(), "1 + I <= 2 + 2 I"); + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a - 3 >= 0"); EXPECT_EQ(f(Variable("a"), Variable("a"))->toString(), "True"); diff --git a/tests/src/functions/comparison/LessTests.cpp b/tests/src/functions/comparison/LessTests.cpp index 418cf4931..e15b6a09f 100644 --- a/tests/src/functions/comparison/LessTests.cpp +++ b/tests/src/functions/comparison/LessTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -30,6 +31,11 @@ TEST(LessTests, callTest) { EXPECT_EQ(f(Integer(3), Rational(3, 1))->toString(), "False"); EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "False"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "1 + I < 1 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "1 + I < 1 + 2 I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 1))->toString(), "1 + I < 2 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 2))->toString(), "1 + I < 2 + 2 I"); + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a - 3 > 0"); EXPECT_EQ(f(Variable("a"), Variable("a"))->toString(), "False"); diff --git a/tests/src/functions/comparison/MoreEqvTests.cpp b/tests/src/functions/comparison/MoreEqvTests.cpp index 7f864695d..68b96f439 100644 --- a/tests/src/functions/comparison/MoreEqvTests.cpp +++ b/tests/src/functions/comparison/MoreEqvTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -30,6 +31,11 @@ TEST(MoreEqvTests, callTest) { EXPECT_EQ(f(Integer(3), Rational(3, 1))->toString(), "True"); EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "True"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "1 + I >= 1 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "1 + I >= 1 + 2 I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 1))->toString(), "1 + I >= 2 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 2))->toString(), "1 + I >= 2 + 2 I"); + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a - 3 <= 0"); EXPECT_EQ(f(Variable("a"), Variable("a"))->toString(), "True"); diff --git a/tests/src/functions/comparison/MoreTests.cpp b/tests/src/functions/comparison/MoreTests.cpp index 9b1fb7499..4e0d8cdff 100644 --- a/tests/src/functions/comparison/MoreTests.cpp +++ b/tests/src/functions/comparison/MoreTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -30,6 +31,11 @@ TEST(MoreTests, callTest) { EXPECT_EQ(f(Integer(3), Rational(3, 1))->toString(), "False"); EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "True"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "1 + I > 1 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "1 + I > 1 + 2 I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 1))->toString(), "1 + I > 2 + I"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 2))->toString(), "1 + I > 2 + 2 I"); + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a - 3 < 0"); EXPECT_EQ(f(Variable("a"), Variable("a"))->toString(), "False"); diff --git a/tests/src/functions/comparison/NeqvTests.cpp b/tests/src/functions/comparison/NeqvTests.cpp index 6cc021af6..284ef11e7 100644 --- a/tests/src/functions/comparison/NeqvTests.cpp +++ b/tests/src/functions/comparison/NeqvTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -30,6 +31,11 @@ TEST(NeqvTests, callTest) { EXPECT_EQ(f(Integer(3), Rational(3, 1))->toString(), "False"); EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "True"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "False"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "True"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 1))->toString(), "True"); + EXPECT_EQ(f(Complex(1, 1), Complex(2, 2))->toString(), "True"); + EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "a - 3 != 0"); EXPECT_EQ(f(Variable("a"), Variable("a"))->toString(), "False"); diff --git a/tests/src/functions/hyperbolic/AcoshTests.cpp b/tests/src/functions/hyperbolic/AcoshTests.cpp index e4014ab36..ff6fc7419 100644 --- a/tests/src/functions/hyperbolic/AcoshTests.cpp +++ b/tests/src/functions/hyperbolic/AcoshTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -22,8 +23,8 @@ TEST(AcoshTests, getFunctionTypeTest) { } TEST(AcoshTests, callTest) { - EXPECT_EQ(f(Integer(-1))->toString(), "acosh(-1)"); - EXPECT_EQ(f(Integer(0))->toString(), "acosh(0)"); + EXPECT_EQ(f(Integer(-1))->toString(), "I Pi"); + EXPECT_EQ(f(Integer(0))->toString(), "(I Pi)/2"); EXPECT_EQ(f(Integer(1))->toString(), "0"); EXPECT_EQ(f(Integer(2))->toString(), "1.316957896924816708625046347307968444026981971467516479768472256920460185416444"); @@ -36,6 +37,8 @@ TEST(AcoshTests, callTest) { EXPECT_EQ(f(Real("1.5"))->toString(), "0.96242365011920689499551782684873684627036866877132103932203633768032773521644355"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "acosh(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "acosh(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/hyperbolic/AcothTests.cpp b/tests/src/functions/hyperbolic/AcothTests.cpp index 1c4883c41..5ab553e36 100644 --- a/tests/src/functions/hyperbolic/AcothTests.cpp +++ b/tests/src/functions/hyperbolic/AcothTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -23,7 +24,7 @@ TEST(AcothTests, getFunctionTypeTest) { TEST(AcothTests, callTest) { EXPECT_EQ(f(Integer(-1))->toString(), "-Inf"); - EXPECT_EQ(f(Integer(0))->toString(), "acoth(0)"); + EXPECT_EQ(f(Integer(0))->toString(), "(I Pi)/2"); EXPECT_EQ(f(Integer(1))->toString(), "Inf"); EXPECT_EQ(f(Integer(2))->toString(), "0.54930614433405484569762261846126285232374527891137472586734716681874714660930448"); @@ -36,6 +37,8 @@ TEST(AcothTests, callTest) { EXPECT_EQ(f(Real("1.5"))->toString(), "0.80471895621705018730037966661309381976280067713425886095632394573708949385382888"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "acoth(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "acoth(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/hyperbolic/AsinhTests.cpp b/tests/src/functions/hyperbolic/AsinhTests.cpp index 44341c098..cc1121758 100644 --- a/tests/src/functions/hyperbolic/AsinhTests.cpp +++ b/tests/src/functions/hyperbolic/AsinhTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -31,6 +32,8 @@ TEST(AsinhTests, callTest) { EXPECT_EQ(f(Rational(-1, 5))->toString(), "-0.19869011034924140647463691595020696822130879422445377302126322228548564789597237"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "asinh(1 + I)"); + EXPECT_EQ(f(Real("0.5"))->toString(), "0.48121182505960344749775891342436842313518433438566051966101816884016386760822177"); diff --git a/tests/src/functions/hyperbolic/AtanhTests.cpp b/tests/src/functions/hyperbolic/AtanhTests.cpp index c96a7f8e3..12fd1d6d2 100644 --- a/tests/src/functions/hyperbolic/AtanhTests.cpp +++ b/tests/src/functions/hyperbolic/AtanhTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -27,6 +28,8 @@ TEST(AtanhTests, callTest) { EXPECT_EQ(f(Integer(1))->toString(), "Inf"); EXPECT_EQ(f(Integer(2))->toString(), "atanh(2)"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "atanh(1 + I)"); + EXPECT_EQ(f(Rational(10, 11))->toString(), "1.5222612188617114982502989901828527171422876437023053200970422417875370779853391"); EXPECT_EQ(f(Rational(-10, 11))->toString(), diff --git a/tests/src/functions/hyperbolic/CoshTests.cpp b/tests/src/functions/hyperbolic/CoshTests.cpp index fa2ebb832..7bf63e68b 100644 --- a/tests/src/functions/hyperbolic/CoshTests.cpp +++ b/tests/src/functions/hyperbolic/CoshTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -34,6 +35,8 @@ TEST(CoshTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "1.127625965206380785226225161402672012547847118098667483628985735187858770303982"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "cosh(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "cosh(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/hyperbolic/CothTests.cpp b/tests/src/functions/hyperbolic/CothTests.cpp index 27295ba7e..252022ef9 100644 --- a/tests/src/functions/hyperbolic/CothTests.cpp +++ b/tests/src/functions/hyperbolic/CothTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -37,6 +38,8 @@ TEST(CothTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "2.1639534137386528487700040102180231170937386021507922725335741192960876347833395"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "coth(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "coth(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/hyperbolic/SinhTests.cpp b/tests/src/functions/hyperbolic/SinhTests.cpp index 30591dfa4..adb7c4e72 100644 --- a/tests/src/functions/hyperbolic/SinhTests.cpp +++ b/tests/src/functions/hyperbolic/SinhTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -34,6 +35,8 @@ TEST(SinhTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "0.52109530549374736162242562641149155910592898261148052794609357645280225089023359"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "sinh(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "sinh(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/hyperbolic/TanhTests.cpp b/tests/src/functions/hyperbolic/TanhTests.cpp index 43cdf266b..fe658b45d 100644 --- a/tests/src/functions/hyperbolic/TanhTests.cpp +++ b/tests/src/functions/hyperbolic/TanhTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -35,6 +36,8 @@ TEST(TanhTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "0.46211715726000975850231848364367254873028928033011303855273181583808090614040928"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "tanh(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "tanh(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/logarithms/LbTests.cpp b/tests/src/functions/logarithms/LbTests.cpp index e624eedb1..9bb84fb0c 100644 --- a/tests/src/functions/logarithms/LbTests.cpp +++ b/tests/src/functions/logarithms/LbTests.cpp @@ -29,9 +29,9 @@ TEST(LbTests, callTest) { EXPECT_EQ(f(Rational(1, 16))->toString(), "-4"); - EXPECT_EQ(f(Variable("a"))->toString(), "log(2, a)"); + EXPECT_EQ(f(Integer(-10))->toString(), "log(2, -10)"); - EXPECT_THROW(f(Integer(-10)), UndefinedFunctionException); + EXPECT_EQ(f(Variable("a"))->toString(), "log(2, a)"); EXPECT_THROW(f(), InvalidInputFunctionException); EXPECT_THROW(f(Integer(10), Integer(10), Integer(10)), InvalidInputFunctionException); diff --git a/tests/src/functions/logarithms/LgTests.cpp b/tests/src/functions/logarithms/LgTests.cpp index 31c8528fa..7ff2d9bb6 100644 --- a/tests/src/functions/logarithms/LgTests.cpp +++ b/tests/src/functions/logarithms/LgTests.cpp @@ -29,9 +29,9 @@ TEST(LgTests, callTest) { EXPECT_EQ(f(Rational(1, 10))->toString(), "-1"); - EXPECT_EQ(f(Variable("a"))->toString(), "log(10, a)"); + EXPECT_EQ(f(Integer(-10))->toString(), "log(10, -10)"); - EXPECT_THROW(f(Integer(-10)), UndefinedFunctionException); + EXPECT_EQ(f(Variable("a"))->toString(), "log(10, a)"); EXPECT_THROW(f(), InvalidInputFunctionException); EXPECT_THROW(f(Integer(10), Integer(10), Integer(10)), InvalidInputFunctionException); diff --git a/tests/src/functions/logarithms/LnTests.cpp b/tests/src/functions/logarithms/LnTests.cpp index 9b4e5564a..5719fd30f 100644 --- a/tests/src/functions/logarithms/LnTests.cpp +++ b/tests/src/functions/logarithms/LnTests.cpp @@ -33,9 +33,9 @@ TEST(LnTests, callTest) { "-2.3025850929940456840179914546843642076011014886287729760333279009675726096773525"); EXPECT_EQ(f(getE())->toString(), "1.0"); - EXPECT_EQ(f(Variable("a"))->toString(), "ln(a)"); + EXPECT_EQ(f(Integer(-10))->toString(), "ln(-10)"); - EXPECT_THROW(f(Integer(-10)), UndefinedFunctionException); + EXPECT_EQ(f(Variable("a"))->toString(), "ln(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException); diff --git a/tests/src/functions/logarithms/LogTests.cpp b/tests/src/functions/logarithms/LogTests.cpp index eb33133d5..7c07dc50e 100644 --- a/tests/src/functions/logarithms/LogTests.cpp +++ b/tests/src/functions/logarithms/LogTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" using namespace fintamath; @@ -60,16 +61,21 @@ TEST(LogTests, callTest) { EXPECT_EQ(f(Integer(10), 1 / Real(121))->toString(), "-2.0827853703164500815003999424860484834134043809329061891930780373595060644664987"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "1"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 2))->toString(), "log(1 + I, 1 + 2 I)"); + EXPECT_EQ(f(Complex(1, 1), Integer(1))->toString(), "0"); + EXPECT_EQ(f(Integer(10), Integer(0))->toString(), "-Inf"); EXPECT_EQ(f(Rational(1, 10), Integer(0))->toString(), "Inf"); EXPECT_EQ(f(Integer(1), Integer(10))->toString(), "ComplexInf"); + EXPECT_EQ(f(Integer(1), Complex(1, 1))->toString(), "ComplexInf"); EXPECT_EQ(f(Integer(1), Integer(1))->toString(), "Undefined"); EXPECT_EQ(f(Integer(0), Integer(0))->toString(), "Undefined"); - EXPECT_EQ(f(Variable("a"), Variable("b"))->toString(), "log(a, b)"); + EXPECT_EQ(f(Integer(-10), Integer(10))->toString(), "log(-10, 10)"); + EXPECT_EQ(f(Integer(10), Integer(-10))->toString(), "log(10, -10)"); - EXPECT_THROW(f(Integer(-10), Integer(10)), UndefinedFunctionException); - EXPECT_THROW(f(Integer(10), Integer(-10)), UndefinedFunctionException); + EXPECT_EQ(f(Variable("a"), Variable("b"))->toString(), "log(a, b)"); EXPECT_THROW(f(), InvalidInputFunctionException); EXPECT_THROW(f(Integer(10)), InvalidInputFunctionException); diff --git a/tests/src/functions/other/FactorialTests.cpp b/tests/src/functions/other/FactorialTests.cpp index 343a817d6..76cd3b576 100644 --- a/tests/src/functions/other/FactorialTests.cpp +++ b/tests/src/functions/other/FactorialTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -59,6 +60,8 @@ TEST(FactorialTests, callTest) { EXPECT_EQ(f(Real("10"))->toString(), "3628800.0"); EXPECT_EQ(f(Real(-10))->toString(), "(-10.0)!"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "(1 + I)!"); + EXPECT_EQ(f(Integer(-10))->toString(), "ComplexInf"); EXPECT_EQ(f(Rational(-10))->toString(), "ComplexInf"); diff --git a/tests/src/functions/powers/PowTests.cpp b/tests/src/functions/powers/PowTests.cpp index 581360845..21ce477b6 100644 --- a/tests/src/functions/powers/PowTests.cpp +++ b/tests/src/functions/powers/PowTests.cpp @@ -7,6 +7,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -75,7 +76,13 @@ TEST(PowTests, callTest) { EXPECT_EQ(f(Real("2.2"), Real("0.5"))->toString(), "1.48323969741913258974227948816014261219598086381950031974652465286876603686277"); - EXPECT_EQ(f(Rational(-10), Rational("-1.5"))->toString(), "(-10)^(-3/2)"); + EXPECT_EQ(f(Integer(-10), Rational(1, 2))->toString(), "I sqrt(10)"); + EXPECT_EQ(f(Rational(-10), Real("-1.5"))->toString(), "(-10)^(-1.5)"); // TODO: solve this + + EXPECT_EQ(f(Complex(1, 1), Integer(1))->toString(), "1 + I"); + EXPECT_EQ(f(Complex(1, 1), Rational(1, 2))->toString(), "sqrt(1 + I)"); + EXPECT_EQ(f(Complex(1, 1), Real("1.2"))->toString(), "(1 + I)^1.2"); + EXPECT_EQ(f(Complex(1, 1), Complex(1, 1))->toString(), "(1 + I)^(1 + I)"); EXPECT_EQ(f(Integer(0), Integer(-1))->toString(), "ComplexInf"); EXPECT_EQ(f(Integer(0), Integer(-10))->toString(), "ComplexInf"); diff --git a/tests/src/functions/powers/RootTests.cpp b/tests/src/functions/powers/RootTests.cpp index ba4e8eea7..e4ea89d95 100644 --- a/tests/src/functions/powers/RootTests.cpp +++ b/tests/src/functions/powers/RootTests.cpp @@ -47,6 +47,10 @@ TEST(RootTests, callTest) { EXPECT_EQ(f(Integer(1024), Integer(3))->toString(), "8 root(2, 3)"); EXPECT_EQ(f(Integer(1024), Integer(5))->toString(), "4"); EXPECT_EQ(f(Integer(1024), Integer(10))->toString(), "2"); + EXPECT_EQ(f(Integer(-1000), Integer(3))->toString(), "-10"); + EXPECT_EQ(f(Integer(-10), Integer(3))->toString(), "-root(10, 3)"); + EXPECT_EQ(f(Integer(-100000), Integer(5))->toString(), "-10"); + EXPECT_EQ(f(Integer(-10), Integer(5))->toString(), "-root(10, 5)"); EXPECT_EQ(f(Rational(25), Integer(4))->toString(), "sqrt(5)"); EXPECT_EQ(f(Rational(25, 169), Integer(4))->toString(), "sqrt(65)/13"); @@ -87,15 +91,17 @@ TEST(RootTests, callTest) { EXPECT_EQ(f(Real(2), Real("2.33"))->toString(), "1.3464722988167144947473840795888543539968696938592078715906325948094320119117764"); + EXPECT_EQ(f(Integer(-10), Integer(2))->toString(), "I sqrt(10)"); + EXPECT_EQ(f(Integer(-10), Integer(4))->toString(), "root(-10, 4)"); + EXPECT_EQ(f(Integer(-10), Integer(6))->toString(), "root(-10, 6)"); + EXPECT_EQ(f(Rational(-9289, 10), Rational(2, 3))->toString(), "(9289 I sqrt(92890))/100"); + EXPECT_EQ(f(Real(-9289), Rational(2, 3))->toString(), "(-9289.0)^(3/2)"); // TODO: solve this + 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(), "root(2, a)"); - EXPECT_EQ(f(Integer(-10), Integer(2))->toString(), "sqrt(-10)"); - EXPECT_EQ(f(Rational(-9289, 10), Rational(2, 3))->toString(), "(-9289/10)^(3/2)"); - EXPECT_EQ(f(Real(-9289), Rational(2, 3))->toString(), "(-9289.0)^(3/2)"); - EXPECT_THROW(f(), InvalidInputFunctionException); EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException); } diff --git a/tests/src/functions/powers/SqrtTests.cpp b/tests/src/functions/powers/SqrtTests.cpp index 4a5a73c23..581dfb76e 100644 --- a/tests/src/functions/powers/SqrtTests.cpp +++ b/tests/src/functions/powers/SqrtTests.cpp @@ -48,9 +48,9 @@ TEST(SqrtTests, callTest) { EXPECT_EQ(f(Real(144))->toString(), "12.0"); EXPECT_EQ(f(Real(2))->toString(), "1.414213562373095048801688724209698078569671875376948073176679737990732478462107"); - EXPECT_EQ(f(Integer(-10))->toString(), "sqrt(-10)"); - EXPECT_EQ(f(Rational(-9289, 10))->toString(), "sqrt(-9289/10)"); - EXPECT_EQ(f(Real(-9289))->toString(), "sqrt(-9289.0)"); + EXPECT_EQ(f(Integer(-10))->toString(), "I sqrt(10)"); + EXPECT_EQ(f(Rational(-9289, 10))->toString(), "(I sqrt(92890))/10"); + EXPECT_EQ(f(Real(-9289))->toString(), "96.379458392335863966326568498632217265291077134379132716928952438952915972901934 I"); EXPECT_EQ(f(Variable("a"))->toString(), "sqrt(a)"); diff --git a/tests/src/functions/trigonometry/AcosTests.cpp b/tests/src/functions/trigonometry/AcosTests.cpp index bc022badf..b69a3f7d1 100644 --- a/tests/src/functions/trigonometry/AcosTests.cpp +++ b/tests/src/functions/trigonometry/AcosTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -36,6 +37,8 @@ TEST(AcosTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "1.0471975511965977461542144610931676280657231331250352736583148641026054687620697"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "acos(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "acos(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/AcotTests.cpp b/tests/src/functions/trigonometry/AcotTests.cpp index d26906e77..b1590465f 100644 --- a/tests/src/functions/trigonometry/AcotTests.cpp +++ b/tests/src/functions/trigonometry/AcotTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -38,6 +39,8 @@ TEST(AcotTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "1.1071487177940905030170654601785370400700476454014326466765392074337103389773628"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "acot(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "acot(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/AsinTests.cpp b/tests/src/functions/trigonometry/AsinTests.cpp index 8904d2a0a..c18b40a2b 100644 --- a/tests/src/functions/trigonometry/AsinTests.cpp +++ b/tests/src/functions/trigonometry/AsinTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -36,6 +37,8 @@ TEST(AsinTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "0.52359877559829887307710723054658381403286156656251763682915743205130273438103483"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "asin(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "asin(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/AtanTests.cpp b/tests/src/functions/trigonometry/AtanTests.cpp index 84be797f3..2234bd324 100644 --- a/tests/src/functions/trigonometry/AtanTests.cpp +++ b/tests/src/functions/trigonometry/AtanTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" @@ -37,6 +38,8 @@ TEST(AtanTests, callTest) { EXPECT_EQ(f(Real("0.5"))->toString(), "0.46364760900080611621425623146121440202853705428612026381093308872019786416574171"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "atan(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "atan(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/CosTests.cpp b/tests/src/functions/trigonometry/CosTests.cpp index 21cce6537..cc7f41c85 100644 --- a/tests/src/functions/trigonometry/CosTests.cpp +++ b/tests/src/functions/trigonometry/CosTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -37,6 +38,8 @@ TEST(CosTests, callTest) { "5.4692230477529111586267970406424055872514205135096926055277982231147447746519098*10^-121"); EXPECT_EQ(f(getPi())->toString(), "-1.0"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "cos(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "cos(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/CotTests.cpp b/tests/src/functions/trigonometry/CotTests.cpp index a16269f14..2e590a245 100644 --- a/tests/src/functions/trigonometry/CotTests.cpp +++ b/tests/src/functions/trigonometry/CotTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -40,6 +41,8 @@ TEST(CotTests, callTest) { "5.4692230477529111586267970406424055872514205135096926055277982231147447746519098*10^-121"); EXPECT_EQ(f(getPi() / 4)->toString(), "1.0"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "cot(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "cot(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/SinTests.cpp b/tests/src/functions/trigonometry/SinTests.cpp index 0fd29917a..f7ab5e188 100644 --- a/tests/src/functions/trigonometry/SinTests.cpp +++ b/tests/src/functions/trigonometry/SinTests.cpp @@ -5,6 +5,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -37,6 +38,8 @@ TEST(SinTests, callTest) { EXPECT_EQ(f(getPi())->toString(), "9.3844609550582231725359408128481117450284102701938521105559644622948954930381964*10^-122"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "sin(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "sin(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/functions/trigonometry/TanTests.cpp b/tests/src/functions/trigonometry/TanTests.cpp index 53b08f37a..b6a56f97f 100644 --- a/tests/src/functions/trigonometry/TanTests.cpp +++ b/tests/src/functions/trigonometry/TanTests.cpp @@ -6,6 +6,7 @@ #include "fintamath/functions/arithmetic/Sub.hpp" #include "fintamath/functions/arithmetic/UnaryPlus.hpp" #include "fintamath/literals/Variable.hpp" +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/Rational.hpp" #include "fintamath/numbers/Real.hpp" #include "fintamath/numbers/RealFunctions.hpp" @@ -40,6 +41,8 @@ TEST(TanTests, callTest) { EXPECT_EQ(f(getPi() / 2)->toString(), "1.8284132705300082902317661058105479684239284072480833124982117000101510968883506*10^120"); + EXPECT_EQ(f(Complex(1, 1))->toString(), "tan(1 + I)"); + EXPECT_EQ(f(Variable("a"))->toString(), "tan(a)"); EXPECT_THROW(f(), InvalidInputFunctionException); diff --git a/tests/src/numbers/IntegerFunctionsTests.cpp b/tests/src/numbers/IntegerFunctionsTests.cpp index 140c68105..80722535b 100644 --- a/tests/src/numbers/IntegerFunctionsTests.cpp +++ b/tests/src/numbers/IntegerFunctionsTests.cpp @@ -1,5 +1,6 @@ #include +#include "fintamath/numbers/Complex.hpp" #include "fintamath/numbers/IntegerFunctions.hpp" #include "fintamath/exceptions/UndefinedException.hpp" @@ -127,9 +128,19 @@ TEST(IntegerFunctionsTests, powTest) { EXPECT_EQ(pow(Real(6789), Integer(-4)).toString(), "4.7073529830645308411980456378106763573183149819028161454972767500068746591107477*10^-16"); + EXPECT_EQ(pow(Complex(5, 2), Integer(2)).toString(), "21 + 20 I"); + EXPECT_EQ(pow(Complex(Rational(1, 2), Rational(2, 3)), Integer(5)).toString(), "-79/2592 - 779/1944 I"); + EXPECT_EQ(pow(Complex(6789, 2345), Integer(4)).toString(), "633857838549916 + 2584899750306720 I"); + EXPECT_EQ(pow(Complex("135253468973498327423987498324729384.12987349823749832"), Integer(3)).toString(), + "4832537992678386348337867205980822373798257851094432575433371642956047093945525418683507600681355491343220" + "122262032882136893556623485326120689398001084489/1953125000000000000000000000000000000000000000000"); + EXPECT_EQ(pow(Complex(6789, 11), Integer(-4)).toString(), + "531075666086959/1128212841481282934557153710724 - 860496245400/282053210370320733639288427681 I"); + EXPECT_THROW(pow(Integer(0), Integer(0)), UndefinedBinaryOperatorException); EXPECT_THROW(pow(Rational(0), Integer(0)), UndefinedBinaryOperatorException); - EXPECT_THROW(pow(Rational(0), Integer(0)), UndefinedBinaryOperatorException); + EXPECT_THROW(pow(Real(0), Integer(0)), UndefinedBinaryOperatorException); + EXPECT_THROW(pow(Complex(0), Integer(0)), UndefinedBinaryOperatorException); } TEST(IntegerFunctionsTests, factorialTest) {