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 4, 2024
1 parent 37d4156 commit 50c8b91
Show file tree
Hide file tree
Showing 72 changed files with 784 additions and 1,096 deletions.
4 changes: 4 additions & 0 deletions include/fintamath/core/IMathObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class IMathObject {
virtual MathObjectClass getClass() const noexcept = 0;

friend bool operator==(const IMathObject &lhs, const IMathObject &rhs) {
if (&lhs == &rhs) {
return true;
}

return lhs.equalsAbstract(rhs);
}

Expand Down
4 changes: 4 additions & 0 deletions include/fintamath/core/IMathObjectCRTP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class IMathObjectCRTP_ : public IMathObject {
}

bool operator==(const I_MATH_OBJECT_CRTP &rhs) const {
if (this == &rhs) {
return true;
}

return equals(cast<Derived>(rhs));
}

Expand Down
28 changes: 8 additions & 20 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,20 +139,16 @@ 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 std::string stringCached;

mutable bool isSimplified = false;
mutable ArgumentPtrVector childrenCached;
};

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

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

template <typename Function>
Expand Down
3 changes: 1 addition & 2 deletions include/fintamath/expressions/ExpressionFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ Expression negInf();

Expression complexInf();

// TODO! move to Expression
Expression solve(const Expression &rhs);

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

}
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
51 changes: 35 additions & 16 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;
const VariableSet &getVariables() 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;

protected:
virtual ArgumentPtr simplify() const;
std::string toString() const override;

protected:
virtual ArgumentPtr preSimplify() const;

virtual ArgumentPtr postSimplify() const;
virtual ArgumentPtr simplify() const;

virtual ArgumentPtr approximate() const;

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

static void simplifyChild(ArgumentPtr &child);
State getState() const;

ArgumentPtr callFunction() const;

static void preSimplifyChild(ArgumentPtr &child);

static void postSimplifyChild(ArgumentPtr &child);
static void simplifyChild(ArgumentPtr &child);

static void approximateChild(ArgumentPtr &child);

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 toStateChild(ArgumentPtr &child, State newState);

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
15 changes: 4 additions & 11 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 @@ -34,14 +32,9 @@ class IBinaryExpression : public IExpression {

virtual SimplifyFunctionVector getFunctionsForPreSimplify() const;

virtual SimplifyFunctionVector getFunctionsForPostSimplify() const;
virtual SimplifyFunctionVector getFunctionsForSimplify() const;

ArgumentPtr preSimplify() const override;

ArgumentPtr postSimplify() const override;

private:
ArgumentPtr simplifyRec(bool isPostSimplify) const;
ArgumentPtr toState(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 @@ -36,28 +34,24 @@ class IPolynomExpression : public IExpression {

virtual SimplifyFunctionVector getFunctionsForPreSimplify() const;

virtual SimplifyFunctionVector getFunctionsForPostSimplify() const;
virtual SimplifyFunctionVector getFunctionsForSimplify() const;

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

ArgumentPtr preSimplify() const override;

ArgumentPtr postSimplify() const override;

virtual bool isTermOrderInversed() const noexcept;

virtual bool isComparableOrderInversed() const noexcept;

virtual std::strong_ordering compare(const ArgumentPtr &lhs, const ArgumentPtr &rhs) const;

private:
void simplifyRec(bool isPostSimplify);

void simplifyChildren(bool isPostSimplify);
ArgumentPtr toState(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
14 changes: 4 additions & 10 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 @@ -34,22 +32,18 @@ class IUnaryExpression : public IExpression {

virtual SimplifyFunctionVector getFunctionsForPreSimplify() const;

virtual SimplifyFunctionVector getFunctionsForPostSimplify() const;

ArgumentPtr preSimplify() const override;

ArgumentPtr postSimplify() const override;
virtual SimplifyFunctionVector getFunctionsForSimplify() const;

protected:
std::shared_ptr<IFunction> func;

ArgumentPtr child;

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

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

template <typename Derived>
Expand Down
2 changes: 1 addition & 1 deletion include/fintamath/numbers/Complex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Complex : public INumberCRTP<Complex> {

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

bool isPrecise() const noexcept override;
std::optional<unsigned> getPrecision() const noexcept override;

bool isComplex() const noexcept override;

Expand Down
5 changes: 3 additions & 2 deletions include/fintamath/numbers/INumber.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <concepts>
#include <memory>
#include <optional>
#include <string>
#include <utility>

Expand All @@ -17,8 +18,8 @@ class INumber : public IComparable {
FINTAMATH_PARENT_CLASS_BODY(INumber, IComparable)

public:
virtual bool isPrecise() const noexcept {
return true;
virtual std::optional<unsigned> getPrecision() const noexcept {
return {};
}

virtual bool isComplex() const noexcept {
Expand Down
Loading

0 comments on commit 50c8b91

Please sign in to comment.