Skip to content

Commit

Permalink
Implement PowF function
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Jul 25, 2023
1 parent cedd342 commit ad5b889
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/fintamath/core/MathObjectTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum class MathObjectType : MathObjectTypeId {
Derivative,
Integral,
Frac,
PowF,

IOperator = 12000,

Expand Down
22 changes: 22 additions & 0 deletions include/fintamath/functions/powers/PowF.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include "fintamath/core/IArithmetic.hpp"
#include "fintamath/functions/IFunction.hpp"

namespace fintamath {

class PowF : public IFunctionCRTP<IArithmetic, PowF, IArithmetic, IArithmetic> {
public:
std::string toString() const override {
return "pow";
}

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

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

}
5 changes: 5 additions & 0 deletions src/fintamath/config/ExpressionConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include "fintamath/functions/other/Percent.hpp"
#include "fintamath/functions/powers/Exp.hpp"
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/functions/powers/PowF.hpp"
#include "fintamath/functions/powers/Root.hpp"
#include "fintamath/functions/powers/Sqrt.hpp"
#include "fintamath/functions/trigonometry/Acos.hpp"
Expand Down Expand Up @@ -168,6 +169,10 @@ struct ExpressionConfig {
return std::make_unique<PowExpression>(args.front(), args.back());
});

Expression::registerFunctionExpressionMaker<PowF>([](const ArgumentsPtrVector &args) {
return std::make_unique<PowExpression>(args.front(), args.back());
});

Expression::registerFunctionExpressionMaker<Eqv>([](const ArgumentsPtrVector &args) {
return std::make_unique<CompExpression>(Eqv(), args.front(), args.back());
});
Expand Down
2 changes: 2 additions & 0 deletions src/fintamath/config/ParserConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "fintamath/functions/other/Percent.hpp"
#include "fintamath/functions/powers/Exp.hpp"
#include "fintamath/functions/powers/Pow.hpp"
#include "fintamath/functions/powers/PowF.hpp"
#include "fintamath/functions/powers/Root.hpp"
#include "fintamath/functions/powers/Sqrt.hpp"
#include "fintamath/functions/trigonometry/Acos.hpp"
Expand Down Expand Up @@ -196,6 +197,7 @@ struct ParserConfig {
IFunction::registerType<Derivative>();
IFunction::registerType<Integral>();
IFunction::registerType<Frac>();
IFunction::registerType<PowF>();

IOperator::registerType<Add>();
IOperator::registerType<Sub>();
Expand Down
11 changes: 11 additions & 0 deletions src/fintamath/functions/powers/PowF.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "fintamath/functions/powers/PowF.hpp"

#include "fintamath/functions/powers/Pow.hpp"

namespace fintamath {

std::unique_ptr<IMathObject> PowF::call(const ArgumentsRefVector &argsVect) const {
return Pow()(argsVect);
}

}
2 changes: 2 additions & 0 deletions tests/src/expressions/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ TEST(ExpressionTests, stringConstructorTest) {
EXPECT_EQ(Expression("sign(-5)").toString(), "-1");
EXPECT_EQ(Expression("frac(2,4)").toString(), "1/2");
EXPECT_EQ(Expression("frac(x,y)").toString(), "x/y");
EXPECT_EQ(Expression("pow(2,4)").toString(), "16");
EXPECT_EQ(Expression("pow(x,y)").toString(), "x^y");

EXPECT_EQ(Expression("a*0").toString(), "0");
EXPECT_EQ(Expression("0*a").toString(), "0");
Expand Down
112 changes: 112 additions & 0 deletions tests/src/functions/powers/PowFTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include "gtest/gtest.h"

#include "fintamath/functions/powers/PowF.hpp"

#include "fintamath/core/IArithmetic.hpp"
#include "fintamath/exceptions/UndefinedException.hpp"
#include "fintamath/functions/arithmetic/Sub.hpp"
#include "fintamath/functions/arithmetic/UnaryPlus.hpp"
#include "fintamath/literals/Variable.hpp"
#include "fintamath/numbers/Rational.hpp"
#include "fintamath/numbers/Real.hpp"

using namespace fintamath;

const PowF f;

TEST(PowFTests, toStringTest) {
EXPECT_EQ(f.toString(), "pow");
}

TEST(PowFTests, getFunctionTypeTest) {
EXPECT_EQ(f.getFunctionType(), IFunction::Type::Binary);
}

TEST(PowFTests, callTest) {
EXPECT_EQ(f(Integer(3), Integer(2))->toString(), "9");
EXPECT_EQ(f(Integer(-3), Integer(2))->toString(), "9");
EXPECT_EQ(f(Integer(3), Integer(-2))->toString(), "1/9");
EXPECT_EQ(f(Rational(5, 2), Integer(2))->toString(), "25/4");
EXPECT_EQ(f(Integer(11), Integer(200))->toString(),
"1899052764604618242121820463954116340585832240009877848127251456103762646167989140750662066593328455813588"
"1805238401044949435868367905913020005911442340062387227375955664576836341689587626164144676307968892001");

EXPECT_EQ(f(Integer(4), Rational(1, 2))->toString(), "2");
EXPECT_EQ(f(Integer(4), Rational(1, 3))->toString(), "root(4, 3)");
EXPECT_EQ(f(Integer(4), Rational(1, 4))->toString(), "sqrt(2)");
EXPECT_EQ(f(Integer(8), Rational(1, 3))->toString(), "2");
EXPECT_EQ(f(Integer(16), Rational(1, 4))->toString(), "2");
EXPECT_EQ(f(Integer(7), Rational(1, 1000))->toString(), "root(7, 1000)");
EXPECT_EQ(f(Integer(4), Rational(5, 2))->toString(), "32");
EXPECT_EQ(f(Integer(4), Rational(5, 3))->toString(), "8 root(2, 3)");
EXPECT_EQ(f(Integer(4), Rational(5, 4))->toString(), "4 sqrt(2)");
EXPECT_EQ(f(Integer(8), Rational(5, 3))->toString(), "32");
EXPECT_EQ(f(Integer(16), Rational(5, 4))->toString(), "32");
EXPECT_EQ(f(Integer(7), Rational(3, 1000))->toString(), "root(343, 1000)");
EXPECT_EQ(f(Integer(1), Rational(1, 1234))->toString(), "1");
EXPECT_EQ(f(Integer(10000000000), Rational(1, 100))->toString(), "root(10, 10)");
EXPECT_EQ(f(Integer(-4), Rational(1))->toString(), "-4");

EXPECT_EQ(f(*f(Integer(10), Integer(100)), Rational(1, 100))->toString(), "10");
EXPECT_EQ(f(*f(Integer(10), Integer(300)), Rational(1, 100))->toString(), "1000");

EXPECT_EQ(f(Integer(4), Rational(-1, 2))->toString(), "1/2");
EXPECT_EQ(f(Integer(4), Rational(-1, 3))->toString(), "1/root(4, 3)");
EXPECT_EQ(f(Integer(4), Rational(-1, 4))->toString(), "1/sqrt(2)");
EXPECT_EQ(f(Integer(8), Rational(-1, 3))->toString(), "1/2");
EXPECT_EQ(f(Integer(16), Rational(-1, 4))->toString(), "1/2");
EXPECT_EQ(f(Integer(4), Rational(-5, 2))->toString(), "1/32");
EXPECT_EQ(f(Integer(4), Rational(-5, 3))->toString(), "1/(8 root(2, 3))");
EXPECT_EQ(f(Integer(4), Rational(-5, 4))->toString(), "1/(4 sqrt(2))");
EXPECT_EQ(f(Integer(8), Rational(-5, 3))->toString(), "1/32");
EXPECT_EQ(f(Integer(16), Rational(-5, 4))->toString(), "1/32");
EXPECT_EQ(f(Integer(7), Rational(-3, 1000))->toString(), "1/root(343, 1000)");

EXPECT_EQ(f(Rational(-10), Rational(-3))->toString(), "-1/1000");
EXPECT_EQ(f(Rational(-1), Rational(-25))->toString(), "-1");
EXPECT_EQ(f(Rational("-2.2"), Rational(-5))->toString(), "-3125/161051");
EXPECT_EQ(f(Rational("2.2"), Rational(-5, 2))->toString(), "(25 sqrt(5/11))/121");

EXPECT_EQ(f(Real("2.2"), Real("2"))->toString(), "4.84");
EXPECT_EQ(f(Real("2.2"), Real("0.5"))->toString(),
"1.48323969741913258974227948816014261219598086381950031974652465286876603686277");

EXPECT_EQ(f(Integer(3), Variable("a"))->toString(), "3^a");
EXPECT_EQ(f(Variable("a"), Rational(1, 2))->toString(), "sqrt(a)");
EXPECT_EQ(f(Variable("a"), Rational(3, 2))->toString(), "a^(3/2)");

EXPECT_THROW(f(Integer(0), Integer(0)), UndefinedException);
EXPECT_THROW(f(Rational("0"), Rational("-10")), UndefinedException);
EXPECT_THROW(f(Rational("-10"), Rational("-1.5")), UndefinedException);

EXPECT_THROW(f(), InvalidInputFunctionException);
EXPECT_THROW(f(Integer(1)), InvalidInputFunctionException);
EXPECT_THROW(f(Rational(2, 3)), InvalidInputFunctionException);
EXPECT_THROW(f(Integer(1), Integer(1), Integer(1)), InvalidInputFunctionException);
}

TEST(PowFTests, doArgsMatchTest) {
Integer a;

EXPECT_FALSE(f.doArgsMatch({}));
EXPECT_FALSE(f.doArgsMatch({a}));
EXPECT_TRUE(f.doArgsMatch({a, a}));
EXPECT_FALSE(f.doArgsMatch({a, a, a}));
}

TEST(PowFTests, equalsTest) {
EXPECT_EQ(f, f);
EXPECT_EQ(f, PowF());
EXPECT_EQ(PowF(), f);
EXPECT_EQ(f, cast<IMathObject>(PowF()));
EXPECT_EQ(cast<IMathObject>(PowF()), f);
EXPECT_NE(f, Sub());
EXPECT_NE(Sub(), f);
EXPECT_NE(f, UnaryPlus());
EXPECT_NE(UnaryPlus(), f);
}

TEST(PowFTests, getTypeIdTest) {
EXPECT_EQ(PowF::getTypeIdStatic(), MathObjectTypeId(MathObjectType::PowF));
EXPECT_EQ(PowF().getTypeId(), MathObjectTypeId(MathObjectType::PowF));
}

0 comments on commit ad5b889

Please sign in to comment.