Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy computations in Expression #150

Merged
merged 2 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 43 additions & 28 deletions include/fintamath/expressions/Expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ class Expression : public IExpressionCRTP<Expression> {

Expression precise(uint8_t precision = FINTAMATH_PRECISION) const;

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

ArgumentPtrVector getChildren() const override;
const ArgumentPtrVector &getChildren() const override;

void setChildren(const ArgumentPtrVector &childVect) override;

Expand All @@ -54,31 +54,7 @@ class Expression : public IExpressionCRTP<Expression> {
}

template <typename Function, bool isPolynomial = false>
static void registerFunctionExpressionMaker(auto &&maker) {
Parser::Function<std::unique_ptr<IMathObject>, const ArgumentPtrVector &> constructor =
[maker = std::forward<decltype(maker)>(maker)](const ArgumentPtrVector &args) {
static const IFunction::Type type = Function().getFunctionType();
std::unique_ptr<IMathObject> res;

if constexpr (IsFunctionTypeAny<Function>::value) {
res = maker(args);
}
else if constexpr (isPolynomial) {
if (size_t(type) <= args.size()) {
res = maker(args);
}
}
else {
if (size_t(type) == args.size()) {
res = maker(args);
}
}

return res;
};

Parser::add<Function>(getExpressionMakers(), std::move(constructor));
}
static void registerFunctionExpressionMaker(auto &&maker);

static MathObjectType getTypeStatic() {
return MathObjectType::Expression;
Expand All @@ -100,6 +76,10 @@ class Expression : public IExpressionCRTP<Expression> {
ArgumentPtr preciseSimplify() const override;

private:
void simplifyMutable() const;

void updateStringMutable() const;

bool parseOperator(const TermVector &terms, size_t start, size_t end);

bool parseFunction(const TermVector &terms, size_t start, size_t end);
Expand Down Expand Up @@ -142,6 +122,8 @@ class Expression : public IExpressionCRTP<Expression> {

static void preciseRec(ArgumentPtr &arg, uint8_t precision);

static ArgumentPtr compress(const ArgumentPtr &child);

friend std::unique_ptr<IMathObject> makeExpr(const IFunction &func, const ArgumentPtrVector &args);

friend ArgumentPtr parseExpr(const std::string &str);
Expand All @@ -155,7 +137,13 @@ class Expression : public IExpressionCRTP<Expression> {
static Parser::Map<std::unique_ptr<IMathObject>, const ArgumentPtrVector &> &getExpressionMakers();

private:
ArgumentPtr child;
mutable ArgumentPtr child;

mutable ArgumentPtrVector childrenCached = {{}};

mutable std::string stringCached;

mutable bool isSimplified = false;
};

ArgumentPtr parseExpr(const std::string &str);
Expand Down Expand Up @@ -188,4 +176,31 @@ Expression operator/(const Expression &lhs, const Variable &rhs);

Expression operator/(const Variable &lhs, const Expression &rhs);

template <typename Function, bool isPolynomial>
inline void Expression::registerFunctionExpressionMaker(auto &&maker) {
Parser::Function<std::unique_ptr<IMathObject>, const ArgumentPtrVector &> constructor =
[maker = std::forward<decltype(maker)>(maker)](const ArgumentPtrVector &args) {
static const IFunction::Type type = Function().getFunctionType();
std::unique_ptr<IMathObject> res;

if constexpr (IsFunctionTypeAny<Function>::value) {
res = maker(args);
}
else if constexpr (isPolynomial) {
if (size_t(type) <= args.size()) {
res = maker(args);
}
}
else {
if (size_t(type) == args.size()) {
res = maker(args);
}
}

return res;
};

Parser::add<Function>(getExpressionMakers(), std::move(constructor));
}

}
8 changes: 3 additions & 5 deletions include/fintamath/expressions/IExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ namespace fintamath {

class IExpression : public IArithmetic {
public:
virtual std::shared_ptr<IFunction> getFunction() const = 0;
virtual const std::shared_ptr<IFunction> &getFunction() const = 0;

virtual ArgumentPtrVector getChildren() const = 0;
virtual const ArgumentPtrVector &getChildren() const = 0;

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

Expand Down Expand Up @@ -45,9 +45,7 @@ class IExpression : public IArithmetic {

virtual ArgumentPtr postSimplify() const;

virtual ArgumentPtr preciseSimplify() const = 0;

static void compressChild(ArgumentPtr &child);
virtual ArgumentPtr preciseSimplify() const;

static void simplifyChild(ArgumentPtr &child);

Expand Down
4 changes: 2 additions & 2 deletions include/fintamath/expressions/IExpressionCRTP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class IExpressionCRTP_ : public IExpressionBaseCRTP<Derived, isMultiFunction> {
}
}

ArgumentPtrVector lhsChildren = this->getChildren();
ArgumentPtrVector rhsChildren = rhs.getChildren();
const ArgumentPtrVector &lhsChildren = this->getChildren();
const ArgumentPtrVector &rhsChildren = rhs.getChildren();

if (lhsChildren.size() != rhsChildren.size()) {
return false;
Expand Down
15 changes: 6 additions & 9 deletions include/fintamath/expressions/interfaces/IBinaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class IBinaryExpression : public IExpression {
public:
std::string toString() const override;

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

ArgumentPtrVector getChildren() const final;
const ArgumentPtrVector &getChildren() const final;

void setChildren(const ArgumentPtrVector &childVect) final;

Expand All @@ -31,8 +31,6 @@ class IBinaryExpression : public IExpression {

ArgumentPtr postSimplify() const override;

ArgumentPtr preciseSimplify() const override;

private:
ArgumentPtr useSimplifyFunctions(const SimplifyFunctionVector &simplFuncs) const;

Expand All @@ -42,6 +40,9 @@ class IBinaryExpression : public IExpression {
ArgumentPtr lhsChild;

ArgumentPtr rhsChild;

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

template <typename Derived, bool isMultiFunction = false>
Expand All @@ -60,13 +61,9 @@ class IBinaryExpressionCRTP : public IBinaryExpressionBaseCRTP<Derived, isMultiF
public:
explicit IBinaryExpressionCRTP(const IFunction &inFunc, const ArgumentPtr &lhs, const ArgumentPtr &rhs) {
this->func = cast<IFunction>(inFunc.clone());

this->lhsChild = lhs;
this->compressChild(this->lhsChild);

this->rhsChild = rhs;
this->compressChild(this->rhsChild);
}
};

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class IPolynomExpression : public IExpression {
public:
std::string toString() const override;

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

ArgumentPtrVector getChildren() const final;
const ArgumentPtrVector &getChildren() const final;

void setChildren(const ArgumentPtrVector &childVect) final;

Expand Down Expand Up @@ -60,8 +60,6 @@ class IPolynomExpression : public IExpression {

ArgumentPtr postSimplify() const override;

ArgumentPtr preciseSimplify() const override;

virtual bool isTermsOrderInversed() const;

virtual bool isComparableOrderInversed() const;
Expand Down Expand Up @@ -187,7 +185,6 @@ class IPolynomExpressionCRTP : public IPolynomExpressionBaseCRTP<Derived, isMult

void addElement(const ArgumentPtr &element) final {
ArgumentPtr elem = element;
this->compressChild(elem);

ArgumentPtrVector elemPolynom;

Expand Down
11 changes: 5 additions & 6 deletions include/fintamath/expressions/interfaces/IUnaryExpression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class IUnaryExpression : public IExpression {
public:
std::string toString() const override;

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

ArgumentPtrVector getChildren() const override;
const ArgumentPtrVector &getChildren() const override;

void setChildren(const ArgumentPtrVector &childVect) override;

Expand All @@ -31,15 +31,16 @@ class IUnaryExpression : public IExpression {

ArgumentPtr postSimplify() const override;

ArgumentPtr preciseSimplify() const override;

private:
ArgumentPtr useSimplifyFunctions(const SimplifyFunctionVector &simplFuncs) const;

protected:
std::shared_ptr<IFunction> func;

ArgumentPtr child;

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

template <typename Derived, bool isMultiFunction = false>
Expand All @@ -58,9 +59,7 @@ class IUnaryExpressionCRTP : public IUnaryExpressionBaseCRTP<Derived, isMultiFun
public:
explicit IUnaryExpressionCRTP(const IFunction &inFunc, const ArgumentPtr &arg) {
this->func = cast<IFunction>(inFunc.clone());

this->child = arg;
this->compressChild(this->child);
}
};

Expand Down
Loading