Skip to content

Commit

Permalink
Make expressions immutable and improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed May 5, 2024
1 parent 32a5143 commit 260214e
Show file tree
Hide file tree
Showing 34 changed files with 984 additions and 1,333 deletions.
28 changes: 9 additions & 19 deletions include/fintamath/expressions/Expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "fintamath/functions/IFunction.hpp"
#include "fintamath/functions/IOperator.hpp"
#include "fintamath/literals/Variable.hpp"
#include "fintamath/numbers/Real.hpp"

namespace fintamath {

Expand Down Expand Up @@ -78,29 +79,20 @@ class Expression : public IExpressionCRTP<Expression> {

Expression(int64_t val);

std::string toString() const override;

const std::shared_ptr<IFunction> &getFunction() const override;

const ArgumentPtrVector &getChildren() const override;

void setChildren(const ArgumentPtrVector &childVect) override;
std::string toString() const override;

void setVariables(const std::vector<std::pair<Variable, ArgumentPtr>> &varsToVals) override;
std::unique_ptr<IMathObject> toMinimalObject() const override;

void setVariable(const Variable &var, const Expression &val);
friend Expression approximate(const Expression &rhs, unsigned precision);

template <typename Function>
static void registerExpressionConstructor(ExpressionConstructor constructor);

protected:
ArgumentPtr simplify() const override;

private:
void simplifyMutable() const;

void updateStringMutable() const;

static detail::TermVector tokensToTerms(detail::TokenVector &tokens);

static detail::ObjectStack termsToObjects(detail::TermVector &terms);
Expand Down Expand Up @@ -147,19 +139,17 @@ class Expression : public IExpressionCRTP<Expression> {

friend std::unique_ptr<IMathObject> parseRawExpr(const std::string &str);

friend Expression approximate(const Expression &rhs, unsigned precision);

static ExpressionMaker &getExpressionMaker();

private:
mutable ArgumentPtr child;
ArgumentPtr child;

mutable ArgumentPtrVector childrenCached = {{}};
mutable ArgumentPtrVector childrenCached;
};

mutable std::string stringCached;
Expression solve(const Expression &rhs);

mutable bool isSimplified = false;
};
Expression approximate(const Expression &rhs, unsigned precision = Real::getPrecisionStatic());

std::unique_ptr<IMathObject> parseRawExpr(const std::string &str);

Expand Down
4 changes: 0 additions & 4 deletions include/fintamath/expressions/ExpressionFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,4 @@ Expression negInf();

Expression complexInf();

Expression solve(const Expression &rhs);

extern Expression approximate(const Expression &rhs, unsigned precision = Real::getPrecisionStatic());

}
17 changes: 0 additions & 17 deletions include/fintamath/expressions/ExpressionUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,6 @@ ArgumentPtr useSimplifyFunctions(const std::vector<SimplifyFunction> &simplFuncs
return {};
}

ArgumentPtr simplifyUndefined(const IFunction &func, const std::same_as<ArgumentPtr> auto &...args) {
ArgumentPtr res;

if ((is<Undefined>(args) || ...)) {
static const MathObjectClass undefinedReturnType = Undefined{}.getReturnClass();
const MathObjectClass funcReturnType = func.getReturnClass();

if (is(undefinedReturnType, funcReturnType) ||
is(funcReturnType, undefinedReturnType)) {

res = Undefined{}.clone();
}
}

return res;
}

bool isInfinity(const ArgumentPtr &arg);

bool isMulInfinity(const ArgumentPtr &arg);
Expand Down
57 changes: 38 additions & 19 deletions include/fintamath/expressions/IExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@ namespace fintamath {
class IExpression : public IMathObject {
FINTAMATH_PARENT_CLASS_BODY(IExpression, IMathObject)

protected:
enum class State : uint8_t {
Unknown,
PreSimplify,
Simplify,
Solve,
Approximate,
};

private:
struct CallFunctionCached {
ArgumentPtr value;
std::optional<unsigned> precision;
bool areArgsPrecise = true;
};

public:
using VariableSet = std::set<Variable, ToStringComparator<std::less<>>>;

Expand All @@ -30,45 +46,48 @@ class IExpression : public IMathObject {

virtual const ArgumentPtrVector &getChildren() const = 0;

virtual void setChildren(const ArgumentPtrVector &childVect) = 0;

VariableSet getVariables() const;
const VariableSet &getVariables() const;

virtual void setVariables(const std::vector<std::pair<Variable, ArgumentPtr>> &varsToVals);

std::unique_ptr<IMathObject> toMinimalObject() const final;
std::unique_ptr<IMathObject> toMinimalObject() const override;

virtual const std::shared_ptr<IFunction> &getOutputFunction() const;

std::string toString() const override;

protected:
virtual ArgumentPtr simplify() const;
virtual ArgumentPtr preSimplify(bool isTranformOverriden = true) const;

virtual ArgumentPtr preSimplify() const;
virtual ArgumentPtr simplify(bool isTranformOverriden = true) const;

virtual ArgumentPtr postSimplify() const;
virtual ArgumentPtr approximate(bool isTranformOverriden = true) const;

virtual ArgumentPtr approximate() const;
virtual ArgumentPtr tranform(State newState) const;

virtual ArgumentPtr setPrecision(unsigned precision, const Integer &maxInt) const;
State getState() const;

static void simplifyChild(ArgumentPtr &child);
ArgumentPtr callFunction() const;

static void preSimplifyChild(ArgumentPtr &child);
static void preSimplifyChild(ArgumentPtr &child, bool isTranformOverriden = true);

static void postSimplifyChild(ArgumentPtr &child);
static void simplifyChild(ArgumentPtr &child, bool isTranformOverriden = true);

static void approximateChild(ArgumentPtr &child);
static void approximateChild(ArgumentPtr &child, bool isTranformOverriden = true);

static void setPrecisionChild(ArgumentPtr &child, unsigned precision, const Integer &maxInt);
static void callFunctionChild(ArgumentPtr &child);

static ArgumentPtr callFunction(const IFunction &func, const ArgumentPtrVector &argPtrs);
static void tranformChild(ArgumentPtr &child, State newState, bool isOverriden);

private:
ArgumentPtr simplifyUndefined() const;

static std::unique_ptr<INumber> convertToApproximated(const INumber &num);

static std::unique_ptr<INumber> convertToApproximated(const INumber &num, unsigned precision, const Integer &maxInt);
private:
mutable std::optional<VariableSet> variablesCached;

mutable std::optional<CallFunctionCached> callFunctionCached;

static ArgumentPtrVector convertToApproximatedNumbers(const ArgumentPtrVector &args);
mutable State state = State::Unknown;
};

template <typename Derived>
Expand Down
13 changes: 3 additions & 10 deletions include/fintamath/expressions/interfaces/IBinaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ class IBinaryExpression : public IExpression {
public:
explicit IBinaryExpression(const IFunction &inFunc, ArgumentPtr lhs, ArgumentPtr rhs);

std::string toString() const override;

const std::shared_ptr<IFunction> &getFunction() const final;

const ArgumentPtrVector &getChildren() const final;

void setChildren(const ArgumentPtrVector &childVect) final;
std::string toString() const override;

protected:
using SimplifyFunction = std::function<ArgumentPtr(const IFunction &, const ArgumentPtr &, const ArgumentPtr &)>;
Expand All @@ -36,12 +34,7 @@ class IBinaryExpression : public IExpression {

virtual SimplifyFunctionVector getFunctionsForPostSimplify() const;

ArgumentPtr preSimplify() const override;

ArgumentPtr postSimplify() const override;

private:
ArgumentPtr simplifyRec(bool isPostSimplify) const;
ArgumentPtr tranform(State newState) const override;

protected:
std::shared_ptr<IFunction> func;
Expand All @@ -51,7 +44,7 @@ class IBinaryExpression : public IExpression {
ArgumentPtr rhsChild;

private:
mutable ArgumentPtrVector childrenCached = {{}, {}};
mutable ArgumentPtrVector childrenCached;
};

template <typename Derived>
Expand Down
16 changes: 5 additions & 11 deletions include/fintamath/expressions/interfaces/IPolynomExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ class IPolynomExpression : public IExpression {
public:
explicit IPolynomExpression(const IFunction &inFunc, ArgumentPtrVector args);

std::string toString() const override;

const std::shared_ptr<IFunction> &getFunction() const final;

const ArgumentPtrVector &getChildren() const final;

void setChildren(const ArgumentPtrVector &childVect) final;
std::string toString() const override;

protected:
using SimplifyFunction = std::function<ArgumentPtr(const IFunction &, const ArgumentPtr &, const ArgumentPtr &)>;
Expand All @@ -40,9 +38,7 @@ class IPolynomExpression : public IExpression {

virtual std::string childToString(const IOperator &oper, const ArgumentPtr &inChild, const ArgumentPtr &prevChild) const;

ArgumentPtr preSimplify() const override;

ArgumentPtr postSimplify() const override;
ArgumentPtr preSimplify(bool isTranformOverriden = true) const override;

virtual bool isTermOrderInversed() const noexcept;

Expand All @@ -51,13 +47,11 @@ class IPolynomExpression : public IExpression {
virtual std::strong_ordering compare(const ArgumentPtr &lhs, const ArgumentPtr &rhs) const;

private:
void simplifyRec(bool isPostSimplify);

void simplifyChildren(bool isPostSimplify);
ArgumentPtr tranform(State newState) const override;

void compress();
void compress(ArgumentPtrVector &newChildren) const;

void sort();
void sort(ArgumentPtrVector &newChildren) const;

protected:
std::shared_ptr<IFunction> func;
Expand Down
12 changes: 3 additions & 9 deletions include/fintamath/expressions/interfaces/IUnaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ class IUnaryExpression : public IExpression {
public:
explicit IUnaryExpression(const IFunction &inFunc, ArgumentPtr rhs);

std::string toString() const override;

const std::shared_ptr<IFunction> &getFunction() const final;

const ArgumentPtrVector &getChildren() const override;

void setChildren(const ArgumentPtrVector &childVect) override;
std::string toString() const override;

protected:
using SimplifyFunction = std::function<ArgumentPtr(const IFunction &, const ArgumentPtr &)>;
Expand All @@ -36,20 +34,16 @@ class IUnaryExpression : public IExpression {

virtual SimplifyFunctionVector getFunctionsForPostSimplify() const;

ArgumentPtr preSimplify() const override;

ArgumentPtr postSimplify() const override;

protected:
std::shared_ptr<IFunction> func;

ArgumentPtr child;

private:
ArgumentPtr simplifyRec(bool isPostSimplify) const;
ArgumentPtr tranform(State newState) const override;

private:
mutable ArgumentPtrVector childrenCached = {{}};
mutable ArgumentPtrVector childrenCached;
};

template <typename Derived>
Expand Down
Loading

0 comments on commit 260214e

Please sign in to comment.