From 5aae6b83acd28c37e65ace22a77ee4b27523f2a8 Mon Sep 17 00:00:00 2001 From: Abd-El-Aziz Zayed Date: Thu, 5 Jan 2023 17:22:18 -0500 Subject: [PATCH 1/6] Use shared pointers instead of raw --- .github/workflows/cmake-ubuntu.yml | 4 +- cas/include/cas/data/ExpressionParser.h | 2 +- cas/include/cas/data/ExpressionProperties.h | 3 +- cas/include/cas/data/VariableMap.h | 2 + cas/include/cas/node/Abs.h | 10 +- cas/include/cas/node/BracketExpression.h | 6 +- cas/include/cas/node/Cbrt.h | 10 +- cas/include/cas/node/Ceil.h | 10 +- cas/include/cas/node/Const.h | 28 +-- cas/include/cas/node/Divide.h | 28 +-- cas/include/cas/node/Exp.h | 10 +- cas/include/cas/node/Expression.h | 184 +++++++++------- cas/include/cas/node/Floor.h | 8 +- cas/include/cas/node/IMath.h | 9 +- cas/include/cas/node/Ln.h | 12 +- cas/include/cas/node/Log.h | 32 +-- cas/include/cas/node/Max.h | 8 +- cas/include/cas/node/Min.h | 8 +- cas/include/cas/node/Mod.h | 22 +- cas/include/cas/node/NaryExpression.h | 12 +- cas/include/cas/node/Negate.h | 12 +- cas/include/cas/node/Operator.h | 14 +- cas/include/cas/node/Power.h | 28 +-- cas/include/cas/node/Prod.h | 40 ++++ cas/include/cas/node/Product.h | 38 ---- cas/include/cas/node/Root.h | 15 +- cas/include/cas/node/Round.h | 8 +- cas/include/cas/node/Sign.h | 10 +- cas/include/cas/node/Sqrt.h | 10 +- cas/include/cas/node/Sum.h | 12 +- cas/include/cas/node/UnaryExpression.h | 12 +- cas/include/cas/node/Var.h | 41 ++-- cas/include/cas/node/trig/ArcCos.h | 10 +- cas/include/cas/node/trig/ArcCot.h | 10 +- cas/include/cas/node/trig/ArcCsc.h | 10 +- cas/include/cas/node/trig/ArcSec.h | 10 +- cas/include/cas/node/trig/ArcSin.h | 10 +- cas/include/cas/node/trig/ArcTan.h | 10 +- cas/include/cas/node/trig/Cos.h | 10 +- cas/include/cas/node/trig/Cot.h | 10 +- cas/include/cas/node/trig/Csc.h | 10 +- .../cas/node/trig/InverseTrigExpression.h | 2 +- cas/include/cas/node/trig/Sec.h | 10 +- cas/include/cas/node/trig/Sin.h | 10 +- cas/include/cas/node/trig/Tan.h | 10 +- cas/include/cas/node/trig/TrigExpression.h | 10 +- cas/include/cas/plot/Function.h | 12 +- cas/include/cas/plot/Surface.h | 75 ------- cas/src/CMakeLists.txt | 2 +- cas/src/core/data/ExpressionParser.cpp | 182 ++++++++-------- cas/src/core/data/ExpressionProperties.cpp | 2 +- cas/src/core/node/Abs.cpp | 12 +- cas/src/core/node/BracketExpression.cpp | 8 +- cas/src/core/node/Cbrt.cpp | 22 +- cas/src/core/node/Ceil.cpp | 12 +- cas/src/core/node/Const.cpp | 10 +- cas/src/core/node/Divide.cpp | 40 ++-- cas/src/core/node/Exp.cpp | 16 +- cas/src/core/node/Expression.cpp | 202 +++++++++--------- cas/src/core/node/Floor.cpp | 12 +- cas/src/core/node/Ln.cpp | 18 +- cas/src/core/node/Log.cpp | 52 ++--- cas/src/core/node/Max.cpp | 26 +-- cas/src/core/node/Min.cpp | 26 +-- cas/src/core/node/Mod.cpp | 30 +-- cas/src/core/node/NaryExpression.cpp | 17 +- cas/src/core/node/Negate.cpp | 20 +- cas/src/core/node/Operator.cpp | 18 +- cas/src/core/node/Power.cpp | 113 ++++------ cas/src/core/node/Product.cpp | 47 ++-- cas/src/core/node/Root.cpp | 16 +- cas/src/core/node/Round.cpp | 10 +- cas/src/core/node/Sign.cpp | 18 +- cas/src/core/node/Sqrt.cpp | 28 +-- cas/src/core/node/Sum.cpp | 31 ++- cas/src/core/node/UnaryExpression.cpp | 17 +- cas/src/core/node/Var.cpp | 16 +- cas/src/core/node/trig/ArcCos.cpp | 10 +- cas/src/core/node/trig/ArcCot.cpp | 16 +- cas/src/core/node/trig/ArcCsc.cpp | 12 +- cas/src/core/node/trig/ArcSec.cpp | 12 +- cas/src/core/node/trig/ArcSin.cpp | 15 +- cas/src/core/node/trig/ArcTan.cpp | 14 +- cas/src/core/node/trig/Cos.cpp | 21 +- cas/src/core/node/trig/Cot.cpp | 28 +-- cas/src/core/node/trig/Csc.cpp | 26 +-- .../core/node/trig/InverseTrigExpression.cpp | 2 +- cas/src/core/node/trig/Sec.cpp | 24 +-- cas/src/core/node/trig/Sin.cpp | 16 +- cas/src/core/node/trig/Tan.cpp | 16 +- cas/src/core/node/trig/TrigExpression.cpp | 8 +- cas/src/core/plot/Function.cpp | 24 +-- cas/tests/core/data/ExpressionParserTest.cpp | 2 +- cas/tests/core/node/ArcCscNodeTest.cpp | 2 +- cas/tests/core/node/ArcSecNodeTest.cpp | 2 +- cas/tests/core/node/CbrtNodeTest.cpp | 2 +- cas/tests/core/node/DivideNodeTest.cpp | 2 +- cas/tests/core/node/ExpNodeTest.cpp | 2 +- cas/tests/core/node/ProductNodeTest.cpp | 2 +- cas/tests/core/plot/FunctionTest.cpp | 2 +- 100 files changed, 1061 insertions(+), 1089 deletions(-) create mode 100644 cas/include/cas/node/Prod.h delete mode 100644 cas/include/cas/node/Product.h delete mode 100644 cas/include/cas/plot/Surface.h diff --git a/.github/workflows/cmake-ubuntu.yml b/.github/workflows/cmake-ubuntu.yml index b2337ef..9c2122d 100644 --- a/.github/workflows/cmake-ubuntu.yml +++ b/.github/workflows/cmake-ubuntu.yml @@ -20,8 +20,8 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Install dependencies - run: | + - name: Install Dependencies + run: | sudo apt-get update sudo apt-get install -y openssl libssl-dev libx11-dev xorg-dev diff --git a/cas/include/cas/data/ExpressionParser.h b/cas/include/cas/data/ExpressionParser.h index cea4f64..26e4ceb 100644 --- a/cas/include/cas/data/ExpressionParser.h +++ b/cas/include/cas/data/ExpressionParser.h @@ -13,7 +13,7 @@ CAS_NAMESPACE class ExpressionParser { public: static ExpressionParser& getInstance(); - Expression* parse(const std::string& expression, VarSet& variables); + ExprPtr parse(const std::string& expression, VarSet& variables); void setup(std::string& expr); bool isValidExpression(const std::string& expr); diff --git a/cas/include/cas/data/ExpressionProperties.h b/cas/include/cas/data/ExpressionProperties.h index 2cef42b..0afe600 100644 --- a/cas/include/cas/data/ExpressionProperties.h +++ b/cas/include/cas/data/ExpressionProperties.h @@ -10,10 +10,11 @@ CAS_NAMESPACE +// TODO redesign so this is never copied + class ExpressionProperties { public: ExpressionProperties(ExpressionType type, std::string name, std::string shortName); - bool operator==(const ExpressionProperties& other) const; uint16_t getOrder() const; diff --git a/cas/include/cas/data/VariableMap.h b/cas/include/cas/data/VariableMap.h index 0f51f8f..f06ac6b 100644 --- a/cas/include/cas/data/VariableMap.h +++ b/cas/include/cas/data/VariableMap.h @@ -12,6 +12,8 @@ CAS_NAMESPACE +// TODO redesign to store std::pairs so iterators can be references + struct LetterMap { static const char LETTER_COUNT = 26; char letters = 0; diff --git a/cas/include/cas/node/Abs.h b/cas/include/cas/node/Abs.h index ddae4d7..582b20e 100644 --- a/cas/include/cas/node/Abs.h +++ b/cas/include/cas/node/Abs.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Abs : public BracketExpression { public: - explicit Abs(Expression* argument); + explicit Abs(ExprPtr argument); Abs() = delete; @@ -19,11 +19,15 @@ class Abs : public BracketExpression { double evaluate(const VariableMap& variables) override; - Abs* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; std::string text() override; + + static ExprPtr from(ExprPtr argument) { + return std::make_shared(argument); + } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/BracketExpression.h b/cas/include/cas/node/BracketExpression.h index 9f0296a..c28a999 100644 --- a/cas/include/cas/node/BracketExpression.h +++ b/cas/include/cas/node/BracketExpression.h @@ -15,9 +15,9 @@ class BracketExpression : public UnaryExpression { ~BracketExpression() override = default; - bool _equals(Expression* other) override; + bool _equals(ExprPtr other) override; - Expression* derivative(char var) override; + ExprPtr derivative(char var) override; std::string latex() override; @@ -28,7 +28,7 @@ class BracketExpression : public UnaryExpression { std::string explicitText() override; protected: - explicit BracketExpression(const ExpressionProperties& properties, Expression* argument, + explicit BracketExpression(const ExpressionProperties& properties, ExprPtr argument, const wchar_t* openBracket, const wchar_t* closeBracket, const char* openBracketLatex, const char* closeBracketLatex); diff --git a/cas/include/cas/node/Cbrt.h b/cas/include/cas/node/Cbrt.h index 4d7c578..80576b8 100644 --- a/cas/include/cas/node/Cbrt.h +++ b/cas/include/cas/node/Cbrt.h @@ -11,19 +11,21 @@ CAS_NAMESPACE class Cbrt : public Root { public: - explicit Cbrt(Expression* base); + explicit Cbrt(ExprPtr base); Cbrt() = delete; ~Cbrt() override = default; double evaluate(const VariableMap& variables) override; - Cbrt* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; std::string latex() override; std::wstring stringify() override; std::string text() override; std::string explicitText() override; + + static CbrtPtr from(ExprPtr base) { return std::make_shared(base); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Ceil.h b/cas/include/cas/node/Ceil.h index df77d48..a3965bf 100644 --- a/cas/include/cas/node/Ceil.h +++ b/cas/include/cas/node/Ceil.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Ceil : public BracketExpression { public: - explicit Ceil(Expression* argument); + explicit Ceil(ExprPtr argument); Ceil() = delete; @@ -19,9 +19,13 @@ class Ceil : public BracketExpression { double evaluate(const VariableMap& variables) override; - Ceil* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; + + static ExprPtr from(ExprPtr argument) { + return std::make_shared(argument); + } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Const.h b/cas/include/cas/node/Const.h index a401663..ed631f9 100644 --- a/cas/include/cas/node/Const.h +++ b/cas/include/cas/node/Const.h @@ -1,6 +1,7 @@ // // Created by Abd-El-Aziz Zayed on 2022-08-26. // + #ifndef CAS_CONSTANT_H #define CAS_CONSTANT_H @@ -9,23 +10,21 @@ CAS_NAMESPACE -class Const : public Expression { +class Const : public Expr { public: explicit Const(double value); - - explicit Const() : Const(0.0){}; - + Const() = delete; ~Const() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Const* clone() override; + ExprPtr clone() override; - Const* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Const* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -35,17 +34,18 @@ class Const : public Expression { double getValue() const { return value; } - static Const* PI() { return new Const{math::PI}; } + static ConstPtr PI() { return n(math::PI); } - static Const* E() { return new Const{math::E}; } + static ConstPtr E() { return n(math::E); } - static Const* PHI() { return new Const{math::PHI}; } + static ConstPtr PHI() { return n(math::PHI); } - static Const* zero() { return new Const; } + static ConstPtr zero() { return n(0.0); } - static Const* one() { return new Const{1.0}; } + static ConstPtr one() { return n(1.0); } - static Const* n(double value) { return new Const{value}; } + static ConstPtr n(double value) { return std::make_shared(value); } + static ConstPtr from(double value) { return n(value); } static bool floatingsEqual(double a, double b) { double max = std::max(1.0, std::max(std::fabs(a), std::fabs(b))); diff --git a/cas/include/cas/node/Divide.h b/cas/include/cas/node/Divide.h index 1b5231f..bcfc3ed 100644 --- a/cas/include/cas/node/Divide.h +++ b/cas/include/cas/node/Divide.h @@ -10,23 +10,22 @@ CAS_NAMESPACE -class Divide : public Expression { +class Divide : public Expr { public: - explicit Divide(Expression* dividend, Expression* divisor); - Divide() = delete; + explicit Divide(ExprPtr dividend, ExprPtr divisor); - ~Divide() override; + ~Divide() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Divide* clone() override; + ExprPtr clone() override; - Divide* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -36,12 +35,17 @@ class Divide : public Expression { std::string explicitText() override; - Expression* getDividend() const { return dividend; } - Expression* getDivisor() const { return divisor; } + static DividePtr from(ExprPtr dividend, ExprPtr divisor) { return std::make_shared(dividend, divisor); } + + ExprPtr getDividend() const { return dividend; } + ExprPtr getDivisor() const { return divisor; } + +private: + void setParents(); private: - Expression* dividend; - Expression* divisor; + ExprPtr dividend; + ExprPtr divisor; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Exp.h b/cas/include/cas/node/Exp.h index 96e9e9a..887b5db 100644 --- a/cas/include/cas/node/Exp.h +++ b/cas/include/cas/node/Exp.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Exp : public Power { public: - explicit Exp(Expression* exponent); + explicit Exp(ExprPtr exponent); Exp() = delete; @@ -19,13 +19,15 @@ class Exp : public Power { double evaluate(const VariableMap& variables) override; - Exp* clone() override; + ExprPtr clone() override; - Expression* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string explicitText() override; + + static ExpPtr from(ExprPtr exponent) { return std::make_shared(exponent); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Expression.h b/cas/include/cas/node/Expression.h index 448c2fd..c6a59cd 100644 --- a/cas/include/cas/node/Expression.h +++ b/cas/include/cas/node/Expression.h @@ -12,7 +12,10 @@ CAS_NAMESPACE -class Product; +class Const; +class Var; + +class Prod; class Sum; class Divide; class Negate; @@ -46,89 +49,129 @@ class Round; class Sign; class Mod; -class Expression : public IMath, public IRepresentableMath { +class Min; +class Max; + +class Expr; + +using ExprPtr = std::shared_ptr; +using ConstPtr = std::shared_ptr; +using VarPtr = std::shared_ptr; +using ProdPtr = std::shared_ptr; +using SumPtr = std::shared_ptr; +using DividePtr = std::shared_ptr; +using NegatePtr = std::shared_ptr; +using PowerPtr = std::shared_ptr; +using ExpPtr = std::shared_ptr; +using LogPtr = std::shared_ptr; +using LnPtr = std::shared_ptr; +using RootPtr = std::shared_ptr; +using SqrtPtr = std::shared_ptr; +using CbrtPtr = std::shared_ptr; +using SinPtr = std::shared_ptr; +using CosPtr = std::shared_ptr; +using TanPtr = std::shared_ptr; +using CotPtr = std::shared_ptr; +using CscPtr = std::shared_ptr; +using SecPtr = std::shared_ptr; +using ArcSinPtr = std::shared_ptr; +using ArcCosPtr = std::shared_ptr; +using ArcTanPtr = std::shared_ptr; +using ArcCotPtr = std::shared_ptr; +using ArcCscPtr = std::shared_ptr; +using ArcSecPtr = std::shared_ptr; +using AbsPtr = std::shared_ptr; +using FloorPtr = std::shared_ptr; +using CeilPtr = std::shared_ptr; +using RoundPtr = std::shared_ptr; +using SignPtr = std::shared_ptr; +using ModPtr = std::shared_ptr; +using MinPtr = std::shared_ptr; +using MaxPtr = std::shared_ptr; + +class Expr : public IMath, public IRepresentableMath, public std::enable_shared_from_this { public: - explicit Expression(const ExpressionProperties& properties); + explicit Expr(const ExpressionProperties& properties); - virtual ~Expression() = default; + virtual ~Expr() = default; - Expression(const Expression& expression) = delete; + Expr(const Expr& expression) = delete; double evaluate(const VariableMap& variables) override; virtual double evaluate(); - virtual bool equals(Expression* expression); - virtual bool _equals(Expression* expression); - - virtual Expression* clone(); - - Expression* derivative(char var) override; - virtual Expression* _derivative(char var); - - Expression* simplified() override; - bool isEquivalent(IMath* expression) override; - - Product* multiply(Expression* expression); - Product* multiply(double value); - Sum* add(Expression* expression); - Sum* subtract(Expression* expression); - Sum* add(double value); - Sum* subtract(double value); - Divide* divide(Expression* expression); - Divide* divide(double divisor); - Negate* negate(); - - Power* power(Expression* expression); - Power* power(double exponent); - Exp* exp(); - Log* log(Expression* base); - Log* log(double base); - Ln* ln(); - - Root* root(Expression* root); - Root* root(double root); - Sqrt* sqrt(); - Cbrt* cbrt(); - - Cos* cos(); - Sin* sin(); - Tan* tan(); - ArcTan* atan(); - ArcCos* acos(); - ArcSin* asin(); - Csc* csc(); - Sec* sec(); - Cot* cot(); - ArcCsc* acsc(); - ArcSec* asec(); - ArcCot* acot(); - - Abs* abs(); - Floor* floor(); - Ceil* ceil(); - Round* round(); - Sign* sign(); - Mod* mod(Expression* expression); - - Expression* reciprocal(); - - bool operator<(const Expression& expression) const; - - bool lessThan(Expression* expression) const; - - static bool compare(Expression* left, Expression* right); + virtual bool equals(ExprPtr expression); + virtual bool _equals(ExprPtr expression); + + virtual ExprPtr clone(); + + ExprPtr derivative(char var) override; + virtual ExprPtr _derivative(char var); + + ExprPtr simplified() override; + bool isEquivalent(ExprPtr expression) override; + + ProdPtr multiply(ExprPtr expression); + ProdPtr multiply(double value); + SumPtr add(ExprPtr expression); + SumPtr subtract(ExprPtr expression); + SumPtr add(double value); + SumPtr subtract(double value); + DividePtr divide(ExprPtr expression); + DividePtr divide(double divisor); + NegatePtr negate(); + + PowerPtr power(ExprPtr expression); + PowerPtr power(double exponent); + ExpPtr exp(); + LogPtr log(ExprPtr base); + LogPtr log(double base); + LnPtr ln(); + + RootPtr root(ExprPtr root); + RootPtr root(double root); + SqrtPtr sqrt(); + CbrtPtr cbrt(); + + CosPtr cos(); + SinPtr sin(); + TanPtr tan(); + ArcTanPtr atan(); + ArcCosPtr acos(); + ArcSinPtr asin(); + CscPtr csc(); + SecPtr sec(); + CotPtr cot(); + ArcCscPtr acsc(); + ArcSecPtr asec(); + ArcCotPtr acot(); + + AbsPtr abs(); + FloorPtr floor(); + CeilPtr ceil(); + RoundPtr round(); + SignPtr sign(); + ModPtr mod(ExprPtr expression); + + ExprPtr reciprocal(); + + bool operator<(const Expr& expression) const; + + bool lessThan(ExprPtr expression) const; + + static bool compare(ExprPtr left, ExprPtr right); ExpressionProperties getProperties() const; - Expression* getParent() const; + Expr* getParent() const; - void setParent(Expression* newParent); + void setParent(Expr* newParent); bool isNegated() const; bool isOfType(ExpressionType type) const; - bool isOfSameType(Expression* expression) const; + bool isOfSameType(ExprPtr expression) const; // TODO overload math operators + - * / ^ @@ -136,12 +179,9 @@ class Expression : public IMath, public IRepresentableMath { protected: const ExpressionProperties properties; - Expression* parent = nullptr; + Expr* parent = nullptr; }; -using ExpressionPtr = Expression*; -using ExprPtr = Expression*; - CAS_NAMESPACE_END #endif//CAS_EXPRESSION_H diff --git a/cas/include/cas/node/Floor.h b/cas/include/cas/node/Floor.h index 4eb6601..2885632 100644 --- a/cas/include/cas/node/Floor.h +++ b/cas/include/cas/node/Floor.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Floor : public BracketExpression { public: - explicit Floor(Expression* argument); + explicit Floor(ExprPtr argument); Floor() = delete; @@ -19,9 +19,11 @@ class Floor : public BracketExpression { double evaluate(const VariableMap& variables) override; - Floor* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; + + static FloorPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/IMath.h b/cas/include/cas/node/IMath.h index 7ef936a..6d2e2c3 100644 --- a/cas/include/cas/node/IMath.h +++ b/cas/include/cas/node/IMath.h @@ -5,18 +5,19 @@ #ifndef CAS_IMATH_H #define CAS_IMATH_H -#include #include "cas/CAS.h" #include "cas/data/VariableMap.h" +#include CAS_NAMESPACE +template class IMath { public: virtual double evaluate(const VariableMap& variables) = 0; - virtual IMath* derivative(char var) = 0; - virtual IMath* simplified() = 0; - virtual bool isEquivalent(IMath* expr) = 0; + virtual E derivative(char var) = 0; + virtual E simplified() = 0; + virtual bool isEquivalent(E expr) = 0; }; namespace math { diff --git a/cas/include/cas/node/Ln.h b/cas/include/cas/node/Ln.h index 2fa32e1..5dfc245 100644 --- a/cas/include/cas/node/Ln.h +++ b/cas/include/cas/node/Ln.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Ln : public Log { public: - explicit Ln(Expression* argument); + explicit Ln(ExprPtr argument); Ln() = delete; @@ -19,13 +19,13 @@ class Ln : public Log { double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Ln* clone() override; + ExprPtr clone() override; - Expression* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -34,6 +34,8 @@ class Ln : public Log { std::string text() override; std::string explicitText() override; + + static LnPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Log.h b/cas/include/cas/node/Log.h index baa3197..60c393d 100644 --- a/cas/include/cas/node/Log.h +++ b/cas/include/cas/node/Log.h @@ -9,27 +9,27 @@ CAS_NAMESPACE -class Log : public Expression { +class Log : public Expr { public: - explicit Log(Expression* base, Expression* argument); + explicit Log(ExprPtr base, ExprPtr argument); - explicit Log(double base, Expression* argument); + explicit Log(double base, ExprPtr argument); - explicit Log(Expression* argument); + explicit Log(ExprPtr argument); Log() = delete; - ~Log() override; + ~Log() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Log* clone() override; + ExprPtr clone() override; - Expression* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -39,18 +39,22 @@ class Log : public Expression { std::string explicitText() override; - Expression* getBase() const { return base; } + ExprPtr getBase() const { return base; } - Expression* getArgument() const { return argument; } + ExprPtr getArgument() const { return argument; } + + static LogPtr from(ExprPtr base, ExprPtr argument) { return std::make_shared(base, argument); } + static LogPtr from(double base, ExprPtr argument) { return std::make_shared(base, argument); } + static LogPtr from(ExprPtr argument) { return std::make_shared(argument); } protected: - explicit Log(const ExpressionProperties& props, Expression* base, Expression* argument); + explicit Log(const ExpressionProperties& props, ExprPtr base, ExprPtr argument); bool argumentNeedsParentheses(); protected: - Expression* base; - Expression* argument; + ExprPtr base; + ExprPtr argument; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Max.h b/cas/include/cas/node/Max.h index 16822e4..d70b769 100644 --- a/cas/include/cas/node/Max.h +++ b/cas/include/cas/node/Max.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Max : public NaryExpression { public: - explicit Max(std::vector expressions); + explicit Max(std::vector expressions); Max() = delete; @@ -19,9 +19,11 @@ class Max : public NaryExpression { double evaluate(const VariableMap& variables) override; - Max* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; + + static MaxPtr from(std::vector expressions) { return std::make_shared(expressions); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Min.h b/cas/include/cas/node/Min.h index 8c038e0..3893d5b 100644 --- a/cas/include/cas/node/Min.h +++ b/cas/include/cas/node/Min.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Min : public NaryExpression { public: - explicit Min(std::vector expressions); + explicit Min(std::vector expressions); Min() = delete; @@ -19,9 +19,11 @@ class Min : public NaryExpression { double evaluate(const VariableMap& variables) override; - Min* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; + + static MinPtr from(std::vector expressions) { return std::make_shared(expressions); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Mod.h b/cas/include/cas/node/Mod.h index 2ecc070..07fa95a 100644 --- a/cas/include/cas/node/Mod.h +++ b/cas/include/cas/node/Mod.h @@ -9,28 +9,30 @@ CAS_NAMESPACE -class Mod : public Expression { +class Mod : public Expr { public: - explicit Mod(Expression* dividend, Expression* divisor); + explicit Mod(ExprPtr dividend, ExprPtr divisor); Mod() = delete; - ~Mod() override; + ~Mod() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; - Mod* clone() override; - Expression* simplified() override; + bool _equals(ExprPtr expression) override; + ExprPtr clone() override; + ExprPtr simplified() override; std::string latex() override; std::wstring stringify() override; std::string text() override; std::string explicitText() override; - Expression* getDividend() const { return dividend; } - Expression* getDivisor() const { return divisor; } + ExprPtr getDividend() const { return dividend; } + ExprPtr getDivisor() const { return divisor; } + + static ModPtr from(ExprPtr dividend, ExprPtr divisor) { return std::make_shared(dividend, divisor); } private: - Expression* dividend; - Expression* divisor; + ExprPtr dividend; + ExprPtr divisor; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/NaryExpression.h b/cas/include/cas/node/NaryExpression.h index fa0f301..678c276 100644 --- a/cas/include/cas/node/NaryExpression.h +++ b/cas/include/cas/node/NaryExpression.h @@ -10,13 +10,13 @@ CAS_NAMESPACE -class NaryExpression : public Expression { +class NaryExpression : public Expr { public: NaryExpression() = delete; - ~NaryExpression() override; + ~NaryExpression() override = default; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; std::string latex() override; @@ -26,7 +26,7 @@ class NaryExpression : public Expression { std::string explicitText() override; - std::vector getExpressions() const { return {expressions}; } + std::vector getExpressions() const { return {expressions}; } template bool all(F&& f) const; @@ -38,10 +38,10 @@ class NaryExpression : public Expression { void forEach(F&& f) const; protected: - explicit NaryExpression(const ExpressionProperties& props, std::vector expressions); + explicit NaryExpression(const ExpressionProperties& props, std::vector expressions); protected: - std::vector expressions; + std::vector expressions; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Negate.h b/cas/include/cas/node/Negate.h index f39b2b8..ed8dbdc 100644 --- a/cas/include/cas/node/Negate.h +++ b/cas/include/cas/node/Negate.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Negate : public UnaryExpression { public: - explicit Negate(Expression* expression); + explicit Negate(ExprPtr expression); Negate() = delete; @@ -19,13 +19,13 @@ class Negate : public UnaryExpression { double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Negate* clone() override; + ExprPtr clone() override; - Negate* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -35,6 +35,8 @@ class Negate : public UnaryExpression { std::string explicitText() override; + static NegatePtr from(ExprPtr expression) { return std::make_shared(expression); } + protected: bool needsParentheses(); }; diff --git a/cas/include/cas/node/Operator.h b/cas/include/cas/node/Operator.h index 85e85ef..e92f4e9 100644 --- a/cas/include/cas/node/Operator.h +++ b/cas/include/cas/node/Operator.h @@ -10,17 +10,17 @@ CAS_NAMESPACE -class Operator : public Expression { +class Operator : public Expr { public: - explicit Operator(const ExpressionProperties& props, double neutral, char symbol, std::vector expressions); + explicit Operator(const ExpressionProperties& props, double neutral, char symbol, std::vector expressions); Operator() = delete; - ~Operator() override; + ~Operator() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; std::string text() override; @@ -28,18 +28,18 @@ class Operator : public Expression { char getSymbol() const { return symbol; } - std::vector getExpressions() const { return {expressions}; } + std::vector getExpressions() const { return {expressions}; } size_t getExpressionsSize() const { return expressions.size(); } protected: virtual double operate(double a, double b) = 0; - virtual bool needsParentheses(Expression* expression) = 0; + virtual bool needsParentheses(ExprPtr expression) = 0; protected: const double neutral; const char symbol; - std::vector expressions; + std::vector expressions; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Power.h b/cas/include/cas/node/Power.h index 3a766ee..5819b36 100644 --- a/cas/include/cas/node/Power.h +++ b/cas/include/cas/node/Power.h @@ -9,25 +9,25 @@ CAS_NAMESPACE -class Power : public Expression { +class Power : public Expr { public: - explicit Power(Expression* base, Expression* exponent); + explicit Power(ExprPtr base, ExprPtr exponent); - explicit Power(Expression* base, double exponent); + explicit Power(ExprPtr base, double exponent); Power() = delete; - ~Power() override; + ~Power() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Power* clone() override; + ExprPtr clone() override; - Expression* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -37,20 +37,22 @@ class Power : public Expression { std::string explicitText() override; - Expression* getBase() const { return base; } + ExprPtr getBase() const { return base; } - Expression* getExponent() const { return exponent; } + ExprPtr getExponent() const { return exponent; } + + static PowerPtr from(ExprPtr base, ExprPtr exponent) { return std::make_shared(base, exponent); } protected: - explicit Power(const ExpressionProperties& props, Expression* base, Expression* exponent); + explicit Power(const ExpressionProperties& props, ExprPtr base, ExprPtr exponent); bool baseNeedsParentheses(); bool exponentNeedsParentheses(); protected: - Expression* base; - Expression* exponent; + ExprPtr base; + ExprPtr exponent; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Prod.h b/cas/include/cas/node/Prod.h new file mode 100644 index 0000000..b4a642e --- /dev/null +++ b/cas/include/cas/node/Prod.h @@ -0,0 +1,40 @@ +// +// Created by Abd-El-Aziz Zayed on 2022-09-01. +// + +#ifndef CAS_PRODUCT_H +#define CAS_PRODUCT_H + +#include "Operator.h" + +CAS_NAMESPACE + +class Prod : public Operator { +public: + explicit Prod(const std::vector& expressions); + + Prod() = delete; + + ~Prod() override = default; + + ExprPtr clone() override; + + ExprPtr _derivative(char var) override; + + ExprPtr simplified() override; + + std::string latex() override; + + std::wstring stringify() override; + + static ProdPtr from(const std::vector& expressions) { return std::make_shared(expressions); } + +protected: + double operate(double a, double b) override { return a * b; }; + + bool needsParentheses(ExprPtr expression) override; +}; + +CAS_NAMESPACE_END + +#endif//CAS_PRODUCT_H diff --git a/cas/include/cas/node/Product.h b/cas/include/cas/node/Product.h deleted file mode 100644 index 0ac46f9..0000000 --- a/cas/include/cas/node/Product.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// Created by Abd-El-Aziz Zayed on 2022-09-01. -// - -#ifndef CAS_PRODUCT_H -#define CAS_PRODUCT_H - -#include "Operator.h" - -CAS_NAMESPACE - -class Product : public Operator { -public: - explicit Product(const std::vector& expressions); - - Product() = delete; - - ~Product() override = default; - - Product* clone() override; - - Expression* _derivative(char var) override; - - Expression* simplified() override; - - std::string latex() override; - - std::wstring stringify() override; - -protected: - double operate(double a, double b) override { return a * b; }; - - bool needsParentheses(Expression* expression) override; -}; - -CAS_NAMESPACE_END - -#endif//CAS_PRODUCT_H diff --git a/cas/include/cas/node/Root.h b/cas/include/cas/node/Root.h index 46153b3..37714ae 100644 --- a/cas/include/cas/node/Root.h +++ b/cas/include/cas/node/Root.h @@ -11,22 +11,25 @@ CAS_NAMESPACE class Root : public Power { public: - explicit Root(const ExpressionProperties& props, Expression* base, Expression* root); - explicit Root(Expression* base, Expression* root); - explicit Root(Expression* base, double root); + explicit Root(const ExpressionProperties& props, ExprPtr base, ExprPtr root); + explicit Root(ExprPtr base, ExprPtr root); + explicit Root(ExprPtr base, double root); Root() = delete; ~Root() override = default; double evaluate(const VariableMap& variables) override; - Root* clone() override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr simplified() override; std::string latex() override; std::wstring stringify() override; std::string text() override; - Expression* getRoot() const { return getExponent(); } + ExprPtr getRoot() const { return getExponent(); } + + static RootPtr from(ExprPtr base, ExprPtr root) { return std::make_shared(base, root); } + static RootPtr from(ExprPtr base, double root) { return std::make_shared(base, root); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Round.h b/cas/include/cas/node/Round.h index f624b94..7d8fc5f 100644 --- a/cas/include/cas/node/Round.h +++ b/cas/include/cas/node/Round.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Round : public BracketExpression { public: - explicit Round(Expression* argument); + explicit Round(ExprPtr argument); Round() = delete; @@ -19,9 +19,11 @@ class Round : public BracketExpression { double evaluate(const VariableMap& variables) override; - Round* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; + + static RoundPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Sign.h b/cas/include/cas/node/Sign.h index 36ddc9a..09af4dd 100644 --- a/cas/include/cas/node/Sign.h +++ b/cas/include/cas/node/Sign.h @@ -11,20 +11,22 @@ CAS_NAMESPACE class Sign : public UnaryExpression { public: - explicit Sign(Expression* argument); + explicit Sign(ExprPtr argument); Sign() = delete; ~Sign() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Sign* clone() override; + ExprPtr clone() override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; + static SignPtr from(ExprPtr argument) { return std::make_shared(argument); } + private: bool needsParentheses(); }; diff --git a/cas/include/cas/node/Sqrt.h b/cas/include/cas/node/Sqrt.h index b7a60a0..c9b5ccf 100644 --- a/cas/include/cas/node/Sqrt.h +++ b/cas/include/cas/node/Sqrt.h @@ -11,19 +11,21 @@ CAS_NAMESPACE class Sqrt : public Root { public: - explicit Sqrt(Expression* base); + explicit Sqrt(ExprPtr base); Sqrt() = delete; ~Sqrt() override = default; double evaluate(const VariableMap& variables) override; - Sqrt* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; std::string latex() override; std::wstring stringify() override; std::string text() override; std::string explicitText() override; + + static SqrtPtr from(ExprPtr base) { return std::make_shared(base); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Sum.h b/cas/include/cas/node/Sum.h index d9937c5..21911ea 100644 --- a/cas/include/cas/node/Sum.h +++ b/cas/include/cas/node/Sum.h @@ -11,26 +11,28 @@ CAS_NAMESPACE class Sum : public Operator { public: - explicit Sum(const std::vector& expressions); + explicit Sum(const std::vector& expressions); Sum() = delete; ~Sum() override = default; - Sum* clone() override; + ExprPtr clone() override; - Sum* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Expression* simplified() override; + ExprPtr simplified() override; std::string latex() override; std::wstring stringify() override; + static SumPtr from(const std::vector& expressions) { return std::make_shared(expressions); } + protected: double operate(double a, double b) override { return a + b; }; - bool needsParentheses(Expression*) override { return false; }; + bool needsParentheses(ExprPtr) override { return false; }; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/UnaryExpression.h b/cas/include/cas/node/UnaryExpression.h index e45dc35..277398d 100644 --- a/cas/include/cas/node/UnaryExpression.h +++ b/cas/include/cas/node/UnaryExpression.h @@ -9,15 +9,15 @@ CAS_NAMESPACE -class UnaryExpression : public Expression { +class UnaryExpression : public Expr { public: UnaryExpression() = delete; - ~UnaryExpression() override; + ~UnaryExpression() override = default; - Expression* derivative(char var) override; + ExprPtr derivative(char var) override; - Expression* getArgument() const { return argument; } + ExprPtr getArgument() const { return argument; } std::string latex() override; @@ -28,10 +28,10 @@ class UnaryExpression : public Expression { std::string explicitText() override; protected: - explicit UnaryExpression(const ExpressionProperties& properties, Expression* argument); + explicit UnaryExpression(const ExpressionProperties& properties, ExprPtr argument); protected: - Expression* argument; + ExprPtr argument; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Var.h b/cas/include/cas/node/Var.h index 5e068d1..b5741cc 100644 --- a/cas/include/cas/node/Var.h +++ b/cas/include/cas/node/Var.h @@ -9,22 +9,21 @@ CAS_NAMESPACE -class Var : public Expression { +class Var : public Expr { public: explicit Var(char variable); - explicit Var() : Var('x') {} ~Var() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; - Var* clone() override; + ExprPtr clone() override; - Expression* _derivative(char var) override; + ExprPtr _derivative(char var) override; - Var* simplified() override; + ExprPtr simplified() override; std::string latex() override; @@ -34,24 +33,26 @@ class Var : public Expression { char getSymbol() const { return symbol; } - static Var* var(char variable) { return new Var(variable); } + static VarPtr var(char variable) { return Var::from(variable); } - static Var* a() { return var('a'); } - static Var* b() { return var('b'); } - static Var* c() { return var('c'); } + static VarPtr a() { return var('a'); } + static VarPtr b() { return var('b'); } + static VarPtr c() { return var('c'); } - static Var* i() { return var('i'); } - static Var* j() { return var('j'); } - static Var* k() { return var('k'); } + static VarPtr i() { return var('i'); } + static VarPtr j() { return var('j'); } + static VarPtr k() { return var('k'); } - static Var* x() { return var('x'); } - static Var* y() { return var('y'); } - static Var* z() { return var('z'); } - static Var* w() { return var('w'); } + static VarPtr x() { return var('x'); } + static VarPtr y() { return var('y'); } + static VarPtr z() { return var('z'); } + static VarPtr w() { return var('w'); } - static Var* s() { return var('s'); } - static Var* t() { return var('t'); } - static Var* u() { return var('u'); } + static VarPtr s() { return var('s'); } + static VarPtr t() { return var('t'); } + static VarPtr u() { return var('u'); } + + static VarPtr from(char variable) { return std::make_shared(variable); } private: const char symbol; diff --git a/cas/include/cas/node/trig/ArcCos.h b/cas/include/cas/node/trig/ArcCos.h index b4ccfeb..aae6f77 100644 --- a/cas/include/cas/node/trig/ArcCos.h +++ b/cas/include/cas/node/trig/ArcCos.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class ArcCos : public InverseTrigExpression { public: - explicit ArcCos(Expression* argument); + explicit ArcCos(ExprPtr argument); ArcCos() = delete; ~ArcCos() override = default; double evaluate(const VariableMap& variables) override; - ArcCos* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static ArcCosPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcCot.h b/cas/include/cas/node/trig/ArcCot.h index 46f6663..e35e525 100644 --- a/cas/include/cas/node/trig/ArcCot.h +++ b/cas/include/cas/node/trig/ArcCot.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class ArcCot : public InverseTrigExpression { public: - explicit ArcCot(Expression* argument); + explicit ArcCot(ExprPtr argument); ArcCot() = delete; ~ArcCot() override = default; double evaluate(const VariableMap& variables) override; - ArcCot* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static ArcCotPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcCsc.h b/cas/include/cas/node/trig/ArcCsc.h index ee9ee67..c82562f 100644 --- a/cas/include/cas/node/trig/ArcCsc.h +++ b/cas/include/cas/node/trig/ArcCsc.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class ArcCsc : public InverseTrigExpression { public: - explicit ArcCsc(Expression* argument); + explicit ArcCsc(ExprPtr argument); ArcCsc() = delete; ~ArcCsc() override = default; double evaluate(const VariableMap& variables) override; - ArcCsc* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static ArcCscPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcSec.h b/cas/include/cas/node/trig/ArcSec.h index 0087f5a..7e85a56 100644 --- a/cas/include/cas/node/trig/ArcSec.h +++ b/cas/include/cas/node/trig/ArcSec.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class ArcSec : public InverseTrigExpression { public: - explicit ArcSec(Expression* argument); + explicit ArcSec(ExprPtr argument); ArcSec() = delete; ~ArcSec() override = default; double evaluate(const VariableMap& variables) override; - ArcSec* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static ArcSecPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcSin.h b/cas/include/cas/node/trig/ArcSin.h index d4188b6..4569f16 100644 --- a/cas/include/cas/node/trig/ArcSin.h +++ b/cas/include/cas/node/trig/ArcSin.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class ArcSin : public InverseTrigExpression { public: - explicit ArcSin(Expression* argument); + explicit ArcSin(ExprPtr argument); ArcSin() = delete; ~ArcSin() override = default; double evaluate(const VariableMap& variables) override; - ArcSin* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static ArcSinPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcTan.h b/cas/include/cas/node/trig/ArcTan.h index 82c3852..61a058d 100644 --- a/cas/include/cas/node/trig/ArcTan.h +++ b/cas/include/cas/node/trig/ArcTan.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class ArcTan : public InverseTrigExpression { public: - explicit ArcTan(Expression* argument); + explicit ArcTan(ExprPtr argument); ArcTan() = delete; ~ArcTan() override = default; double evaluate(const VariableMap& variables) override; - ArcTan* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static ArcTanPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Cos.h b/cas/include/cas/node/trig/Cos.h index eb92750..62da892 100644 --- a/cas/include/cas/node/trig/Cos.h +++ b/cas/include/cas/node/trig/Cos.h @@ -12,14 +12,16 @@ CAS_NAMESPACE class Cos : public TrigExpression { public: - explicit Cos(Expression* argument); + explicit Cos(ExprPtr argument); Cos() = delete; ~Cos() override = default; double evaluate(const VariableMap& variables) override; - Cos* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static CosPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Cot.h b/cas/include/cas/node/trig/Cot.h index 735311a..74fcc46 100644 --- a/cas/include/cas/node/trig/Cot.h +++ b/cas/include/cas/node/trig/Cot.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class Cot : public TrigExpression { public: - explicit Cot(Expression* argument); + explicit Cot(ExprPtr argument); Cot() = delete; ~Cot() override = default; double evaluate(const VariableMap& variables) override; - Cot* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static CotPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Csc.h b/cas/include/cas/node/trig/Csc.h index 098ba61..6fb9a73 100644 --- a/cas/include/cas/node/trig/Csc.h +++ b/cas/include/cas/node/trig/Csc.h @@ -11,14 +11,16 @@ CAS_NAMESPACE class Csc : public TrigExpression { public: - explicit Csc(Expression* argument); + explicit Csc(ExprPtr argument); Csc() = delete; ~Csc() override = default; double evaluate(const VariableMap& variables) override; - Csc* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static CscPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/InverseTrigExpression.h b/cas/include/cas/node/trig/InverseTrigExpression.h index 7e0d623..066de80 100644 --- a/cas/include/cas/node/trig/InverseTrigExpression.h +++ b/cas/include/cas/node/trig/InverseTrigExpression.h @@ -17,7 +17,7 @@ class InverseTrigExpression : public TrigExpression { std::string latex() override; protected: - explicit InverseTrigExpression(const ExpressionProperties& props, Expression* argument); + explicit InverseTrigExpression(const ExpressionProperties& props, ExprPtr argument); }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Sec.h b/cas/include/cas/node/trig/Sec.h index 95055dc..1405eb8 100644 --- a/cas/include/cas/node/trig/Sec.h +++ b/cas/include/cas/node/trig/Sec.h @@ -12,14 +12,16 @@ CAS_NAMESPACE class Sec : public TrigExpression { public: - explicit Sec(Expression* argument); + explicit Sec(ExprPtr argument); Sec() = delete; ~Sec() override = default; double evaluate(const VariableMap& variables) override; - Sec* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static SecPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Sin.h b/cas/include/cas/node/trig/Sin.h index ca01000..1f8ccf0 100644 --- a/cas/include/cas/node/trig/Sin.h +++ b/cas/include/cas/node/trig/Sin.h @@ -12,14 +12,16 @@ CAS_NAMESPACE class Sin : public TrigExpression { public: - explicit Sin(Expression* argument); + explicit Sin(ExprPtr argument); Sin() = delete; ~Sin() override = default; double evaluate(const VariableMap& variables) override; - Sin* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static SinPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Tan.h b/cas/include/cas/node/trig/Tan.h index ce6403d..d4b597a 100644 --- a/cas/include/cas/node/trig/Tan.h +++ b/cas/include/cas/node/trig/Tan.h @@ -12,14 +12,16 @@ CAS_NAMESPACE class Tan : public TrigExpression { public: - explicit Tan(Expression* argument); + explicit Tan(ExprPtr argument); Tan() = delete; ~Tan() override = default; double evaluate(const VariableMap& variables) override; - Tan* clone() override; - Expression* _derivative(char variable) override; - Expression* simplified() override; + ExprPtr clone() override; + ExprPtr _derivative(char variable) override; + ExprPtr simplified() override; + + static TanPtr from(ExprPtr argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/TrigExpression.h b/cas/include/cas/node/trig/TrigExpression.h index 60310fe..02b401f 100644 --- a/cas/include/cas/node/trig/TrigExpression.h +++ b/cas/include/cas/node/trig/TrigExpression.h @@ -13,9 +13,9 @@ CAS_NAMESPACE struct UnitCircleCoordinate { double angle; - Expression* cos; - Expression* sin; - Expression* tan; + ExprPtr cos; + ExprPtr sin; + ExprPtr tan; }; class TrigExpression : public UnaryExpression { @@ -23,7 +23,7 @@ class TrigExpression : public UnaryExpression { TrigExpression() = delete; ~TrigExpression() override = default; - bool _equals(Expression* expression) override; + bool _equals(ExprPtr expression) override; std::string latex() override; std::wstring stringify() override; @@ -32,7 +32,7 @@ class TrigExpression : public UnaryExpression { static const std::unordered_map unitCircle; protected: - explicit TrigExpression(const ExpressionProperties& props, Expression* argument); + explicit TrigExpression(const ExpressionProperties& props, ExprPtr argument); bool needsParentheses(); }; diff --git a/cas/include/cas/plot/Function.h b/cas/include/cas/plot/Function.h index 83d4f7e..d54c612 100644 --- a/cas/include/cas/plot/Function.h +++ b/cas/include/cas/plot/Function.h @@ -9,16 +9,16 @@ CAS_NAMESPACE -class Function : public IMath, public IRepresentableMath { +class Function : public IMath, public IRepresentableMath { public: explicit Function(std::string strFunction, const std::string& name = "z", bool simplify = true); - virtual ~Function(); + ~Function() = default; double evaluate(const VariableMap& vars) override; Function* derivative(char var) override; Function* simplifiedDerivative(char var); Function* simplified() override; - bool isEquivalent(IMath* expression) override; + bool isEquivalent(Function* expression) override; std::string latex() override; std::wstring stringify() override; @@ -29,18 +29,18 @@ class Function : public IMath, public IRepresentableMath { size_t getUid() const; const std::string& getStrExpr() const; - Expression* getExpr() const; + ExprPtr getExpr() const; const std::string& getName() const; const std::string& getFilename() const; const VarSet& getVariables() const; protected: - explicit Function(const std::string& strFunction, Expression* expr, const VarSet& variables, const std::string& name = "z"); + explicit Function(const std::string& strFunction, ExprPtr expr, const VarSet& variables, const std::string& name = "z"); private: const size_t uid; const std::string strExpr; - Expression* expr; + ExprPtr expr; const std::string name; const std::string filename; VarSet variables; diff --git a/cas/include/cas/plot/Surface.h b/cas/include/cas/plot/Surface.h deleted file mode 100644 index b2a55aa..0000000 --- a/cas/include/cas/plot/Surface.h +++ /dev/null @@ -1,75 +0,0 @@ -// -// Created by Abd-El-Aziz Zayed on 2022-10-25. -// - -#ifndef CAS_SURFACE_H -#define CAS_SURFACE_H - -#include "Function.h" - -template// V for vertex -struct Plot { - bool visible = true; - - static const uint32_t RESOLUTION = 100; - static const uint32_t SIZE = RESOLUTION + 1; - - static const uint32_t indexCount = RESOLUTION * RESOLUTION * 6; - static const uint32_t indicesSize = indexCount * sizeof(uint32_t); - static uint32_t* indices; - - static const uint32_t vertexCount = SIZE * SIZE; - static const uint32_t verticesSize = vertexCount * sizeof(V); - V* vertices = new V[vertexCount]; - - static void generateIndices() { - if (indices != nullptr) { - return; - } - - indices = new uint32_t[indexCount]; - uint32_t offset = 0; - for (uint32_t y = 0; y < RESOLUTION; y++) { - for (uint32_t x = 0; x < RESOLUTION; x++) { - uint32_t a = y * SIZE + x; - uint32_t b = a + 1; - uint32_t c = (y + 1) * SIZE + x; - uint32_t d = c + 1; - - indices[offset++] = a; - indices[offset++] = b; - indices[offset++] = c; - - indices[offset++] = b; - indices[offset++] = c; - indices[offset++] = d; - } - } - } - - static void cleanup() { - if (indices != nullptr) { - delete[] indices; - indices = nullptr; - } - } -}; - -CAS_NAMESPACE - -template// F: F(xyz, rgba) -> T -class Surface : public Function { - explicit Surface(std::string strFunction); - virtual ~Surface() override; - - void update(); - -private: - Plot fPlot; - Plot xDerivativePlot; - Plot yDerivativePlot; -}; - -CAS_NAMESPACE_END - -#endif//CAS_SURFACE_H diff --git a/cas/src/CMakeLists.txt b/cas/src/CMakeLists.txt index d21f848..e61d9ae 100644 --- a/cas/src/CMakeLists.txt +++ b/cas/src/CMakeLists.txt @@ -29,7 +29,7 @@ set(CAS_SRC_HEADERS ../include/cas/node/Var.h ../include/cas/node/Operator.h ../include/cas/node/Sum.h - ../include/cas/node/Product.h + ../include/cas/node/Prod.h ../include/cas/node/Divide.h ../include/cas/node/Power.h ../include/cas/node/Negate.h diff --git a/cas/src/core/data/ExpressionParser.cpp b/cas/src/core/data/ExpressionParser.cpp index a8ae2fd..c36353e 100644 --- a/cas/src/core/data/ExpressionParser.cpp +++ b/cas/src/core/data/ExpressionParser.cpp @@ -15,7 +15,7 @@ #include "cas/node/Min.h" #include "cas/node/Mod.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Round.h" #include "cas/node/Sign.h" #include "cas/node/Sqrt.h" @@ -114,7 +114,7 @@ std::string ExpressionParser::pop(std::list& list) { return top; } -Expression* ExpressionParser::parse(const std::string& expression, VarSet& variables) { +ExprPtr ExpressionParser::parse(const std::string& expression, VarSet& variables) { std::string expr = expression; removeUnnecessarySurroundingBrackets(expr); @@ -139,13 +139,13 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia } } - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) expressions.push_back(parse(part, variables)); } - return new Sum(expressions); + return Sum::from(expressions); } else if (contains(cut, "-")) { std::vector parts = split(cut, "-"); for (std::string& part: parts) { @@ -155,20 +155,20 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia } if (parts.size() == 2 && parts[0].empty()) { - return new Negate(parse(parts[1], variables)); + return Negate::from(parse(parts[1], variables)); } bool first = true; - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) { - Expression* neg = parse(part, variables); - expressions.push_back(first ? neg : new Negate(neg)); + ExprPtr neg = parse(part, variables); + expressions.push_back(first ? neg : neg->negate()); } first = false; } - return new Sum(expressions); + return Sum::from(expressions); } else if (contains(cut, "*")) { std::vector parts = split(cut, "*"); for (std::string& part: parts) { @@ -177,13 +177,13 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia } } - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) expressions.push_back(parse(part, variables)); } - return new Product(expressions); + return Prod::from(expressions); } else if (contains(cut, "/")) { std::vector parts = splitFirst(cut, "/"); @@ -194,7 +194,7 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia replaceOnce(parts[1], "()", "(" + pop(remove) + ")"); } - return new Divide(parse(parts[0], variables), parse(parts[1], variables)); + return Divide::from(parse(parts[0], variables), parse(parts[1], variables)); } else if (contains(cut, "^")) { std::vector parts = splitFirst(cut, "^"); @@ -206,42 +206,42 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia } std::string& base = parts[0]; - Expression* power = parse(parts[1], variables); + ExprPtr power = parse(parts[1], variables); if (base == "e") { - return new Exp(power); + return Exp::from(power); } - return new Power(parse(base, variables), power); + return Power::from(parse(base, variables), power); } else if (cut == "-()") { - return new Negate(parse(pop(remove), variables)); + return Negate::from(parse(pop(remove), variables)); } else if (cut == "sin()") { - return new Sin(parse(pop(remove), variables)); + return Sin::from(parse(pop(remove), variables)); } else if (cut == "cos()") { - return new Cos(parse(pop(remove), variables)); + return Cos::from(parse(pop(remove), variables)); } else if (cut == "tan()") { - return new Tan(parse(pop(remove), variables)); + return Tan::from(parse(pop(remove), variables)); } else if (cut == "cot()") { - return new Cot(parse(pop(remove), variables)); + return Cot::from(parse(pop(remove), variables)); } else if (cut == "sec()") { - return new Sec(parse(pop(remove), variables)); + return Sec::from(parse(pop(remove), variables)); } else if (cut == "csc()") { - return new Csc(parse(pop(remove), variables)); + return Csc::from(parse(pop(remove), variables)); } else if (cut == "asin()" || cut == "arcsin()") { - return new ArcSin(parse(pop(remove), variables)); + return ArcSin::from(parse(pop(remove), variables)); } else if (cut == "acos()" || cut == "arccos()") { - return new ArcCos(parse(pop(remove), variables)); + return ArcCos::from(parse(pop(remove), variables)); } else if (cut == "atan()" || cut == "arctan()") { - return new ArcTan(parse(pop(remove), variables)); + return ArcTan::from(parse(pop(remove), variables)); } else if (cut == "acot()" || cut == "arccot()") { - return new ArcCot(parse(pop(remove), variables)); + return ArcCot::from(parse(pop(remove), variables)); } else if (cut == "asec()" || cut == "arcsec()") { - return new ArcSec(parse(pop(remove), variables)); + return ArcSec::from(parse(pop(remove), variables)); } else if (cut == "acsc()" || cut == "arccsc()") { - return new ArcCsc(parse(pop(remove), variables)); + return ArcCsc::from(parse(pop(remove), variables)); } else if (cut == "ln()") { - return new Ln(parse(pop(remove), variables)); + return Ln::from(parse(pop(remove), variables)); } else if (cut == "log()") { - return new Log(parse(pop(remove), variables)); + return Log::from(parse(pop(remove), variables)); } else if (cut.starts_with("log_")) { std::string log = cut.substr(4); std::vector parts = split(log, "_"); @@ -253,23 +253,23 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia replaceOnce(parts[1], "()", "(" + pop(remove) + ")"); } - return new Log(parse(parts[0], variables), parse(parts[1], variables)); + return Log::from(parse(parts[0], variables), parse(parts[1], variables)); } else if (cut == "sqrt()") { - return new Sqrt(parse(pop(remove), variables)); + return Sqrt::from(parse(pop(remove), variables)); } else if (cut == "cbrt()") { - return new Cbrt(parse(pop(remove), variables)); + return Cbrt::from(parse(pop(remove), variables)); } else if (cut == "abs()") { - return new Abs(parse(pop(remove), variables)); + return Abs::from(parse(pop(remove), variables)); } else if (cut == "exp()") { - return new Exp(parse(pop(remove), variables)); + return Exp::from(parse(pop(remove), variables)); } else if (cut == "floor()") { - return new Floor(parse(pop(remove), variables)); + return Floor::from(parse(pop(remove), variables)); } else if (cut == "ceil()") { - return new Ceil(parse(pop(remove), variables)); + return Ceil::from(parse(pop(remove), variables)); } else if (cut == "round()") { - return new Round(parse(pop(remove), variables)); + return Round::from(parse(pop(remove), variables)); } else if (cut == "sign()" || cut == "sgn()") { - return new Sign(parse(pop(remove), variables)); + return Sign::from(parse(pop(remove), variables)); } else if (cut == "mod()") { std::string mod = pop(remove); std::vector parts = split(mod, ","); @@ -278,29 +278,29 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia throw std::invalid_argument("Invalid number of arguments for mod in " + expression); } - return new Mod(parse(parts[0], variables), parse(parts[1], variables)); + return Mod::from(parse(parts[0], variables), parse(parts[1], variables)); } else if (cut == "max()") { std::string max = pop(remove); std::vector parts = split(max, ","); - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) expressions.push_back(parse(part, variables)); } - return new Max(expressions); + return Max::from(expressions); } else if (cut == "min()") { std::string max = pop(remove); std::vector parts = split(max, ","); - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) expressions.push_back(parse(part, variables)); } - return new Min(expressions); + return Min::from(expressions); } } else if (expr == "e") { return cas::Const::E(); @@ -311,117 +311,117 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia } else if (expr.length() == 1 && isalpha(expr[0])) { char c = expr[0]; variables.insert(c); - return new Var(c); + return Var::from(c); } else if (isNumber(expr)) { - return new Const(std::stod(expr)); + return Const::from(std::stod(expr)); } else if (contains(expr, "+")) { std::vector parts = split(expr, "+"); - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) expressions.push_back(parse(part, variables)); } - return new Sum(expressions); + return Sum::from(expressions); } else if (contains(expr, "-")) { std::vector parts = split(expr, "-"); if (parts.size() == 2 && parts[0].empty()) { - return new Negate(parse(parts[1], variables)); + return Negate::from(parse(parts[1], variables)); } bool first = true; - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) { - Expression* neg = parse(part, variables); - expressions.push_back(first ? neg : new Negate(neg)); + ExprPtr neg = parse(part, variables); + expressions.push_back(first ? neg : Negate::from(neg)); } first = false; } - return new Sum(expressions); + return Sum::from(expressions); } else if (contains(expr, "*")) { std::vector parts = split(expr, "*"); - std::vector expressions; + std::vector expressions; for (const std::string& part: parts) { if (!part.empty()) expressions.push_back(parse(part, variables)); } - return new Product(expressions); + return Prod::from(expressions); } else if (contains(expr, "/")) { std::vector parts = splitFirst(expr, "/"); - return new Divide(parse(parts[0], variables), parse(parts[1], variables)); + return Divide::from(parse(parts[0], variables), parse(parts[1], variables)); } else if (contains(expr, "^")) { std::vector parts = splitFirst(expr, "^"); std::string& base = parts[0]; - Expression* power = parse(parts[1], variables); + ExprPtr power = parse(parts[1], variables); if (base == "e") { - return new Exp(power); + return Exp::from(power); } - return new Power(parse(base, variables), power); + return Power::from(parse(base, variables), power); } else if (expr.starts_with("-")) { - return new Negate(parse(expr.substr(1), variables)); + return Negate::from(parse(expr.substr(1), variables)); } else if (expr.starts_with("ln")) { - return new Ln(parse(expr.substr(2), variables)); + return Ln::from(parse(expr.substr(2), variables)); } else if (expr.starts_with("sin")) { - return new Sin(parse(expr.substr(3), variables)); + return Sin::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("cos")) { - return new Cos(parse(expr.substr(3), variables)); + return Cos::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("tan")) { - return new Tan(parse(expr.substr(3), variables)); + return Tan::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("cot")) { - return new Cot(parse(expr.substr(3), variables)); + return Cot::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("csc")) { - return new Csc(parse(expr.substr(3), variables)); + return Csc::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("sec")) { - return new Sec(parse(expr.substr(3), variables)); + return Sec::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("asin")) { - return new ArcSin(parse(expr.substr(4), variables)); + return ArcSin::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("acos")) { - return new ArcCos(parse(expr.substr(4), variables)); + return ArcCos::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("atan")) { - return new ArcTan(parse(expr.substr(4), variables)); + return ArcTan::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("acot")) { - return new ArcCot(parse(expr.substr(4), variables)); + return ArcCot::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("acsc")) { - return new ArcCsc(parse(expr.substr(4), variables)); + return ArcCsc::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("asec")) { - return new ArcSec(parse(expr.substr(4), variables)); + return ArcSec::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("arcsin")) { - return new ArcSin(parse(expr.substr(6), variables)); + return ArcSin::from(parse(expr.substr(6), variables)); } else if (expr.starts_with("arccos")) { - return new ArcCos(parse(expr.substr(6), variables)); + return ArcCos::from(parse(expr.substr(6), variables)); } else if (expr.starts_with("arctan")) { - return new ArcTan(parse(expr.substr(6), variables)); + return ArcTan::from(parse(expr.substr(6), variables)); } else if (expr.starts_with("arccot")) { - return new ArcCot(parse(expr.substr(6), variables)); + return ArcCot::from(parse(expr.substr(6), variables)); } else if (expr.starts_with("arccsc")) { - return new ArcCsc(parse(expr.substr(6), variables)); + return ArcCsc::from(parse(expr.substr(6), variables)); } else if (expr.starts_with("arcsec")) { - return new ArcSec(parse(expr.substr(6), variables)); + return ArcSec::from(parse(expr.substr(6), variables)); } else if (expr.starts_with("abs")) { - return new Abs(parse(expr.substr(3), variables)); + return Abs::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("exp")) { - return new Exp(parse(expr.substr(3), variables)); + return Exp::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("sqrt")) { - return new Sqrt(parse(expr.substr(4), variables)); + return Sqrt::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("cbrt")) { - return new Cbrt(parse(expr.substr(4), variables)); + return Cbrt::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("ceil")) { - return new Ceil(parse(expr.substr(4), variables)); + return Ceil::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("floor")) { - return new Floor(parse(expr.substr(5), variables)); + return Floor::from(parse(expr.substr(5), variables)); } else if (expr.starts_with("round")) { - return new Round(parse(expr.substr(5), variables)); + return Round::from(parse(expr.substr(5), variables)); } else if (expr.starts_with("sign")) { - return new Sign(parse(expr.substr(4), variables)); + return Sign::from(parse(expr.substr(4), variables)); } else if (expr.starts_with("sgn")) { - return new Sign(parse(expr.substr(3), variables)); + return Sign::from(parse(expr.substr(3), variables)); } else if (expr.starts_with("log_")) { std::string log = expr.substr(4); std::vector parts = split(log, "_"); @@ -429,12 +429,12 @@ Expression* ExpressionParser::parse(const std::string& expression, VarSet& varia if (parts.size() != 2) throw std::invalid_argument("Invalid expression " + expression); - return new Log(parse(parts[0], variables), parse(parts[1], variables)); + return Log::from(parse(parts[0], variables), parse(parts[1], variables)); } else if (expr.starts_with("log")) { if (expr.length() == 4) - return new Log(parse(expr.substr(3), variables)); + return Log::from(parse(expr.substr(3), variables)); if (expr.length() == 5) - return new Log(parse(std::string(1, expr[3]), variables), parse(std::string(1, expr[4]), variables)); + return Log::from(parse(std::string(1, expr[3]), variables), parse(std::string(1, expr[4]), variables)); throw std::invalid_argument("Invalid expression " + expression); } diff --git a/cas/src/core/data/ExpressionProperties.cpp b/cas/src/core/data/ExpressionProperties.cpp index 4c8df1b..b7a4f4f 100644 --- a/cas/src/core/data/ExpressionProperties.cpp +++ b/cas/src/core/data/ExpressionProperties.cpp @@ -7,7 +7,7 @@ CAS_NAMESPACE ExpressionProperties::ExpressionProperties(ExpressionType type, std::string name, std::string shortName) - : order(uint16_t(type)), type(type), name(std::move(name)), shortName(std::move(shortName)) {} + : order(static_cast(type)), type(type), name(std::move(name)), shortName(std::move(shortName)) {} bool ExpressionProperties::operator==(const ExpressionProperties& other) const { return type == other.type && order == other.order && name == other.name && shortName == other.shortName; diff --git a/cas/src/core/node/Abs.cpp b/cas/src/core/node/Abs.cpp index 8d40c13..34953d9 100644 --- a/cas/src/core/node/Abs.cpp +++ b/cas/src/core/node/Abs.cpp @@ -9,23 +9,23 @@ CAS_NAMESPACE -Abs::Abs(Expression* argument) +Abs::Abs(ExprPtr argument) : BracketExpression({ExpressionType::ABSOLUTE_VALUE, "absolute_value", "abs"}, argument, L"|", L"|", "\\left|", "\\right|") {} double Abs::evaluate(const VariableMap& variables) { return std::abs(argument->evaluate(variables)); } -Abs* Abs::clone() { - return new Abs(argument->clone()); +ExprPtr Abs::clone() { + return std::make_shared(argument->clone()); } -Expression* Abs::simplified() { +ExprPtr Abs::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { - return Const::n(Expression::evaluate()); + return Const::n(Expr::evaluate()); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->abs(); } if (argument->isOfType(ExpressionType::ABSOLUTE_VALUE)) { diff --git a/cas/src/core/node/BracketExpression.cpp b/cas/src/core/node/BracketExpression.cpp index 2b011d2..d15be58 100644 --- a/cas/src/core/node/BracketExpression.cpp +++ b/cas/src/core/node/BracketExpression.cpp @@ -8,19 +8,19 @@ CAS_NAMESPACE -BracketExpression::BracketExpression(const ExpressionProperties& properties, Expression* argument, +BracketExpression::BracketExpression(const ExpressionProperties& properties, ExprPtr argument, const wchar_t* openBracket, const wchar_t* closeBracket, const char* openBracketLatex, const char* closeBracketLatex) : UnaryExpression(properties, argument), openBracket(openBracket), closeBracket(closeBracket), openBracketLatex(openBracketLatex), closeBracketLatex(closeBracketLatex) {} -bool BracketExpression::_equals(Expression* other) { - auto* otherBracketFunction = dynamic_cast(other); +bool BracketExpression::_equals(ExprPtr other) { + auto* otherBracketFunction = dynamic_cast(other.get()); return argument->equals(otherBracketFunction->argument); } -Expression* BracketExpression::derivative(char) { +ExprPtr BracketExpression::derivative(char) { throw std::runtime_error("The " + properties.getName() + "::derivative() operation is not supported"); } diff --git a/cas/src/core/node/Cbrt.cpp b/cas/src/core/node/Cbrt.cpp index fe49bd6..9e3fd84 100644 --- a/cas/src/core/node/Cbrt.cpp +++ b/cas/src/core/node/Cbrt.cpp @@ -5,27 +5,27 @@ #include "cas/node/Cbrt.h" #include "cas/node/Const.h" #include "cas/node/Divide.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/util/StringUtils.h" #include #include CAS_NAMESPACE -Cbrt::Cbrt(Expression* base) - : Root({ExpressionType::CUBE_ROOT, "cube_root", "cbrt"}, base, new Const(3)) {} +Cbrt::Cbrt(ExprPtr base) + : Root({ExpressionType::CUBE_ROOT, "cube_root", "cbrt"}, base, Const::n(3)) {} double Cbrt::evaluate(const VariableMap& variables) { return std::cbrt(base->evaluate(variables)); } -Cbrt* Cbrt::clone() { - return new Cbrt(base->clone()); +ExprPtr Cbrt::clone() { + return std::make_shared(base->clone()); } -Expression* Cbrt::_derivative(char var) { +ExprPtr Cbrt::_derivative(char var) { if (base->isOfType(ExpressionType::CONSTANT)) { - return new Const(0); + return Const::zero(); } return base->derivative(var) @@ -35,15 +35,15 @@ Expression* Cbrt::_derivative(char var) { ->cbrt())); } -Expression* Cbrt::simplified() { +ExprPtr Cbrt::simplified() { if (base->isOfType(ExpressionType::CONSTANT)) { - double cbrt = Expression::evaluate(); + double cbrt = Expr::evaluate(); if (isWholeNumber(cbrt)) - return new Const(cbrt); + return Const::n(cbrt); return clone(); } if (base->isOfType(ExpressionType::POWER)) { - auto* power = dynamic_cast(base); + auto* power = dynamic_cast(base.get()); if (power->getExponent()->isOfType(ExpressionType::CONSTANT)) { double exponent = power->getExponent()->evaluate(); if (exponent == 3) diff --git a/cas/src/core/node/Ceil.cpp b/cas/src/core/node/Ceil.cpp index ebce60c..1a7ecbd 100644 --- a/cas/src/core/node/Ceil.cpp +++ b/cas/src/core/node/Ceil.cpp @@ -9,7 +9,7 @@ CAS_NAMESPACE -Ceil::Ceil(Expression* argument) +Ceil::Ceil(ExprPtr argument) : BracketExpression({ExpressionType::CEIL, "ceiling", "ceil"}, argument, L"\u2308", L"\u2309", "\\lceil", "\\rceil") {} @@ -18,19 +18,19 @@ double Ceil::evaluate(const VariableMap& variables) { return std::ceil(argument->evaluate(variables)); } -Ceil* Ceil::clone() { - return new Ceil(argument->clone()); +ExprPtr Ceil::clone() { + return std::make_shared(argument->clone()); } -Expression* Ceil::simplified() { +ExprPtr Ceil::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { - return Const::n(Expression::evaluate()); + return Const::n(Expr::evaluate()); } if (argument->isOfType(ExpressionType::CEIL)) { return argument->simplified(); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->floor()->negate(); } diff --git a/cas/src/core/node/Const.cpp b/cas/src/core/node/Const.cpp index 88d36a0..ec9c3b5 100644 --- a/cas/src/core/node/Const.cpp +++ b/cas/src/core/node/Const.cpp @@ -16,9 +16,9 @@ const char* Const::E_LATEX = "e"; const char* Const::PHI_LATEX = "\\varphi"; Const::Const(double value) - : Expression{{ExpressionType::CONSTANT, "constant", "const"}}, value{value} {} + : Expr{{ExpressionType::CONSTANT, "constant", "const"}}, value{value} {} -Const* Const::clone() { +ExprPtr Const::clone() { return Const::n(value); } @@ -26,15 +26,15 @@ double Const::evaluate(const VariableMap&) { return value; } -bool Const::_equals(Expression* expression) { +bool Const::_equals(ExprPtr expression) { return floatingsEqual(value, expression->evaluate()); } -Const* Const::_derivative(char) { +ExprPtr Const::_derivative(char) { return Const::zero(); } -Const* Const::simplified() { +ExprPtr Const::simplified() { return clone(); } diff --git a/cas/src/core/node/Divide.cpp b/cas/src/core/node/Divide.cpp index 6a0804c..99bb02f 100644 --- a/cas/src/core/node/Divide.cpp +++ b/cas/src/core/node/Divide.cpp @@ -6,41 +6,33 @@ #include "cas/node/Const.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" #include "fmt/printf.h" #include "fmt/xchar.h" CAS_NAMESPACE -Divide::Divide(Expression* dividend, Expression* divisor) - : Expression({ExpressionType::DIVIDE, "divide", "div"}), dividend(dividend), divisor(divisor) { - this->dividend->setParent(this); - this->divisor->setParent(this); -} - -Divide::~Divide() { - delete dividend; - delete divisor; - - dividend = nullptr; - divisor = nullptr; +Divide::Divide(ExprPtr dividend, ExprPtr divisor) + : Expr({ExpressionType::DIVIDE, "divide", "div"}), dividend(dividend), divisor(divisor) { + dividend->setParent(this); + divisor->setParent(this); } double Divide::evaluate(const VariableMap& variables) { return dividend->evaluate(variables) / divisor->evaluate(variables); } -bool Divide::_equals(Expression* expression) { - auto* divide = dynamic_cast(expression); +bool Divide::_equals(ExprPtr expression) { + auto* divide = dynamic_cast(expression.get()); return dividend->equals(divide->dividend) && divisor->equals(divide->divisor); } -Divide* Divide::clone() { - return new Divide(dividend->clone(), divisor->clone()); +ExprPtr Divide::clone() { + return Divide::from(dividend->clone(), divisor->clone()); } -Divide* Divide::_derivative(char var) { +ExprPtr Divide::_derivative(char var) { return dividend->derivative(var) ->multiply(divisor->clone())// f' * g ->subtract(dividend->clone() @@ -49,7 +41,7 @@ Divide* Divide::_derivative(char var) { ->power(2));// (f' * g - f * g') / g^2 } -Expression* Divide::simplified() { +ExprPtr Divide::simplified() { if (dividend->equals(divisor)) { return Const::one(); } @@ -58,20 +50,20 @@ Expression* Divide::simplified() { bool divisorIsDivide = divisor->isOfType(ExpressionType::DIVIDE); if (dividendIsDivide && !divisorIsDivide) {// (g/h)/f = g/(h*f) - auto* dDividend = dynamic_cast(dividend); + auto* dDividend = dynamic_cast(dividend.get()); return dDividend->dividend->simplified() ->divide(dDividend->divisor->simplified() ->multiply(divisor)); } if (!dividendIsDivide && divisorIsDivide) {// f/(g/h) = (f*h)/g - auto* divisorDivide = dynamic_cast(divisor); + auto* divisorDivide = dynamic_cast(divisor.get()); return dividend ->multiply(divisorDivide->divisor->simplified()) ->divide(divisorDivide->dividend->simplified()); } if (dividendIsDivide) {// (g/h)/(f/k) = (g*k)/(h*f) - auto* dividendDivide = dynamic_cast(dividend); - auto* divisorDivide = dynamic_cast(divisor); + auto* dividendDivide = dynamic_cast(dividend.get()); + auto* divisorDivide = dynamic_cast(divisor.get()); return dividendDivide->dividend->simplified() ->multiply(divisorDivide->divisor->simplified()) ->divide(dividendDivide->divisor->simplified() @@ -87,7 +79,7 @@ Expression* Divide::simplified() { double result = dividendValue / divisorValue; if (isWholeNumber(result)) { - return new Const(result); + return Const::n(result); } return Const::n(dividendValue)->divide(Const::n(divisorValue)); } diff --git a/cas/src/core/node/Exp.cpp b/cas/src/core/node/Exp.cpp index b34b800..da5de31 100644 --- a/cas/src/core/node/Exp.cpp +++ b/cas/src/core/node/Exp.cpp @@ -5,31 +5,31 @@ #include "cas/node/Exp.h" #include "cas/node/Const.h" #include "cas/node/Log.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "fmt/format.h" CAS_NAMESPACE -Exp::Exp(Expression* exponent) +Exp::Exp(ExprPtr exponent) : Power({ExpressionType::EXPONENTIAL, "exponential", "exp"}, Const::E(), exponent) {} double Exp::evaluate(const VariableMap& variables) { return std::exp(exponent->evaluate(variables)); } -Exp* Exp::clone() { - return new Exp(exponent->clone()); +ExprPtr Exp::clone() { + return Exp::from(exponent->clone()); } -Expression* Exp::_derivative(char var) { +ExprPtr Exp::_derivative(char var) { if (exponent->isOfType(ExpressionType::CONSTANT)) { - return new Const; + return Const::zero(); } return clone()->multiply(exponent->derivative(var)); } -Expression* Exp::simplified() { +ExprPtr Exp::simplified() { if (exponent->isOfType(ExpressionType::CONSTANT)) { double exponentValue = exponent->evaluate(); if (exponentValue == 0) @@ -38,7 +38,7 @@ Expression* Exp::simplified() { return Const::E(); } if (exponent->isOfType(ExpressionType::LOGARITHM)) { - auto* log = dynamic_cast(exponent); + auto* log = dynamic_cast(exponent.get()); if (log->getBase()->equals(this->base)) return log->getArgument()->simplified(); } diff --git a/cas/src/core/node/Expression.cpp b/cas/src/core/node/Expression.cpp index ad53064..0c7e799 100644 --- a/cas/src/core/node/Expression.cpp +++ b/cas/src/core/node/Expression.cpp @@ -13,7 +13,7 @@ #include "cas/node/Ln.h" #include "cas/node/Mod.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Round.h" #include "cas/node/Sign.h" #include "cas/node/Sqrt.h" @@ -33,22 +33,23 @@ #include "cas/node/trig/Tan.h" #include #include +#include CAS_NAMESPACE -Expression::Expression(const ExpressionProperties& properties) +Expr::Expr(const ExpressionProperties& properties) : properties{properties} {} -double Expression::evaluate(const VariableMap&) { +double Expr::evaluate(const VariableMap&) { throw std::runtime_error("Expression::evaluate() is not implemented for " + properties.getName()); } -double Expression::evaluate() { +double Expr::evaluate() { return evaluate({}); } -bool Expression::equals(Expression* expression) { - if (this == expression) +bool Expr::equals(ExprPtr expression) { + if (this == expression.get()) return true; if (!isOfType(expression->getProperties().getType())) @@ -57,180 +58,177 @@ bool Expression::equals(Expression* expression) { return _equals(expression); } -bool Expression::_equals(Expression*) { +bool Expr::_equals(ExprPtr) { throw std::runtime_error("Expression::equals() is not implemented for " + properties.getName()); } -Expression* Expression::clone() { +ExprPtr Expr::clone() { throw std::runtime_error("Expression::clone() is not implemented for " + properties.getName()); } -Expression* Expression::derivative(char var) { +ExprPtr Expr::derivative(char var) { return _derivative(var); } -Expression* Expression::_derivative(char) { +ExprPtr Expr::_derivative(char) { throw std::runtime_error("Expression::derivative() is not implemented for " + properties.getName()); } -Expression* Expression::simplified() { +ExprPtr Expr::simplified() { throw std::runtime_error("Expression::simplified() is not implemented for " + properties.getName()); } -bool Expression::isEquivalent(cas::IMath*) { +bool Expr::isEquivalent(ExprPtr) { throw std::runtime_error("Expression::isEquivalent() is not implemented for " + properties.getName()); } -Product* Expression::multiply(Expression* expression) { - return new Product({this, expression}); +ProdPtr Expr::multiply(ExprPtr expression) { + return std::make_shared(std::vector{shared_from_this(), expression}); } -Product* Expression::multiply(double value) { - return new Product({this, Const::n(value)}); +ProdPtr Expr::multiply(double value) { + return std::make_shared(std::vector{shared_from_this(), Const::n(value)}); } -Sum* Expression::add(Expression* expression) { - return new Sum({this, expression}); +SumPtr Expr::add(ExprPtr expression) { + return std::make_shared(std::vector{shared_from_this(), expression}); } -Sum* Expression::add(double value) { - return this->add(new Const(value)); +SumPtr Expr::add(double value) { + return add(Const::n(value)); } -Sum* Expression::subtract(Expression* expression) { - return new Sum({this, new Negate(expression)}); +SumPtr Expr::subtract(ExprPtr expression) { + const NegatePtr& negate = Negate::from(expression); + return std::make_shared(std::vector{shared_from_this(), negate}); } -Sum* Expression::subtract(double value) { - return this->subtract(new Const(value)); +SumPtr Expr::subtract(double value) { + return subtract(Const::n(value)); } -Divide* Expression::divide(Expression* expression) { - return new Divide(this, expression); +DividePtr Expr::divide(ExprPtr expression) { + return std::make_shared(shared_from_this(), expression); } -Divide* Expression::divide(double divisor) { +DividePtr Expr::divide(double divisor) { return this->divide(Const::n(divisor)); } -Negate* Expression::negate() { - return new Negate(this); +NegatePtr Expr::negate() { + return std::make_shared(shared_from_this()); } -Power* Expression::power(Expression* expression) { - return new Power(this, expression); +PowerPtr Expr::power(ExprPtr expression) { + return std::make_shared(shared_from_this(), expression); } -Power* Expression::power(double exponent) { - return new Power(this, exponent); +PowerPtr Expr::power(double exponent) { + return std::make_shared(shared_from_this(), exponent); } -Exp* Expression::exp() { - return new Exp(this); +ExpPtr Expr::exp() { + return std::make_shared(shared_from_this()); } -Log* Expression::log(Expression* base) { - return new Log(base, this); +LogPtr Expr::log(ExprPtr base) { + return std::make_shared(base, shared_from_this()); } -Log* Expression::log(double base) { - return new Log(base, this); +LogPtr Expr::log(double base) { + return std::make_shared(base, shared_from_this()); } -Ln* Expression::ln() { - return new Ln(this); +LnPtr Expr::ln() { + return std::make_shared(shared_from_this()); } - -Root* Expression::root(Expression* root) { - return new Root(this, root); +RootPtr Expr::root(ExprPtr root) { + return std::make_shared(shared_from_this(), root); } -Root* Expression::root(double root) { - return new Root(this, root); +RootPtr Expr::root(double root) { + return std::make_shared(shared_from_this(), root); } -Sqrt* Expression::sqrt() { - return new Sqrt(this); +SqrtPtr Expr::sqrt() { + return std::make_shared(shared_from_this()); } -Cbrt* Expression::cbrt() { - return new Cbrt(this); +CbrtPtr Expr::cbrt() { + return std::make_shared(shared_from_this()); } -Abs* Expression::abs() { - return new Abs(this); +AbsPtr Expr::abs() { + return std::make_shared(shared_from_this()); } -Cos* Expression::cos() { - return new Cos(this); +CosPtr Expr::cos() { + return std::make_shared(shared_from_this()); } -Sin* Expression::sin() { - return new Sin(this); +SinPtr Expr::sin() { + return std::make_shared(shared_from_this()); } -Tan* Expression::tan() { - return new Tan(this); +TanPtr Expr::tan() { + return std::make_shared(shared_from_this()); } -ArcTan* Expression::atan() { - return new ArcTan(this); +ArcTanPtr Expr::atan() { + return std::make_shared(shared_from_this()); } -ArcCos* Expression::acos() { - return new ArcCos(this); +ArcCosPtr Expr::acos() { + return std::make_shared(shared_from_this()); } -ArcSin* Expression::asin() { - return new ArcSin(this); +ArcSinPtr Expr::asin() { + return std::make_shared(shared_from_this()); } -Csc* Expression::csc() { - return new Csc(this); +CscPtr Expr::csc() { + return std::make_shared(shared_from_this()); } -Sec* Expression::sec() { - return new Sec(this); +SecPtr Expr::sec() { + return std::make_shared(shared_from_this()); } -Cot* Expression::cot() { - return new Cot(this); +CotPtr Expr::cot() { + return std::make_shared(shared_from_this()); } -ArcCsc* Expression::acsc() { - return new ArcCsc(this); +ArcCscPtr Expr::acsc() { + return std::make_shared(shared_from_this()); } -ArcSec* Expression::asec() { - return new ArcSec(this); +ArcSecPtr Expr::asec() { + return std::make_shared(shared_from_this()); } -ArcCot* Expression::acot() { - return new ArcCot(this); +ArcCotPtr Expr::acot() { + return std::make_shared(shared_from_this()); } -Floor* Expression::floor() { - return new Floor(this); +FloorPtr Expr::floor() { + return std::make_shared(shared_from_this()); } -Ceil* Expression::ceil() { - return new Ceil(this); +CeilPtr Expr::ceil() { + return std::make_shared(shared_from_this()); } -Round* Expression::round() { - return new Round(this); +RoundPtr Expr::round() { + return std::make_shared(shared_from_this()); } -Sign* Expression::sign() { - return new Sign(this); +SignPtr Expr::sign() { + return std::make_shared(shared_from_this()); } -Mod* Expression::mod(Expression* expression) { - return new Mod(this, expression); +ModPtr Expr::mod(ExprPtr expression) { + return std::make_shared(shared_from_this(), expression); } -Expression* Expression::reciprocal() { +ExprPtr Expr::reciprocal() { if (isOfType(ExpressionType::DIVIDE)) { auto* div = dynamic_cast(this); return div->getDivisor()->divide(div->getDividend()); } - return Const::n(1)->divide(this); + return Const::n(1)->divide(shared_from_this()); } -bool Expression::operator<(const cas::Expression& expression) const { - ExpressionType type = properties.getType(); - ExpressionType expressionType = expression.properties.getType(); - - int diff = static_cast(type) - static_cast(expressionType); +bool Expr::operator<(const cas::Expr& expression) const { + int diff = this->properties.getOrder() - expression.properties.getOrder(); if (diff == 0) { if (isOfType(ExpressionType::VARIABLE)) { @@ -258,39 +256,39 @@ bool Expression::operator<(const cas::Expression& expression) const { return diff < 0; } -bool Expression::lessThan(cas::Expression* expression) const { +bool Expr::lessThan(cas::ExprPtr expression) const { return *this < *expression; } -bool Expression::compare(cas::Expression* left, cas::Expression* right) { +bool Expr::compare(cas::ExprPtr left, cas::ExprPtr right) { return left->lessThan(right); } -ExpressionProperties Expression::getProperties() const { +ExpressionProperties Expr::getProperties() const { return properties; } -Expression* Expression::getParent() const { +Expr* Expr::getParent() const { return parent; } -void Expression::setParent(Expression* newParent) { +void Expr::setParent(Expr* newParent) { this->parent = newParent; } -bool Expression::isNegated() const { +bool Expr::isNegated() const { return properties.getType() == ExpressionType::NEGATE; } -bool Expression::isOfType(ExpressionType type) const { +bool Expr::isOfType(ExpressionType type) const { return properties.getType() == type; } -bool Expression::isOfSameType(Expression* expression) const { +bool Expr::isOfSameType(ExprPtr expression) const { return isOfType(expression->getProperties().getType()); } -std::string Expression::explicitText() { +std::string Expr::explicitText() { return properties.getShortName() + "(" + text() + ")"; } diff --git a/cas/src/core/node/Floor.cpp b/cas/src/core/node/Floor.cpp index afd8a46..cab9005 100644 --- a/cas/src/core/node/Floor.cpp +++ b/cas/src/core/node/Floor.cpp @@ -9,26 +9,26 @@ CAS_NAMESPACE -Floor::Floor(Expression* argument) +Floor::Floor(ExprPtr argument) : BracketExpression({ExpressionType::FLOOR, "floor_value", "floor"}, argument, L"\u230A", L"\u230B", "\\lfloor", "\\rfloor") {} double Floor::evaluate(const VariableMap& variables) { return std::floor(argument->evaluate(variables)); } -Floor* Floor::clone() { - return new Floor(argument->clone()); +ExprPtr Floor::clone() { + return Floor::from(argument->clone()); } -Expression* Floor::simplified() { +ExprPtr Floor::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { - return Const::n(Expression::evaluate()); + return Const::n(Expr::evaluate()); } if (argument->isOfType(ExpressionType::FLOOR)) { return argument->simplified(); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->ceil()->negate(); } diff --git a/cas/src/core/node/Ln.cpp b/cas/src/core/node/Ln.cpp index 8308c9d..2453e83 100644 --- a/cas/src/core/node/Ln.cpp +++ b/cas/src/core/node/Ln.cpp @@ -11,30 +11,30 @@ CAS_NAMESPACE -Ln::Ln(Expression* argument) +Ln::Ln(ExprPtr argument) : Log({ExpressionType::NATURAL_LOGARITHM, "natural_logarithm", "ln"}, Const::E(), argument) {} double Ln::evaluate(const VariableMap& variables) { return std::log(argument->evaluate(variables)); } -bool Ln::_equals(Expression* expression) { +bool Ln::_equals(ExprPtr expression) { if (expression->isOfType(ExpressionType::NATURAL_LOGARITHM)) { - auto* ln = dynamic_cast(expression); + auto* ln = dynamic_cast(expression.get()); return argument->equals(ln->argument); } return false; } -Ln* Ln::clone() { - return new Ln(argument->clone()); +ExprPtr Ln::clone() { + return Ln::from(argument->clone()); } -Expression* Ln::_derivative(char var) { +ExprPtr Ln::_derivative(char var) { return argument->derivative(var)->divide(argument->clone()); } -Expression* Ln::simplified() { +ExprPtr Ln::simplified() { if (argument->equals(base)) return Const::one(); if (argument->isOfType(ExpressionType::CONSTANT)) { @@ -43,11 +43,11 @@ Expression* Ln::simplified() { return Const::zero(); } if (argument->isOfType(ExpressionType::EXPONENTIAL)) { - auto* exp = dynamic_cast(argument); + auto* exp = dynamic_cast(argument.get()); return exp->getExponent()->simplified(); } if (argument->isOfType(ExpressionType::POWER)) { - auto* power = dynamic_cast(argument); + auto* power = dynamic_cast(argument.get()); if (power->getBase()->equals(base)) return power->getExponent()->simplified(); } diff --git a/cas/src/core/node/Log.cpp b/cas/src/core/node/Log.cpp index 8b50294..fc66f8b 100644 --- a/cas/src/core/node/Log.cpp +++ b/cas/src/core/node/Log.cpp @@ -7,57 +7,49 @@ #include "cas/node/Divide.h" #include "cas/node/Ln.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "fmt/printf.h" #include "fmt/xchar.h" CAS_NAMESPACE -Log::Log(const ExpressionProperties& props, Expression* base, Expression* argument) - : Expression(props), base(base), argument(argument) { +Log::Log(const ExpressionProperties& props, ExprPtr base, ExprPtr argument) + : Expr(props), base(base), argument(argument) { base->setParent(this); argument->setParent(this); } -Log::Log(Expression* base, Expression* argument) +Log::Log(ExprPtr base, ExprPtr argument) : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, base, argument) {} -Log::Log(double base, Expression* argument) - : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, new Const(base), argument) {} +Log::Log(double base, ExprPtr argument) + : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, Const::n(base), argument) {} -Log::Log(Expression* argument) +Log::Log(ExprPtr argument) : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, Const::n(10), argument) {} -Log::~Log() { - delete base; - delete argument; - - base = nullptr; - argument = nullptr; -} - double Log::evaluate(const VariableMap& variables) { return std::log(argument->evaluate(variables)) / std::log(base->evaluate(variables)); } -bool Log::_equals(Expression* expression) { +bool Log::_equals(ExprPtr expression) { if (expression->isOfType(ExpressionType::LOGARITHM)) { - auto* log = dynamic_cast(expression); + auto* log = dynamic_cast(expression.get()); return base->equals(log->base) && argument->equals(log->argument); } return false; } -Log* Log::clone() { - return new Log(base->clone(), argument->clone()); +ExprPtr Log::clone() { + return Log::from(base->clone(), argument->clone()); } -Expression* Log::_derivative(char var) { +ExprPtr Log::_derivative(char var) { bool baseIsConstant = base->isOfType(ExpressionType::CONSTANT); bool argumentIsConstant = argument->isOfType(ExpressionType::CONSTANT); if (baseIsConstant && argumentIsConstant) { - return new Const(0); + return Const::zero(); } if (baseIsConstant) { @@ -66,18 +58,16 @@ Expression* Log::_derivative(char var) { ->multiply(base->clone()->ln())); } - Expression* exp = base->clone() - ->ln() - ->divide(argument->clone() - ->ln()); - Expression* derivative = exp->derivative(var); - - delete exp; + ExprPtr exp = base->clone() + ->ln() + ->divide(argument->clone() + ->ln()); + ExprPtr derivative = exp->derivative(var); return derivative; } -Expression* Log::simplified() { +ExprPtr Log::simplified() { if (argument->equals(base)) return Const::one(); @@ -88,12 +78,12 @@ Expression* Log::simplified() { } if (argument->isOfType(ExpressionType::POWER)) { - auto* power = dynamic_cast(argument); + auto* power = dynamic_cast(argument.get()); if (power->getBase()->equals(base)) return power->getExponent()->simplified(); } - return new Log(base->simplified(), argument->simplified()); + return Log::from(base->simplified(), argument->simplified()); } bool Log::argumentNeedsParentheses() { diff --git a/cas/src/core/node/Max.cpp b/cas/src/core/node/Max.cpp index f26b0f4..d79d175 100644 --- a/cas/src/core/node/Max.cpp +++ b/cas/src/core/node/Max.cpp @@ -8,39 +8,39 @@ CAS_NAMESPACE -Max::Max(std::vector expressions) +Max::Max(std::vector expressions) : NaryExpression({ExpressionType::MAX, "maximum", "max"}, std::move(expressions)) {} double Max::evaluate(const VariableMap& variables) { - auto functor = [&](Expression* a, Expression* b) { + auto functor = [&](ExprPtr a, ExprPtr b) { return a->evaluate(variables) > b->evaluate(variables); }; return (*std::max_element(expressions.begin(), expressions.end(), functor))->evaluate(variables); } -Max* Max::clone() { - std::vector clonedExpressions; +ExprPtr Max::clone() { + std::vector clonedExpressions; clonedExpressions.reserve(expressions.size()); for (auto& expression: expressions) clonedExpressions.push_back(expression->clone()); - return new Max(clonedExpressions); + return Max::from(clonedExpressions); } -Expression* Max::simplified() { +ExprPtr Max::simplified() { if (expressions.size() == 1) return expressions[0]->simplified(); - std::vector simplifiedExpressions; + std::vector simplifiedExpressions; simplifiedExpressions.reserve(expressions.size()); - std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](Expression* expr) { + std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](ExprPtr expr) { return expr->simplified(); }); - bool (*isConstant)(Expression*) = [](Expression* expression) { + bool (*isConstant)(ExprPtr) = [](ExprPtr expression) { return expression->isOfType(ExpressionType::CONSTANT); }; @@ -49,14 +49,14 @@ Expression* Max::simplified() { if (constantCount > 1) { bool allConstant = std::all_of(simplifiedExpressions.begin(), simplifiedExpressions.end(), isConstant); if (allConstant) { - double maxElement = (*std::max_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](Expression* a, Expression* b) { + double maxElement = (*std::max_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](ExprPtr a, ExprPtr b) { return a->evaluate() > b->evaluate(); }))->evaluate(); return Const::n(maxElement); } - std::vector reducedExpressions; + std::vector reducedExpressions; reducedExpressions.reserve(expressions.size()); double max = -1.0 / 0.0; @@ -73,10 +73,10 @@ Expression* Max::simplified() { return reducedExpressions[0]; } - return new Max(reducedExpressions); + return Max::from(reducedExpressions); } - return new Max(simplifiedExpressions); + return Max::from(simplifiedExpressions); } CAS_NAMESPACE_END \ No newline at end of file diff --git a/cas/src/core/node/Min.cpp b/cas/src/core/node/Min.cpp index 60187ee..d9392bf 100644 --- a/cas/src/core/node/Min.cpp +++ b/cas/src/core/node/Min.cpp @@ -8,39 +8,39 @@ CAS_NAMESPACE -Min::Min(std::vector expressions) +Min::Min(std::vector expressions) : NaryExpression({ExpressionType::MIN, "minimum", "min"}, std::move(expressions)) {} double Min::evaluate(const VariableMap& variables) { - auto functor = [&](Expression* a, Expression* b) { + auto functor = [&](ExprPtr a, ExprPtr b) { return a->evaluate(variables) < b->evaluate(variables); }; return (*std::min_element(expressions.begin(), expressions.end(), functor))->evaluate(variables); } -Min* Min::clone() { - std::vector clonedExpressions; +ExprPtr Min::clone() { + std::vector clonedExpressions; clonedExpressions.reserve(expressions.size()); for (auto& expression: expressions) clonedExpressions.push_back(expression->clone()); - return new Min(clonedExpressions); + return Min::from(clonedExpressions); } -Expression* Min::simplified() { +ExprPtr Min::simplified() { if (expressions.size() == 1) return expressions[0]->simplified(); - std::vector simplifiedExpressions; + std::vector simplifiedExpressions; simplifiedExpressions.reserve(expressions.size()); - std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](Expression* expr) { + std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](ExprPtr expr) { return expr->simplified(); }); - bool (*isConstant)(Expression*) = [](Expression* expression) { + bool (*isConstant)(ExprPtr) = [](ExprPtr expression) { return expression->isOfType(ExpressionType::CONSTANT); }; @@ -49,14 +49,14 @@ Expression* Min::simplified() { if (constantCount > 1) { bool allConstant = std::all_of(simplifiedExpressions.begin(), simplifiedExpressions.end(), isConstant); if (allConstant) { - double minElement = (*std::min_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](Expression* a, Expression* b) { + double minElement = (*std::min_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](ExprPtr a, ExprPtr b) { return a->evaluate() < b->evaluate(); }))->evaluate(); return Const::n(minElement); } - std::vector reducedExpressions; + std::vector reducedExpressions; reducedExpressions.reserve(expressions.size()); double min = math::POSITIVE_INFINITY; @@ -73,10 +73,10 @@ Expression* Min::simplified() { return reducedExpressions[0]; } - return new Min(reducedExpressions); + return Min::from(reducedExpressions); } - return new Min(simplifiedExpressions); + return Min::from(simplifiedExpressions); } CAS_NAMESPACE_END diff --git a/cas/src/core/node/Mod.cpp b/cas/src/core/node/Mod.cpp index 95259dc..0c0f4c1 100644 --- a/cas/src/core/node/Mod.cpp +++ b/cas/src/core/node/Mod.cpp @@ -9,8 +9,8 @@ CAS_NAMESPACE -Mod::Mod(Expression* dividend, Expression* divisor) - : Expression({ExpressionType::MODULO, "modulo", "mod"}), dividend(dividend), divisor(divisor) { +Mod::Mod(ExprPtr dividend, ExprPtr divisor) + : Expr({ExpressionType::MODULO, "modulo", "mod"}), dividend(dividend), divisor(divisor) { if (divisor->isOfType(ExpressionType::CONSTANT) && divisor->evaluate() == 0) { throw std::invalid_argument("Divisor cannot be zero"); @@ -20,49 +20,41 @@ Mod::Mod(Expression* dividend, Expression* divisor) this->divisor->setParent(this); } -Mod::~Mod() { - delete dividend; - delete divisor; - - dividend = nullptr; - divisor = nullptr; -} - double Mod::evaluate(const VariableMap& variables) { return std::fmod(dividend->evaluate(variables), divisor->evaluate(variables)); } -bool Mod::_equals(Expression* expression) { - if (this == expression) +bool Mod::_equals(ExprPtr expression) { + if (this == expression.get()) return true; if (expression->isOfType(ExpressionType::MODULO)) { - auto* mod = dynamic_cast(expression); + auto* mod = dynamic_cast(expression.get()); return dividend->equals(mod->dividend) && divisor->equals(mod->divisor); } return false; } -Mod* Mod::clone() { - return new Mod(dividend->clone(), divisor->clone()); +ExprPtr Mod::clone() { + return Mod::from(dividend->clone(), divisor->clone()); } -Expression* Mod::simplified() { +ExprPtr Mod::simplified() { if (dividend->isOfType(ExpressionType::CONSTANT) && divisor->isOfType(ExpressionType::CONSTANT)) { if (isWholeNumber(dividend->evaluate()) && isWholeNumber(divisor->evaluate())) { - return new Const(Expression::evaluate()); + return Const::n(Expr::evaluate()); } } if (dividend->isOfType(ExpressionType::CONSTANT) && dividend->evaluate() == 0) { return Const::zero(); } - return new Mod(dividend->simplified(), divisor->simplified()); + return Mod::from(dividend->simplified(), divisor->simplified()); } std::string Mod::latex() { - return fmt::sprintf("\\mod{\\left(%s,%s\\right)}", dividend->latex(), divisor->latex()); + return fmt::sprintf(R"(\mod{\left(%s,%s\right)})", dividend->latex(), divisor->latex()); } std::wstring Mod::stringify() { diff --git a/cas/src/core/node/NaryExpression.cpp b/cas/src/core/node/NaryExpression.cpp index 265b612..28d49aa 100644 --- a/cas/src/core/node/NaryExpression.cpp +++ b/cas/src/core/node/NaryExpression.cpp @@ -10,26 +10,19 @@ CAS_NAMESPACE NaryExpression::NaryExpression(const ExpressionProperties& props, - std::vector expressions) - : Expression(props), expressions(std::move(expressions)) { + std::vector expressions) + : Expr(props), expressions(std::move(expressions)) { for (auto& expression: this->expressions) { expression->setParent(this); } } -NaryExpression::~NaryExpression() { - for (auto& expression: expressions) { - delete expression; - expression = nullptr; - } -} - -bool NaryExpression::_equals(Expression* expression) { - if (this == expression) +bool NaryExpression::_equals(ExprPtr expression) { + if (this == expression.get()) return true; if (expression->isOfType(properties.getType())) { - auto* function = dynamic_cast(expression); + auto* function = dynamic_cast(expression.get()); if (expressions.size() != function->expressions.size()) return false; diff --git a/cas/src/core/node/Negate.cpp b/cas/src/core/node/Negate.cpp index 79a891b..c9e82a5 100644 --- a/cas/src/core/node/Negate.cpp +++ b/cas/src/core/node/Negate.cpp @@ -10,32 +10,32 @@ CAS_NAMESPACE -Negate::Negate(Expression* expression) +Negate::Negate(ExprPtr expression) : UnaryExpression({ExpressionType::NEGATE, "negate", "neg"}, expression) {} double Negate::evaluate(const VariableMap& variables) { return -argument->evaluate(variables); } -bool Negate::_equals(Expression* expr) { - auto* negate = dynamic_cast(expr); +bool Negate::_equals(ExprPtr expr) { + auto* negate = dynamic_cast(expr.get()); return argument->equals(negate->argument); } -Negate* Negate::clone() { - return new Negate(argument->clone()); +ExprPtr Negate::clone() { + return Negate::from(argument->clone()); } -Negate* Negate::_derivative(char var) { - return new Negate(argument->derivative(var)); +ExprPtr Negate::_derivative(char var) { + return Negate::from(argument->derivative(var)); } -Expression* Negate::simplified() { +ExprPtr Negate::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { - return Const::n(Expression::evaluate()); + return Const::n(Expr::evaluate()); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->argument->simplified(); } diff --git a/cas/src/core/node/Operator.cpp b/cas/src/core/node/Operator.cpp index d1a9ab1..764bcce 100644 --- a/cas/src/core/node/Operator.cpp +++ b/cas/src/core/node/Operator.cpp @@ -7,34 +7,28 @@ CAS_NAMESPACE -Operator::Operator(const ExpressionProperties& props, double neutral, char symbol, std::vector expressions) - : Expression(props), neutral(neutral), symbol(symbol), expressions(std::move(expressions)) { +Operator::Operator(const ExpressionProperties& props, double neutral, char symbol, std::vector expressions) + : Expr(props), neutral(neutral), symbol(symbol), expressions(std::move(expressions)) { for (auto& expression: this->expressions) expression->setParent(this); } -Operator::~Operator() { - for (auto* expression: expressions) { - delete expression; - } -} - double Operator::evaluate(const VariableMap& variables) { double result = neutral; - for (auto* expression: expressions) + for (auto& expression: expressions) result = operate(result, expression->evaluate(variables)); return result; } -bool Operator::_equals(Expression* expression) { - if (this == expression) +bool Operator::_equals(ExprPtr expression) { + if (this == expression.get()) return true; if (!isOfSameType(expression)) return false; - auto* op = dynamic_cast(expression); + auto* op = dynamic_cast(expression.get()); if (expressions.size() != op->expressions.size() || symbol != op->getSymbol()) return false; diff --git a/cas/src/core/node/Power.cpp b/cas/src/core/node/Power.cpp index 28ce1fd..326259a 100644 --- a/cas/src/core/node/Power.cpp +++ b/cas/src/core/node/Power.cpp @@ -6,102 +6,79 @@ #include "cas/node/Const.h" #include "cas/node/Divide.h" #include "cas/node/Ln.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" #include "fmt/printf.h" #include "fmt/xchar.h" CAS_NAMESPACE -Power::Power(const ExpressionProperties& props, Expression* base, Expression* exponent) - : Expression(props), base(base), exponent(exponent) { - this->base->setParent(this); - this->exponent->setParent(this); +Power::Power(const ExpressionProperties& props, ExprPtr base, ExprPtr exponent) + : Expr(props), base(base), exponent(exponent) { + // this->base->setParent(shared_from_this()); + // this->exponent->setParent(shared_from_this()); } -Power::Power(Expression* base, Expression* exponent) +Power::Power(ExprPtr base, ExprPtr exponent) : Power({ExpressionType::POWER, "power", "pow"}, base, exponent) {} -Power::Power(Expression* base, double exponent) - : Power({ExpressionType::POWER, "power", "pow"}, base, new Const(exponent)) {} - -Power::~Power() { - delete base; - delete exponent; - - base = nullptr; - exponent = nullptr; -} +Power::Power(ExprPtr base, double exponent) + : Power({ExpressionType::POWER, "power", "pow"}, base, Const::n(exponent)) {} double Power::evaluate(const VariableMap& variables) { return pow(base->evaluate(variables), exponent->evaluate(variables)); } -bool Power::_equals(Expression* expression) { - auto* power = dynamic_cast(expression); +bool Power::_equals(ExprPtr expression) { + auto* power = dynamic_cast(expression.get()); return base->equals(power->base) && exponent->equals(power->exponent); } -Power* Power::clone() { - return new Power(base->clone(), exponent->clone()); +ExprPtr Power::clone() { + return Power::from(base->clone(), exponent->clone()); } -Expression* Power::_derivative(char var) { +ExprPtr Power::_derivative(char var) { bool baseIsNumber = base->isOfType(ExpressionType::CONSTANT); bool exponentIsNumber = exponent->isOfType(ExpressionType::CONSTANT); if (baseIsNumber && exponentIsNumber)// case b^k, where b and k are both numbers (constants) - return new Const(0); + return Const::zero(); if (!baseIsNumber && exponentIsNumber)// case [ f(x) ]^k, where k is a constant { - auto* k = dynamic_cast(exponent); - - return new Product({ - // k*f^(k-1)*f' - exponent->clone(), // k - base->derivative(var), // f' - new Power( // f^(k - 1) - base->clone(), // f - new Const(k->getValue() - 1)// k - 1 - ) // end f^(k - 1) - }); // end k*f^(k-1)*f' + auto* k = dynamic_cast(exponent.get()); + + // k*f^(k-1)*f' + return Prod::from({ + exponent->clone(), // k + base->derivative(var), // f' + base->clone()->power(Const::n(k->getValue() - 1))// f^(k - 1) + }); } if (baseIsNumber)// case k^[ f(x) ], where k is a constant { - return new Product({ - // k^f * lnk * f' + // k^f * lnk * f' + return Prod::from({ this->clone(), // a^f exponent->derivative(var),// f' - new Ln(base) // lnk - }); // end k^f * lnk * f' + Ln::from(base) // lnk + }); } // otherwise: case [ f(x) ]^[ g(x) ], here we use the generalized power rule - return new Product({ - // [f(x)]^[g(x)] * ( g'*lnf + g*f'/f ) - this->clone(),// [f(x)] ^ [g(x)] - new Sum({ - // g'*lnf + g*f'/f - new Product({ - // g' * lnf - exponent->derivative(var),// g' - new Ln(base) // lnf - }), // end g' * lnf - new Product({ - // g * f' * 1/f - exponent->clone(), // g - new Divide( // f'/f - base->derivative(var),// f' - base->clone() // f - ) // end f'/f - }) // end g*f'/f - }) // end g'*lnf + g*f'/f - }); // end [f(x)]^[g(x)] * ( g'*lnf + g*f'/f) + // [f(x)]^[g(x)] * ( g'*lnf + g*f'/f ) + return Prod::from({this->clone(),// [f(x)] ^ [g(x)] + Sum::from({ // g'*lnf + g*f'/f + exponent->derivative(var) + ->multiply(Ln::from(base)),// g'*lnf // end g' * lnf + exponent->clone() + ->multiply(base->derivative(var) + ->divide(base->clone()))})});// g*f'/f } -Expression* Power::simplified() { +ExprPtr Power::simplified() { if (exponent->isOfType(ExpressionType::CONSTANT)) { double exponentValue = exponent->evaluate(); if (exponentValue == 0) { @@ -113,34 +90,34 @@ Expression* Power::simplified() { if (base->isOfType(ExpressionType::CONSTANT)) { if (isWholeNumber(base->evaluate()) && isWholeNumber(exponent->evaluate())) { - double value = Expression::evaluate(); + double value = Expr::evaluate(); if (value < 10000.) return Const::n(value); } } } if (base->isOfType(ExpressionType::DIVIDE)) { - auto* frac = dynamic_cast(base); + auto* frac = dynamic_cast(base.get()); return frac->getDividend()->simplified()->power(exponent->simplified())->divide(frac->getDivisor()->simplified()->power(exponent->simplified())); } if (base->isOfType(ExpressionType::POWER)) { - auto* pow = dynamic_cast(base); + auto* pow = dynamic_cast(base.get()); return pow->getBase()->simplified()->power(pow->getExponent()->simplified()->multiply(exponent->simplified())); } if (base->isOfType(ExpressionType::PRODUCT)) { - auto* prod = dynamic_cast(base); + auto* prod = dynamic_cast(base.get()); - std::vector newFactors; + std::vector newFactors; newFactors.reserve(prod->getExpressionsSize()); - for (auto* factor: prod->getExpressions()) { + for (auto& factor: prod->getExpressions()) { newFactors.push_back(factor->simplified() ->power(exponent->simplified())); } - return new Product(newFactors); + return Prod::from(newFactors); } - if (instanceof (base)) { - auto* log = dynamic_cast(base); + if (instanceof (base.get())) { + auto* log = dynamic_cast(base.get()); if (log->getBase()->equals(base)) { return log->getArgument()->simplified(); } @@ -154,7 +131,7 @@ bool Power::baseNeedsParentheses() { } bool Power::exponentNeedsParentheses() { - return exponent->isOfType(ExpressionType::DIVIDE) || exponent->isOfType(ExpressionType::POWER) || instanceof (exponent); + return exponent->isOfType(ExpressionType::DIVIDE) || exponent->isOfType(ExpressionType::POWER) || instanceof (exponent.get()); } std::string Power::latex() { diff --git a/cas/src/core/node/Product.cpp b/cas/src/core/node/Product.cpp index 23c34ff..7ebd233 100644 --- a/cas/src/core/node/Product.cpp +++ b/cas/src/core/node/Product.cpp @@ -2,68 +2,67 @@ // Created by Abd-El-Aziz Zayed on 2022-09-01. // -#include "cas/node/Product.h" #include "cas/node/Const.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" #include CAS_NAMESPACE -Product::Product(const std::vector& expressions) +Prod::Prod(const std::vector& expressions) : Operator({ExpressionType::PRODUCT, "product", "prod"}, 1.0, '*', expressions) {} -Product* Product::clone() { - std::vector clonedExpressions; +ExprPtr Prod::clone() { + std::vector clonedExpressions; clonedExpressions.reserve(expressions.size()); for (auto& expression: expressions) clonedExpressions.push_back(expression->clone()); - return new Product{clonedExpressions}; + return Prod::from({clonedExpressions}); } -Expression* Product::_derivative(char var) { - std::vector differentiatedExpressions; +ExprPtr Prod::_derivative(char var) { + std::vector differentiatedExpressions; differentiatedExpressions.reserve(expressions.size()); for (size_t i = 0; i < expressions.size(); i++) { - std::vector products; + std::vector products; products.reserve(expressions.size()); for (size_t j = 0; j < expressions.size(); j++) { - Expression* exp = expressions[j]; - Expression* prod = i == j ? exp->derivative(var) : exp->clone(); + ExprPtr exp = expressions[j]; + ExprPtr prod = i == j ? exp->derivative(var) : exp->clone(); products.push_back(prod); } - differentiatedExpressions.push_back(new Product{products}); + differentiatedExpressions.push_back(Prod::from({products})); } - return new Sum{differentiatedExpressions}; + return Sum::from({differentiatedExpressions}); } -Expression* Product::simplified() { +ExprPtr Prod::simplified() { // TODO: simplify // If there is only one expression, return it if (expressions.size() == 1) return expressions[0]->simplified(); - std::vector simplifiedExpressions; + std::vector simplifiedExpressions; simplifiedExpressions.reserve(expressions.size()); double constant = 1.0; for (auto& expression: expressions) { - Expression* x = expression->simplified(); + ExprPtr x = expression->simplified(); if (x->isOfType(ExpressionType::CONSTANT)) { double value = x->evaluate(); if (value == 0) { - delete x; return Const::zero(); } constant *= value; continue; } else if (x->isOfType(ExpressionType::PRODUCT)) { - auto* product = dynamic_cast(x); + auto* product = dynamic_cast(x.get()); for (auto& exp: product->expressions) simplifiedExpressions.push_back(exp); continue; @@ -77,24 +76,24 @@ Expression* Product::simplified() { if (simplifiedExpressions.size() == 1) return simplifiedExpressions[0]; - std::sort(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](Expression* a, Expression* b) { + std::sort(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](ExprPtr a, ExprPtr b) { return a->lessThan(b); }); - return new Product{simplifiedExpressions}; + return Prod::from({simplifiedExpressions}); } -bool Product::needsParentheses(Expression* expression) { +bool Prod::needsParentheses(ExprPtr expression) { return expression->getProperties().getType() == ExpressionType::SUM; } -std::string Product::latex() { +std::string Prod::latex() { if (expressions.empty()) return ""; std::stringstream ss; for (size_t i = 0; i < expressions.size(); i++) { - Expression* exp = expressions[i]; + ExprPtr exp = expressions[i]; bool needsParens = needsParentheses(exp); if (needsParens) @@ -113,14 +112,14 @@ std::string Product::latex() { return ss.str(); } -std::wstring Product::stringify() { +std::wstring Prod::stringify() { if (expressions.empty()) return L""; std::wstringstream ss; for (size_t i = 0; i < expressions.size(); i++) { - Expression* exp = expressions[i]; + ExprPtr exp = expressions[i]; bool needsParens = needsParentheses(exp); if (needsParens) diff --git a/cas/src/core/node/Root.cpp b/cas/src/core/node/Root.cpp index 46f2c96..d3fa98a 100644 --- a/cas/src/core/node/Root.cpp +++ b/cas/src/core/node/Root.cpp @@ -12,24 +12,24 @@ CAS_NAMESPACE -Root::Root(const ExpressionProperties& props, Expression* base, Expression* root) +Root::Root(const ExpressionProperties& props, ExprPtr base, ExprPtr root) : Power(props, base, root) {} -Root::Root(Expression* base, Expression* root) +Root::Root(ExprPtr base, ExprPtr root) : Root({ExpressionType::ROOT, "root", "root"}, base, root) {} -Root::Root(Expression* base, double root) - : Root(base, new Const(root)) {} +Root::Root(ExprPtr base, double root) + : Root(base, Const::n(root)) {} double Root::evaluate(const VariableMap& variables) { return pow(base->evaluate(variables), 1.0 / exponent->evaluate(variables)); } -Root* Root::clone() { - return new Root(base->clone(), exponent->clone()); +ExprPtr Root::clone() { + return Root::from(base->clone(), exponent->clone()); } -Expression* Root::simplified() { +ExprPtr Root::simplified() { if (exponent->isOfType(ExpressionType::CONSTANT)) { double root = exponent->evaluate(); if (root == 1) @@ -40,7 +40,7 @@ Expression* Root::simplified() { return base->simplified()->cbrt(); } - return new Root(base->simplified(), exponent->simplified()); + return Root::from(base->simplified(), exponent->simplified()); } std::string Root::latex() { diff --git a/cas/src/core/node/Round.cpp b/cas/src/core/node/Round.cpp index 5ceeaa8..d3c0df8 100644 --- a/cas/src/core/node/Round.cpp +++ b/cas/src/core/node/Round.cpp @@ -7,20 +7,20 @@ CAS_NAMESPACE -Round::Round(Expression* argument) +Round::Round(ExprPtr argument) : BracketExpression({ExpressionType::ROUND, "round", "round"}, argument, L"\u230A", L"\u2309", "\\lfloor", "\\rceil") {} double Round::evaluate(const VariableMap& variables) { return std::round(argument->evaluate(variables)); } -Round* Round::clone() { - return new Round(argument->clone()); +ExprPtr Round::clone() { + return Round::from(argument->clone()); } -Expression* Round::simplified() { +ExprPtr Round::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { - return Const::n(Expression::evaluate()); + return Const::n(Expr::evaluate()); } if (argument->isOfType(ExpressionType::ROUND)) { return argument->simplified(); diff --git a/cas/src/core/node/Sign.cpp b/cas/src/core/node/Sign.cpp index 2190703..62a2473 100644 --- a/cas/src/core/node/Sign.cpp +++ b/cas/src/core/node/Sign.cpp @@ -10,7 +10,7 @@ CAS_NAMESPACE -Sign::Sign(Expression* argument) +Sign::Sign(ExprPtr argument) : UnaryExpression({ExpressionType::SIGN, "sign", "sign"}, argument) {} double Sign::evaluate(const VariableMap& variables) { @@ -19,30 +19,30 @@ double Sign::evaluate(const VariableMap& variables) { : 0; } -bool Sign::_equals(Expression* expression) { - if (this == expression) +bool Sign::_equals(ExprPtr expression) { + if (this == expression.get()) return true; if (expression->isOfType(ExpressionType::SIGN)) { - auto* sign = dynamic_cast(expression); + auto* sign = dynamic_cast(expression.get()); return argument->equals(sign->argument); } return false; } -Sign* Sign::clone() { - return new Sign(argument->clone()); +ExprPtr Sign::clone() { + return Sign::from(argument->clone()); } -Expression* Sign::simplified() { +ExprPtr Sign::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { - return new Const(Expression::evaluate()); + return Const::n(Expr::evaluate()); } if (argument->isOfType(ExpressionType::SIGN)) { return argument->simplified(); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->sign()->negate(); } return argument->simplified()->sign(); diff --git a/cas/src/core/node/Sqrt.cpp b/cas/src/core/node/Sqrt.cpp index b85e8c1..ae47e91 100644 --- a/cas/src/core/node/Sqrt.cpp +++ b/cas/src/core/node/Sqrt.cpp @@ -5,40 +5,42 @@ #include "cas/node/Sqrt.h" #include "cas/node/Const.h" #include "cas/node/Divide.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/util/StringUtils.h" #include "fmt/printf.h" #include "fmt/xchar.h" CAS_NAMESPACE -Sqrt::Sqrt(Expression* base) - : Root({ExpressionType::SQUARE_ROOT, "square_root", "sqrt"}, base, new Const(2)) {} +Sqrt::Sqrt(ExprPtr base) + : Root({ExpressionType::SQUARE_ROOT, "square_root", "sqrt"}, base, Const::n(2)) {} double Sqrt::evaluate(const VariableMap& variables) { return std::sqrt(base->evaluate(variables)); } -Sqrt* Sqrt::clone() { - return new Sqrt(base->clone()); +ExprPtr Sqrt::clone() { + return Sqrt::from(base->clone()); } -Expression* Sqrt::_derivative(char var) { - return new Divide( - base->derivative(var), - new Product({new Const(2), clone()})); +ExprPtr Sqrt::_derivative(char var) { + + // sqrt( f )' = f' / (2 * sqrt( f )) + return Divide::from( + base->derivative(var), // f' + Const::n(2)->multiply(clone()));// 2 * sqrt( f ) } -Expression* Sqrt::simplified() { +ExprPtr Sqrt::simplified() { if (base->isOfType(ExpressionType::CONSTANT)) { - double sqrt = Expression::evaluate(); + double sqrt = Expr::evaluate(); if (isWholeNumber(sqrt)) - return new Const(sqrt); + return Const::from(sqrt); else return clone(); } if (base->isOfType(ExpressionType::POWER)) { - auto* power = dynamic_cast(base); + auto* power = dynamic_cast(base.get()); if (power->getExponent()->isOfType(ExpressionType::CONSTANT)) { double exponent = power->getExponent()->evaluate(); if (exponent == 2) diff --git a/cas/src/core/node/Sum.cpp b/cas/src/core/node/Sum.cpp index 32489d6..e64686e 100644 --- a/cas/src/core/node/Sum.cpp +++ b/cas/src/core/node/Sum.cpp @@ -4,58 +4,57 @@ #include "cas/node/Sum.h" #include "cas/node/Const.h" -#include #include +#include CAS_NAMESPACE -Sum::Sum(const std::vector& expressions) +Sum::Sum(const std::vector& expressions) : Operator({ExpressionType::SUM, "summation", "sum"}, 0.0, '+', expressions) {} -Sum* Sum::clone() { - std::vector clonedExpressions; +ExprPtr Sum::clone() { + std::vector clonedExpressions; clonedExpressions.reserve(expressions.size()); for (auto& expression: expressions) clonedExpressions.push_back(expression->clone()); - return new Sum{clonedExpressions}; + return Sum::from(clonedExpressions); } -Sum* Sum::_derivative(char var) { - std::vector differentiatedExpressions; +ExprPtr Sum::_derivative(char var) { + std::vector differentiatedExpressions; differentiatedExpressions.reserve(expressions.size()); for (auto& expression: expressions) differentiatedExpressions.push_back(expression->derivative(var)); - return new Sum{differentiatedExpressions}; + return Sum::from(differentiatedExpressions); } -Expression* Sum::simplified() { +ExprPtr Sum::simplified() { // TODO: simplify // If there is only one expression, return it if (expressions.size() == 1) return expressions[0]->simplified(); - std::vector simplifiedExpressions; + std::vector simplifiedExpressions; simplifiedExpressions.reserve(expressions.size()); double constant = 0.0; for (auto& expression: expressions) { - Expression* x = expression->simplified(); + ExprPtr x = expression->simplified(); if (x->isOfType(ExpressionType::CONSTANT)) { double value = x->evaluate(); if (value == 0.0) { - delete x; continue; } constant += value; continue; } else if (x->isOfType(ExpressionType::SUM)) { - auto* sum = dynamic_cast(x); + auto* sum = dynamic_cast(x.get()); for (auto& exp: sum->expressions) simplifiedExpressions.push_back(exp); continue; @@ -70,7 +69,7 @@ Expression* Sum::simplified() { return simplifiedExpressions[0]; std::sort(simplifiedExpressions.begin(), simplifiedExpressions.end()); - return new Sum{simplifiedExpressions}; + return Sum::from(simplifiedExpressions); } std::string Sum::latex() { @@ -80,7 +79,7 @@ std::string Sum::latex() { std::stringstream ss; for (size_t i = 0; i < expressions.size(); i++) { - Expression* exp = expressions[i]; + ExprPtr exp = expressions[i]; bool needsParens = needsParentheses(exp); if (needsParens) @@ -104,7 +103,7 @@ std::wstring Sum::stringify() { std::wstringstream ss; for (size_t i = 0; i < expressions.size(); i++) { - Expression* exp = expressions[i]; + ExprPtr exp = expressions[i]; bool needsParens = needsParentheses(exp); if (needsParens) diff --git a/cas/src/core/node/UnaryExpression.cpp b/cas/src/core/node/UnaryExpression.cpp index 5713aa8..6d489a9 100644 --- a/cas/src/core/node/UnaryExpression.cpp +++ b/cas/src/core/node/UnaryExpression.cpp @@ -11,24 +11,19 @@ CAS_NAMESPACE -UnaryExpression::UnaryExpression(const ExpressionProperties& properties, Expression* argument) - : Expression(properties), argument(argument) { +UnaryExpression::UnaryExpression(const ExpressionProperties& properties, ExprPtr argument) + : Expr(properties), argument(argument) { this->argument->setParent(this); } -UnaryExpression::~UnaryExpression() { - delete argument; - argument = nullptr; -} - -Expression* UnaryExpression::derivative(char var) { +ExprPtr UnaryExpression::derivative(char var) { if (argument->isOfType(ExpressionType::CONSTANT)) - return new Const(0); + return Const::zero(); if (argument->isOfType(ExpressionType::VARIABLE)) { - auto* variable = dynamic_cast(argument); + auto* variable = dynamic_cast(argument.get()); if (variable->getSymbol() != var) - return new Const(0); + return Const::zero(); } return _derivative(var); diff --git a/cas/src/core/node/Var.cpp b/cas/src/core/node/Var.cpp index b54b515..35776a9 100644 --- a/cas/src/core/node/Var.cpp +++ b/cas/src/core/node/Var.cpp @@ -10,10 +10,10 @@ CAS_NAMESPACE Var::Var(char variable) - : Expression({ExpressionType::VARIABLE, "variable", "var"}), symbol(variable) {} + : Expr({ExpressionType::VARIABLE, "variable", "var"}), symbol(variable) {} -Var* Var::clone() { - return new Var(symbol); +ExprPtr Var::clone() { + return Var::from(symbol); } double Var::evaluate(const VariableMap& variables) { @@ -22,17 +22,17 @@ double Var::evaluate(const VariableMap& variables) { return variables.at(symbol); } -bool Var::_equals(Expression* expression) { - auto* var = dynamic_cast(expression); +bool Var::_equals(ExprPtr expression) { + auto* var = dynamic_cast(expression.get()); return var->getSymbol() == symbol; } -Expression* Var::_derivative(char var) { +ExprPtr Var::_derivative(char var) { double derivative = symbol == var ? 1.0 : 0.0; - return new Const{derivative}; + return Const::n(derivative); } -Var* Var::simplified() { +ExprPtr Var::simplified() { return clone(); } diff --git a/cas/src/core/node/trig/ArcCos.cpp b/cas/src/core/node/trig/ArcCos.cpp index ba0d80f..9c72abe 100644 --- a/cas/src/core/node/trig/ArcCos.cpp +++ b/cas/src/core/node/trig/ArcCos.cpp @@ -11,18 +11,18 @@ CAS_NAMESPACE -ArcCos::ArcCos(Expression* argument) +ArcCos::ArcCos(ExprPtr argument) : InverseTrigExpression({ExpressionType::ARC_COS, "arccos", "acos"}, argument) {} double ArcCos::evaluate(const VariableMap& variables) { return std::acos(argument->evaluate(variables)); } -ArcCos* ArcCos::clone() { - return new ArcCos(argument->clone()); +ExprPtr ArcCos::clone() { + return ArcCos::from(argument->clone()); } -Expression* ArcCos::_derivative(char var) { +ExprPtr ArcCos::_derivative(char var) { return argument->derivative(var) ->negate() ->divide(Const::one() @@ -30,7 +30,7 @@ Expression* ArcCos::_derivative(char var) { ->sqrt()); } -Expression* ArcCos::simplified() { +ExprPtr ArcCos::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { if (argument->evaluate() == 1) return Const::zero(); diff --git a/cas/src/core/node/trig/ArcCot.cpp b/cas/src/core/node/trig/ArcCot.cpp index 1baf0da..70872f5 100644 --- a/cas/src/core/node/trig/ArcCot.cpp +++ b/cas/src/core/node/trig/ArcCot.cpp @@ -7,29 +7,29 @@ #include "cas/node/Divide.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" CAS_NAMESPACE -ArcCot::ArcCot(Expression* argument) +ArcCot::ArcCot(ExprPtr argument) : InverseTrigExpression({ExpressionType::ARC_COT, "arccot", "acot"}, argument) {} double ArcCot::evaluate(const VariableMap& variables) { return std::atan(1 / argument->evaluate(variables)); } -ArcCot* ArcCot::clone() { - return new ArcCot(argument->clone()); +ExprPtr ArcCot::clone() { + return ArcCot::from(argument->clone()); } -Expression* ArcCot::_derivative(char var) { - return new Divide( +ExprPtr ArcCot::_derivative(char var) { + return Divide::from( argument->derivative(var)->negate(), - new Sum({argument->clone()->power(2), new Const(1)})); + Sum::from({argument->clone()->power(2), Const::one()})); } -Expression* ArcCot::simplified() { +ExprPtr ArcCot::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { if (argument->evaluate() == 1) return Const::PI()->divide(4); diff --git a/cas/src/core/node/trig/ArcCsc.cpp b/cas/src/core/node/trig/ArcCsc.cpp index 6f9524d..49db0c2 100644 --- a/cas/src/core/node/trig/ArcCsc.cpp +++ b/cas/src/core/node/trig/ArcCsc.cpp @@ -7,24 +7,24 @@ #include "cas/node/Const.h" #include "cas/node/Divide.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sqrt.h" #include "cas/node/Sum.h" CAS_NAMESPACE -ArcCsc::ArcCsc(Expression* argument) +ArcCsc::ArcCsc(ExprPtr argument) : InverseTrigExpression({ExpressionType::ARC_CSC, "arccsc", "acsc"}, argument) {} double ArcCsc::evaluate(const VariableMap& variables) { return std::asin(1 / argument->evaluate(variables)); } -ArcCsc* ArcCsc::clone() { - return new ArcCsc(argument->clone()); +ExprPtr ArcCsc::clone() { + return ArcCsc::from(argument->clone()); } -Expression* ArcCsc::_derivative(char var) { +ExprPtr ArcCsc::_derivative(char var) { return argument->derivative(var) ->negate() ->divide(argument->clone() @@ -35,7 +35,7 @@ Expression* ArcCsc::_derivative(char var) { ->sqrt())); } -Expression* ArcCsc::simplified() { +ExprPtr ArcCsc::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { if (argument->evaluate() == 1) return Const::PI()->divide(2); diff --git a/cas/src/core/node/trig/ArcSec.cpp b/cas/src/core/node/trig/ArcSec.cpp index c5c02f9..09ea167 100644 --- a/cas/src/core/node/trig/ArcSec.cpp +++ b/cas/src/core/node/trig/ArcSec.cpp @@ -8,24 +8,24 @@ #include "cas/node/Divide.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sqrt.h" #include "cas/node/Sum.h" CAS_NAMESPACE -ArcSec::ArcSec(Expression* argument) +ArcSec::ArcSec(ExprPtr argument) : InverseTrigExpression({ExpressionType::ARC_SEC, "arcsec", "asec"}, argument) {} double ArcSec::evaluate(const VariableMap& variables) { return std::acos(1.0 / argument->evaluate(variables)); } -ArcSec* ArcSec::clone() { - return new ArcSec(argument->clone()); +ExprPtr ArcSec::clone() { + return ArcSec::from(argument->clone()); } -Expression* ArcSec::_derivative(char var) { +ExprPtr ArcSec::_derivative(char var) { return argument->derivative(var) ->divide(argument->clone() ->abs() @@ -35,7 +35,7 @@ Expression* ArcSec::_derivative(char var) { ->sqrt())); } -Expression* ArcSec::simplified() { +ExprPtr ArcSec::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { if (argument->evaluate() == 1) return Const::zero(); diff --git a/cas/src/core/node/trig/ArcSin.cpp b/cas/src/core/node/trig/ArcSin.cpp index 2d488b1..39b6bc0 100644 --- a/cas/src/core/node/trig/ArcSin.cpp +++ b/cas/src/core/node/trig/ArcSin.cpp @@ -11,23 +11,24 @@ CAS_NAMESPACE -ArcSin::ArcSin(Expression* argument) +ArcSin::ArcSin(ExprPtr argument) : InverseTrigExpression({ExpressionType::ARC_SIN, "arcsin", "asin"}, argument) {} double ArcSin::evaluate(const VariableMap& variables) { return std::asin(argument->evaluate(variables)); } -ArcSin* ArcSin::clone() { - return new ArcSin(argument->clone()); +ExprPtr ArcSin::clone() { + return ArcSin::from(argument->clone()); } -Expression* ArcSin::_derivative(char var) { - std::vector terms = {new Const(1), argument->clone()->power(2)->negate()}; - return new Divide(argument->derivative(var), new Sqrt(new Sum(terms))); +ExprPtr ArcSin::_derivative(char var) { + // arcsin( f )' = f' / sqrt(1 - f^2) + std::vector terms = {Const::one(), argument->clone()->power(2)->negate()}; + return argument->derivative(var)->divide(Sum::from(terms)->sqrt()); } -Expression* ArcSin::simplified() { +ExprPtr ArcSin::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { if (argument->evaluate() == 0) return Const::zero(); diff --git a/cas/src/core/node/trig/ArcTan.cpp b/cas/src/core/node/trig/ArcTan.cpp index 2f4d044..90ad753 100644 --- a/cas/src/core/node/trig/ArcTan.cpp +++ b/cas/src/core/node/trig/ArcTan.cpp @@ -11,24 +11,24 @@ CAS_NAMESPACE -ArcTan::ArcTan(Expression* argument) +ArcTan::ArcTan(ExprPtr argument) : InverseTrigExpression({ExpressionType::ARC_TAN, "arctan", "atan"}, argument) {} double ArcTan::evaluate(const VariableMap& variables) { return std::atan(argument->evaluate(variables)); } -ArcTan* ArcTan::clone() { - return new ArcTan(argument->clone()); +ExprPtr ArcTan::clone() { + return ArcTan::from(argument->clone()); } -Expression* ArcTan::_derivative(char var) { - return new Divide( +ExprPtr ArcTan::_derivative(char var) { + return Divide::from( argument->derivative(var), - new Sum({new Const(1), argument->clone()->power(2)})); + Sum::from({Const::one(), argument->clone()->power(2)})); } -Expression* ArcTan::simplified() { +ExprPtr ArcTan::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { if (argument->evaluate() == 0) return Const::zero(); diff --git a/cas/src/core/node/trig/Cos.cpp b/cas/src/core/node/trig/Cos.cpp index a381417..c3aa87f 100644 --- a/cas/src/core/node/trig/Cos.cpp +++ b/cas/src/core/node/trig/Cos.cpp @@ -6,39 +6,42 @@ #include "cas/node/Const.h" #include "cas/node/Divide.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sqrt.h" #include "cas/node/trig/ArcCos.h" #include "cas/node/trig/Sin.h" CAS_NAMESPACE -Cos::Cos(Expression* argument) : TrigExpression({ExpressionType::COS, "cosine", "cos"}, argument) {} +Cos::Cos(ExprPtr argument) : TrigExpression({ExpressionType::COS, "cosine", "cos"}, argument) {} double Cos::evaluate(const VariableMap& variables) { return std::cos(argument->evaluate(variables)); } -Cos* Cos::clone() { - return new Cos(argument->clone()); +ExprPtr Cos::clone() { + return Cos::from(argument->clone()); } -Expression* Cos::_derivative(char variable) { - return new Negate(argument->clone()->sin()->multiply(argument->derivative(variable))); +ExprPtr Cos::_derivative(char variable) { + return argument->clone() + ->sin() + ->multiply(argument->derivative(variable)) + ->negate(); } -Expression* Cos::simplified() { +ExprPtr Cos::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { double value = argument->evaluate(); if (unitCircle.contains(value)) return unitCircle.at(value).cos->clone(); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->cos(); } if (argument->isOfType(ExpressionType::ARC_COS)) { - auto* arcCos = dynamic_cast(argument); + auto* arcCos = dynamic_cast(argument.get()); return arcCos->getArgument()->simplified(); } diff --git a/cas/src/core/node/trig/Cot.cpp b/cas/src/core/node/trig/Cot.cpp index 59318c4..bbea163 100644 --- a/cas/src/core/node/trig/Cot.cpp +++ b/cas/src/core/node/trig/Cot.cpp @@ -6,44 +6,46 @@ #include "cas/node/Const.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/trig/ArcCot.h" #include "cas/node/trig/Csc.h" #include "cas/node/trig/Sec.h" CAS_NAMESPACE -Cot::Cot(Expression* argument) : TrigExpression({ExpressionType::COT, "cotangent", "cot"}, argument) {} +Cot::Cot(ExprPtr argument) : TrigExpression({ExpressionType::COT, "cotangent", "cot"}, argument) {} double Cot::evaluate(const VariableMap& variables) { return 1.0 / std::tan(argument->evaluate(variables)); } -Cot* Cot::clone() { - return new Cot(argument->clone()); +ExprPtr Cot::clone() { + return Cot::from(argument->clone()); } -Expression* Cot::_derivative(char variable) { - return new Negate(argument->clone() - ->csc() - ->power(2) - ->multiply(argument->derivative(variable))); +ExprPtr Cot::_derivative(char variable) { + // cot( f )' = -csc( f )^2 * f' + return argument->clone() + ->csc() + ->power(2) + ->multiply(argument->derivative(variable)) + ->negate(); } -Expression* Cot::simplified() { +ExprPtr Cot::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { double value = argument->evaluate(); if (unitCircle.contains(value)) { - Expression* tan = unitCircle.at(value).tan; + ExprPtr tan = unitCircle.at(value).tan; return tan->clone()->reciprocal(); } } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->cot()->negate(); } if (argument->isOfType(ExpressionType::ARC_COT)) { - auto* arcCot = dynamic_cast(argument); + auto* arcCot = dynamic_cast(argument.get()); return arcCot->getArgument()->simplified(); } diff --git a/cas/src/core/node/trig/Csc.cpp b/cas/src/core/node/trig/Csc.cpp index 3a84037..51cbe99 100644 --- a/cas/src/core/node/trig/Csc.cpp +++ b/cas/src/core/node/trig/Csc.cpp @@ -5,43 +5,43 @@ #include "cas/node/trig/Csc.h" #include "cas/node/Const.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/trig/ArcCsc.h" #include "cas/node/trig/Cot.h" CAS_NAMESPACE -Csc::Csc(Expression* argument) : TrigExpression({ExpressionType::CSC, "cosecant", "csc"}, argument) {} +Csc::Csc(ExprPtr argument) : TrigExpression({ExpressionType::CSC, "cosecant", "csc"}, argument) {} double Csc::evaluate(const VariableMap& variables) { return 1.0 / std::sin(argument->evaluate(variables)); } -Csc* Csc::clone() { - return new Csc(argument->clone()); +ExprPtr Csc::clone() { + return Csc::from(argument->clone()); } -Expression* Csc::_derivative(char variable) { - return new Negate( - new Product({argument->clone()->csc(), - argument->clone()->cot(), - argument->derivative(variable)})); +ExprPtr Csc::_derivative(char variable) { + return Prod::from({argument->clone()->csc(), + argument->clone()->cot(), + argument->derivative(variable)}) + ->negate(); } -Expression* Csc::simplified() { +ExprPtr Csc::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { double value = argument->evaluate(); if (unitCircle.contains(value)) { - Expression* sin = unitCircle.at(value).sin; + ExprPtr sin = unitCircle.at(value).sin; return sin->clone()->reciprocal(); } } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->csc()->negate(); } if (argument->isOfType(ExpressionType::ARC_CSC)) { - auto* arcCsc = dynamic_cast(argument); + auto* arcCsc = dynamic_cast(argument.get()); return arcCsc->getArgument()->simplified(); } diff --git a/cas/src/core/node/trig/InverseTrigExpression.cpp b/cas/src/core/node/trig/InverseTrigExpression.cpp index cb28888..47768c8 100644 --- a/cas/src/core/node/trig/InverseTrigExpression.cpp +++ b/cas/src/core/node/trig/InverseTrigExpression.cpp @@ -7,7 +7,7 @@ CAS_NAMESPACE -InverseTrigExpression::InverseTrigExpression(const ExpressionProperties& props, Expression* argument) +InverseTrigExpression::InverseTrigExpression(const ExpressionProperties& props, ExprPtr argument) : TrigExpression(props, argument) {} std::string InverseTrigExpression::latex() { diff --git a/cas/src/core/node/trig/Sec.cpp b/cas/src/core/node/trig/Sec.cpp index bdeb13a..a79238c 100644 --- a/cas/src/core/node/trig/Sec.cpp +++ b/cas/src/core/node/trig/Sec.cpp @@ -5,41 +5,41 @@ #include "cas/node/trig/Sec.h" #include "cas/node/Const.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/trig/Tan.h" CAS_NAMESPACE -Sec::Sec(Expression* argument) : TrigExpression({ExpressionType::SEC, "secant", "sec"}, argument) {} +Sec::Sec(ExprPtr argument) : TrigExpression({ExpressionType::SEC, "secant", "sec"}, argument) {} double Sec::evaluate(const VariableMap& variables) { return 1.0 / std::cos(argument->evaluate(variables)); } -Sec* Sec::clone() { - return new Sec(argument->clone()); +ExprPtr Sec::clone() { + return Sec::from(argument->clone()); } -Expression* Sec::_derivative(char variable) { - return new Product({argument->clone()->sec(), - argument->clone()->tan(), - argument->derivative(variable)}); +ExprPtr Sec::_derivative(char variable) { + return Prod::from({argument->clone()->sec(), + argument->clone()->tan(), + argument->derivative(variable)}); } -Expression* Sec::simplified() { +ExprPtr Sec::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { double value = argument->evaluate(); if (unitCircle.contains(value)) { - Expression* cos = unitCircle.at(value).cos; + ExprPtr cos = unitCircle.at(value).cos; return cos->clone()->reciprocal(); } } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->sec()->negate(); } if (argument->isOfType(ExpressionType::TAN)) { - auto* tan = dynamic_cast(argument); + auto* tan = dynamic_cast(argument.get()); return tan->getArgument()->simplified()->sec(); } diff --git a/cas/src/core/node/trig/Sin.cpp b/cas/src/core/node/trig/Sin.cpp index 4e24cc1..620e861 100644 --- a/cas/src/core/node/trig/Sin.cpp +++ b/cas/src/core/node/trig/Sin.cpp @@ -5,41 +5,41 @@ #include "cas/node/trig/Sin.h" #include "cas/node/Const.h" #include "cas/node/Negate.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/trig/ArcSin.h" #include "cas/node/trig/Cos.h" CAS_NAMESPACE -Sin::Sin(Expression* argument) : TrigExpression({ExpressionType::SIN, "sinus", "sin"}, argument) {} +Sin::Sin(ExprPtr argument) : TrigExpression({ExpressionType::SIN, "sinus", "sin"}, argument) {} double Sin::evaluate(const VariableMap& variables) { return std::sin(argument->evaluate(variables)); } -Sin* Sin::clone() { - return new Sin(argument->clone()); +ExprPtr Sin::clone() { + return Sin::from(argument->clone()); } -Expression* Sin::_derivative(char variable) { +ExprPtr Sin::_derivative(char variable) { return argument ->clone() ->cos() ->multiply(argument->derivative(variable)); } -Expression* Sin::simplified() { +ExprPtr Sin::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { double value = argument->evaluate(); if (unitCircle.contains(value)) return unitCircle.at(value).sin->clone(); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->sin()->negate(); } if (argument->isOfType(ExpressionType::ARC_SIN)) { - auto* arcSin = dynamic_cast(argument); + auto* arcSin = dynamic_cast(argument.get()); return arcSin->getArgument()->simplified(); } diff --git a/cas/src/core/node/trig/Tan.cpp b/cas/src/core/node/trig/Tan.cpp index 8f8adf5..1d0e2ce 100644 --- a/cas/src/core/node/trig/Tan.cpp +++ b/cas/src/core/node/trig/Tan.cpp @@ -6,41 +6,41 @@ #include "cas/node/Const.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/trig/ArcTan.h" #include "cas/node/trig/Sec.h" CAS_NAMESPACE -Tan::Tan(Expression* argument) : TrigExpression({ExpressionType::TAN, "tangent", "tan"}, argument) {} +Tan::Tan(ExprPtr argument) : TrigExpression({ExpressionType::TAN, "tangent", "tan"}, argument) {} double Tan::evaluate(const VariableMap& variables) { return std::tan(argument->evaluate(variables)); } -Tan* Tan::clone() { - return new Tan(argument->clone()); +ExprPtr Tan::clone() { + return Tan::from(argument->clone()); } -Expression* Tan::_derivative(char variable) { +ExprPtr Tan::_derivative(char variable) { return argument->clone() ->sec() ->power(2) ->multiply(argument->derivative(variable)); } -Expression* Tan::simplified() { +ExprPtr Tan::simplified() { if (argument->isOfType(ExpressionType::CONSTANT)) { double value = argument->evaluate(); if (unitCircle.contains(value)) return unitCircle.at(value).tan->clone(); } if (argument->isOfType(ExpressionType::NEGATE)) { - auto* negate = dynamic_cast(argument); + auto* negate = dynamic_cast(argument.get()); return negate->getArgument()->simplified()->tan()->negate(); } if (argument->isOfType(ExpressionType::ARC_TAN)) { - auto* arcTan = dynamic_cast(argument); + auto* arcTan = dynamic_cast(argument.get()); return arcTan->getArgument()->simplified(); } diff --git a/cas/src/core/node/trig/TrigExpression.cpp b/cas/src/core/node/trig/TrigExpression.cpp index 4d153fa..7e4ad40 100644 --- a/cas/src/core/node/trig/TrigExpression.cpp +++ b/cas/src/core/node/trig/TrigExpression.cpp @@ -34,16 +34,16 @@ const std::unordered_map TrigExpression::unitCircl {math::PI_11_6, {math::PI_11_6, Const::n(3)->sqrt()->divide(2), Const::n(-1)->divide(2), Const::n(-1)->divide(Const::n(3)->sqrt())}}, }; -TrigExpression::TrigExpression(const ExpressionProperties& properties, Expression* argument) +TrigExpression::TrigExpression(const ExpressionProperties& properties, ExprPtr argument) : UnaryExpression(properties, argument) {} -bool TrigExpression::_equals(Expression* other) { - auto* otherTrigFunction = dynamic_cast(other); +bool TrigExpression::_equals(ExprPtr other) { + auto* otherTrigFunction = dynamic_cast(other.get()); return argument->equals(otherTrigFunction->argument); } bool TrigExpression::needsParentheses() { - return instanceof (argument) || instanceof (argument) || argument->isOfType(ExpressionType::POWER) || argument->isOfType(ExpressionType::DIVIDE); + return instanceof (argument.get()) || instanceof (argument.get()) || argument->isOfType(ExpressionType::POWER) || argument->isOfType(ExpressionType::DIVIDE); } std::string TrigExpression::latex() { diff --git a/cas/src/core/plot/Function.cpp b/cas/src/core/plot/Function.cpp index 3322ab1..e70d80d 100644 --- a/cas/src/core/plot/Function.cpp +++ b/cas/src/core/plot/Function.cpp @@ -19,30 +19,25 @@ Function::Function(std::string strFunction, const std::string& name, bool simpli this->expr = parser.parse(strFunction, variables); if (simplify) { - Expression* simplifiedExpr = this->expr->simplified(); - delete this->expr; + ExprPtr simplifiedExpr = this->expr->simplified(); this->expr = simplifiedExpr; } } -Function::Function(const std::string& strFunction, cas::Expression* expr, const cas::VarSet& variables, const std::string& name) +Function::Function(const std::string& strFunction, cas::ExprPtr expr, const cas::VarSet& variables, const std::string& name) : uid(nextId()), strExpr(strFunction), expr(expr), name(name), filename(generateFilename()), variables(variables) {} -Function::~Function() { - delete expr; -} - double Function::evaluate(const VariableMap& vars) { return expr->evaluate(vars); } Function* Function::derivative(char var) { - Expression* pExpression = expr->derivative(var); + ExprPtr pExpression = expr->derivative(var); return new Function(pExpression->text(), pExpression, this->variables, this->name + "_" + var); } Function* Function::simplifiedDerivative(char var) { - Expression* pExpression; + ExprPtr pExpression; try { pExpression = expr->derivative(var); } catch (std::runtime_error& e) { @@ -51,9 +46,8 @@ Function* Function::simplifiedDerivative(char var) { } // Simplify the derivative until it can't be simplified anymore - Expression* simplifiedExpr = pExpression->simplified(); + ExprPtr simplifiedExpr = pExpression->simplified(); while (simplifiedExpr->text() != pExpression->text()) { - delete pExpression; pExpression = simplifiedExpr; simplifiedExpr = pExpression->simplified(); } @@ -62,12 +56,12 @@ Function* Function::simplifiedDerivative(char var) { } Function* Function::simplified() { - Expression* pExpression = expr->simplified(); + ExprPtr pExpression = expr->simplified(); return new Function(pExpression->text(), pExpression, this->variables, this->name + "_s"); } -bool Function::isEquivalent(cas::IMath* expression) { - return expr->isEquivalent(expression); +bool Function::isEquivalent(Function* expression) { + return expr->isEquivalent(expression->expr); } std::string Function::latex() { @@ -98,7 +92,7 @@ const std::string& Function::getStrExpr() const { return strExpr; } -Expression* Function::getExpr() const { +ExprPtr Function::getExpr() const { return expr; } diff --git a/cas/tests/core/data/ExpressionParserTest.cpp b/cas/tests/core/data/ExpressionParserTest.cpp index eb7a3da..49eb368 100644 --- a/cas/tests/core/data/ExpressionParserTest.cpp +++ b/cas/tests/core/data/ExpressionParserTest.cpp @@ -15,7 +15,7 @@ #include "cas/node/Mod.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Round.h" #include "cas/node/Sign.h" #include "cas/node/Sqrt.h" diff --git a/cas/tests/core/node/ArcCscNodeTest.cpp b/cas/tests/core/node/ArcCscNodeTest.cpp index 8d65292..1de4038 100644 --- a/cas/tests/core/node/ArcCscNodeTest.cpp +++ b/cas/tests/core/node/ArcCscNodeTest.cpp @@ -3,7 +3,7 @@ #include "cas/node/Divide.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sqrt.h" #include "cas/node/Sum.h" #include "cas/node/Var.h" diff --git a/cas/tests/core/node/ArcSecNodeTest.cpp b/cas/tests/core/node/ArcSecNodeTest.cpp index 0b91d5f..29cfe0b 100644 --- a/cas/tests/core/node/ArcSecNodeTest.cpp +++ b/cas/tests/core/node/ArcSecNodeTest.cpp @@ -3,7 +3,7 @@ #include "cas/node/Divide.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sqrt.h" #include "cas/node/Sum.h" #include "cas/node/Var.h" diff --git a/cas/tests/core/node/CbrtNodeTest.cpp b/cas/tests/core/node/CbrtNodeTest.cpp index d29d0f2..9bb9d41 100644 --- a/cas/tests/core/node/CbrtNodeTest.cpp +++ b/cas/tests/core/node/CbrtNodeTest.cpp @@ -5,7 +5,7 @@ #include "cas/node/Cbrt.h" #include "cas/node/Const.h" #include "cas/node/Divide.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Var.h" #include "gtest/gtest.h" #include diff --git a/cas/tests/core/node/DivideNodeTest.cpp b/cas/tests/core/node/DivideNodeTest.cpp index 3f9fcba..e63ac45 100644 --- a/cas/tests/core/node/DivideNodeTest.cpp +++ b/cas/tests/core/node/DivideNodeTest.cpp @@ -6,7 +6,7 @@ #include "cas/node/Divide.h" #include "cas/node/Negate.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" #include "cas/node/Var.h" #include "gtest/gtest.h" diff --git a/cas/tests/core/node/ExpNodeTest.cpp b/cas/tests/core/node/ExpNodeTest.cpp index f813166..16d9804 100644 --- a/cas/tests/core/node/ExpNodeTest.cpp +++ b/cas/tests/core/node/ExpNodeTest.cpp @@ -4,7 +4,7 @@ #include "cas/node/Const.h" #include "cas/node/Exp.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Var.h" #include "gtest/gtest.h" diff --git a/cas/tests/core/node/ProductNodeTest.cpp b/cas/tests/core/node/ProductNodeTest.cpp index 9e78006..30fb123 100644 --- a/cas/tests/core/node/ProductNodeTest.cpp +++ b/cas/tests/core/node/ProductNodeTest.cpp @@ -3,7 +3,7 @@ // #include "cas/node/Const.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" #include "cas/node/Var.h" #include "gtest/gtest.h" diff --git a/cas/tests/core/plot/FunctionTest.cpp b/cas/tests/core/plot/FunctionTest.cpp index 6070c07..f6720c2 100644 --- a/cas/tests/core/plot/FunctionTest.cpp +++ b/cas/tests/core/plot/FunctionTest.cpp @@ -5,7 +5,7 @@ #include "cas/plot/Function.h" #include "cas/node/Const.h" #include "cas/node/Power.h" -#include "cas/node/Product.h" +#include "cas/node/Prod.h" #include "cas/node/Sum.h" #include "cas/node/Var.h" #include "gtest/gtest.h" From 35598476681b23e64e686137326f793055f27308 Mon Sep 17 00:00:00 2001 From: Abd-El-Aziz Zayed Date: Thu, 5 Jan 2023 17:45:27 -0500 Subject: [PATCH 2/6] Made all const references --- cas/include/cas/node/Abs.h | 4 +-- cas/include/cas/node/BracketExpression.h | 4 +-- cas/include/cas/node/Cbrt.h | 4 +-- cas/include/cas/node/Ceil.h | 4 +-- cas/include/cas/node/Const.h | 2 +- cas/include/cas/node/Divide.h | 9 ++---- cas/include/cas/node/Exp.h | 4 +-- cas/include/cas/node/Expression.h | 28 +++++++++---------- cas/include/cas/node/Floor.h | 4 +-- cas/include/cas/node/IMath.h | 2 +- cas/include/cas/node/IRepresentableMath.h | 6 ++-- cas/include/cas/node/Ln.h | 6 ++-- cas/include/cas/node/Log.h | 16 +++++------ cas/include/cas/node/Max.h | 2 +- cas/include/cas/node/Min.h | 2 +- cas/include/cas/node/Mod.h | 6 ++-- cas/include/cas/node/NaryExpression.h | 2 +- cas/include/cas/node/Negate.h | 6 ++-- cas/include/cas/node/Operator.h | 4 +-- cas/include/cas/node/Power.h | 10 +++---- cas/include/cas/node/Prod.h | 2 +- cas/include/cas/node/Root.h | 10 +++---- cas/include/cas/node/Round.h | 4 +-- cas/include/cas/node/Sign.h | 6 ++-- cas/include/cas/node/Sqrt.h | 4 +-- cas/include/cas/node/Sum.h | 2 +- cas/include/cas/node/UnaryExpression.h | 2 +- cas/include/cas/node/Var.h | 2 +- cas/include/cas/node/trig/ArcCos.h | 4 +-- cas/include/cas/node/trig/ArcCot.h | 4 +-- cas/include/cas/node/trig/ArcCsc.h | 4 +-- cas/include/cas/node/trig/ArcSec.h | 4 +-- cas/include/cas/node/trig/ArcSin.h | 4 +-- cas/include/cas/node/trig/ArcTan.h | 4 +-- cas/include/cas/node/trig/Cos.h | 4 +-- cas/include/cas/node/trig/Cot.h | 4 +-- cas/include/cas/node/trig/Csc.h | 4 +-- .../cas/node/trig/InverseTrigExpression.h | 2 +- cas/include/cas/node/trig/Sec.h | 4 +-- cas/include/cas/node/trig/Sin.h | 4 +-- cas/include/cas/node/trig/Tan.h | 4 +-- cas/include/cas/node/trig/TrigExpression.h | 4 +-- cas/include/cas/plot/Function.h | 4 +-- cas/src/core/node/Abs.cpp | 2 +- cas/src/core/node/BracketExpression.cpp | 4 +-- cas/src/core/node/Cbrt.cpp | 2 +- cas/src/core/node/Ceil.cpp | 2 +- cas/src/core/node/Const.cpp | 2 +- cas/src/core/node/Divide.cpp | 4 +-- cas/src/core/node/Exp.cpp | 2 +- cas/src/core/node/Expression.cpp | 28 +++++++++---------- cas/src/core/node/Floor.cpp | 2 +- cas/src/core/node/Ln.cpp | 4 +-- cas/src/core/node/Log.cpp | 10 +++---- cas/src/core/node/Max.cpp | 8 +++--- cas/src/core/node/Min.cpp | 8 +++--- cas/src/core/node/Mod.cpp | 4 +-- cas/src/core/node/NaryExpression.cpp | 2 +- cas/src/core/node/Negate.cpp | 4 +-- cas/src/core/node/Operator.cpp | 2 +- cas/src/core/node/Power.cpp | 8 +++--- cas/src/core/node/Product.cpp | 4 +-- cas/src/core/node/Root.cpp | 6 ++-- cas/src/core/node/Round.cpp | 2 +- cas/src/core/node/Sign.cpp | 4 +-- cas/src/core/node/Sqrt.cpp | 2 +- cas/src/core/node/UnaryExpression.cpp | 2 +- cas/src/core/node/Var.cpp | 2 +- cas/src/core/node/trig/ArcCos.cpp | 2 +- cas/src/core/node/trig/ArcCot.cpp | 2 +- cas/src/core/node/trig/ArcCsc.cpp | 2 +- cas/src/core/node/trig/ArcSec.cpp | 2 +- cas/src/core/node/trig/ArcSin.cpp | 2 +- cas/src/core/node/trig/ArcTan.cpp | 2 +- cas/src/core/node/trig/Cos.cpp | 2 +- cas/src/core/node/trig/Cot.cpp | 2 +- cas/src/core/node/trig/Csc.cpp | 2 +- .../core/node/trig/InverseTrigExpression.cpp | 2 +- cas/src/core/node/trig/Sec.cpp | 2 +- cas/src/core/node/trig/Sin.cpp | 2 +- cas/src/core/node/trig/Tan.cpp | 2 +- cas/src/core/node/trig/TrigExpression.cpp | 4 +-- cas/src/core/plot/Function.cpp | 4 +-- 83 files changed, 183 insertions(+), 186 deletions(-) diff --git a/cas/include/cas/node/Abs.h b/cas/include/cas/node/Abs.h index 582b20e..45ad325 100644 --- a/cas/include/cas/node/Abs.h +++ b/cas/include/cas/node/Abs.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Abs : public BracketExpression { public: - explicit Abs(ExprPtr argument); + explicit Abs(const ExprPtr& argument); Abs() = delete; @@ -25,7 +25,7 @@ class Abs : public BracketExpression { std::string text() override; - static ExprPtr from(ExprPtr argument) { + static ExprPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; diff --git a/cas/include/cas/node/BracketExpression.h b/cas/include/cas/node/BracketExpression.h index c28a999..31bf23d 100644 --- a/cas/include/cas/node/BracketExpression.h +++ b/cas/include/cas/node/BracketExpression.h @@ -15,7 +15,7 @@ class BracketExpression : public UnaryExpression { ~BracketExpression() override = default; - bool _equals(ExprPtr other) override; + bool _equals(const ExprPtr& other) override; ExprPtr derivative(char var) override; @@ -28,7 +28,7 @@ class BracketExpression : public UnaryExpression { std::string explicitText() override; protected: - explicit BracketExpression(const ExpressionProperties& properties, ExprPtr argument, + explicit BracketExpression(const ExpressionProperties& properties, const ExprPtr& argument, const wchar_t* openBracket, const wchar_t* closeBracket, const char* openBracketLatex, const char* closeBracketLatex); diff --git a/cas/include/cas/node/Cbrt.h b/cas/include/cas/node/Cbrt.h index 80576b8..428edb1 100644 --- a/cas/include/cas/node/Cbrt.h +++ b/cas/include/cas/node/Cbrt.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Cbrt : public Root { public: - explicit Cbrt(ExprPtr base); + explicit Cbrt(const ExprPtr& base); Cbrt() = delete; ~Cbrt() override = default; @@ -25,7 +25,7 @@ class Cbrt : public Root { std::string text() override; std::string explicitText() override; - static CbrtPtr from(ExprPtr base) { return std::make_shared(base); } + static CbrtPtr from(const ExprPtr& base) { return std::make_shared(base); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Ceil.h b/cas/include/cas/node/Ceil.h index a3965bf..373b1bc 100644 --- a/cas/include/cas/node/Ceil.h +++ b/cas/include/cas/node/Ceil.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Ceil : public BracketExpression { public: - explicit Ceil(ExprPtr argument); + explicit Ceil(const ExprPtr& argument); Ceil() = delete; @@ -23,7 +23,7 @@ class Ceil : public BracketExpression { ExprPtr simplified() override; - static ExprPtr from(ExprPtr argument) { + static ExprPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; diff --git a/cas/include/cas/node/Const.h b/cas/include/cas/node/Const.h index ed631f9..dba04af 100644 --- a/cas/include/cas/node/Const.h +++ b/cas/include/cas/node/Const.h @@ -18,7 +18,7 @@ class Const : public Expr { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; diff --git a/cas/include/cas/node/Divide.h b/cas/include/cas/node/Divide.h index bcfc3ed..8f19102 100644 --- a/cas/include/cas/node/Divide.h +++ b/cas/include/cas/node/Divide.h @@ -13,13 +13,13 @@ CAS_NAMESPACE class Divide : public Expr { public: Divide() = delete; - explicit Divide(ExprPtr dividend, ExprPtr divisor); + explicit Divide(const ExprPtr& dividend, const ExprPtr& divisor); ~Divide() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; @@ -35,14 +35,11 @@ class Divide : public Expr { std::string explicitText() override; - static DividePtr from(ExprPtr dividend, ExprPtr divisor) { return std::make_shared(dividend, divisor); } + static DividePtr from(const ExprPtr& dividend, const ExprPtr& divisor) { return std::make_shared(dividend, divisor); } ExprPtr getDividend() const { return dividend; } ExprPtr getDivisor() const { return divisor; } -private: - void setParents(); - private: ExprPtr dividend; ExprPtr divisor; diff --git a/cas/include/cas/node/Exp.h b/cas/include/cas/node/Exp.h index 887b5db..20eef79 100644 --- a/cas/include/cas/node/Exp.h +++ b/cas/include/cas/node/Exp.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Exp : public Power { public: - explicit Exp(ExprPtr exponent); + explicit Exp(const ExprPtr& exponent); Exp() = delete; @@ -27,7 +27,7 @@ class Exp : public Power { std::string explicitText() override; - static ExpPtr from(ExprPtr exponent) { return std::make_shared(exponent); } + static ExpPtr from(const ExprPtr& exponent) { return std::make_shared(exponent); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Expression.h b/cas/include/cas/node/Expression.h index c6a59cd..9e68620 100644 --- a/cas/include/cas/node/Expression.h +++ b/cas/include/cas/node/Expression.h @@ -100,8 +100,8 @@ class Expr : public IMath, public IRepresentableMath, public std::enabl double evaluate(const VariableMap& variables) override; virtual double evaluate(); - virtual bool equals(ExprPtr expression); - virtual bool _equals(ExprPtr expression); + virtual bool equals(const ExprPtr& expression); + virtual bool _equals(const ExprPtr& expression); virtual ExprPtr clone(); @@ -109,26 +109,26 @@ class Expr : public IMath, public IRepresentableMath, public std::enabl virtual ExprPtr _derivative(char var); ExprPtr simplified() override; - bool isEquivalent(ExprPtr expression) override; + bool isEquivalent(const ExprPtr& expression) override; - ProdPtr multiply(ExprPtr expression); + ProdPtr multiply(const ExprPtr& expression); ProdPtr multiply(double value); - SumPtr add(ExprPtr expression); - SumPtr subtract(ExprPtr expression); + SumPtr add(const ExprPtr& expression); + SumPtr subtract(const ExprPtr& expression); SumPtr add(double value); SumPtr subtract(double value); - DividePtr divide(ExprPtr expression); + DividePtr divide(const ExprPtr& expression); DividePtr divide(double divisor); NegatePtr negate(); - PowerPtr power(ExprPtr expression); + PowerPtr power(const ExprPtr& expression); PowerPtr power(double exponent); ExpPtr exp(); - LogPtr log(ExprPtr base); + LogPtr log(const ExprPtr& base); LogPtr log(double base); LnPtr ln(); - RootPtr root(ExprPtr root); + RootPtr root(const ExprPtr& root); RootPtr root(double root); SqrtPtr sqrt(); CbrtPtr cbrt(); @@ -151,15 +151,15 @@ class Expr : public IMath, public IRepresentableMath, public std::enabl CeilPtr ceil(); RoundPtr round(); SignPtr sign(); - ModPtr mod(ExprPtr expression); + ModPtr mod(const ExprPtr& expression); ExprPtr reciprocal(); bool operator<(const Expr& expression) const; - bool lessThan(ExprPtr expression) const; + bool lessThan(const ExprPtr& expression) const; - static bool compare(ExprPtr left, ExprPtr right); + static bool compare(const ExprPtr& left, const ExprPtr& right); ExpressionProperties getProperties() const; @@ -171,7 +171,7 @@ class Expr : public IMath, public IRepresentableMath, public std::enabl bool isOfType(ExpressionType type) const; - bool isOfSameType(ExprPtr expression) const; + bool isOfSameType(const ExprPtr& expression) const; // TODO overload math operators + - * / ^ diff --git a/cas/include/cas/node/Floor.h b/cas/include/cas/node/Floor.h index 2885632..5368c0c 100644 --- a/cas/include/cas/node/Floor.h +++ b/cas/include/cas/node/Floor.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Floor : public BracketExpression { public: - explicit Floor(ExprPtr argument); + explicit Floor(const ExprPtr& argument); Floor() = delete; @@ -23,7 +23,7 @@ class Floor : public BracketExpression { ExprPtr simplified() override; - static FloorPtr from(ExprPtr argument) { return std::make_shared(argument); } + static FloorPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/IMath.h b/cas/include/cas/node/IMath.h index 6d2e2c3..19c8a97 100644 --- a/cas/include/cas/node/IMath.h +++ b/cas/include/cas/node/IMath.h @@ -17,7 +17,7 @@ class IMath { virtual double evaluate(const VariableMap& variables) = 0; virtual E derivative(char var) = 0; virtual E simplified() = 0; - virtual bool isEquivalent(E expr) = 0; + virtual bool isEquivalent(const E& expr) = 0; }; namespace math { diff --git a/cas/include/cas/node/IRepresentableMath.h b/cas/include/cas/node/IRepresentableMath.h index 0530f00..94dd313 100644 --- a/cas/include/cas/node/IRepresentableMath.h +++ b/cas/include/cas/node/IRepresentableMath.h @@ -2,8 +2,8 @@ // Created by Abd-El-Aziz Zayed on 2022-08-27. // -#ifndef CAS_I_REPRESENTABLE_MATH__H -#define CAS_I_REPRESENTABLE_MATH__H +#ifndef CAS_INTERFACE_REPRESENTABLE_MATH_H +#define CAS_INTERFACE_REPRESENTABLE_MATH_H #include "cas/CAS.h" #include @@ -20,4 +20,4 @@ class IRepresentableMath { CAS_NAMESPACE_END -#endif//CAS_I_REPRESENTABLE_MATH__H +#endif//CAS_INTERFACE_REPRESENTABLE_MATH_H diff --git a/cas/include/cas/node/Ln.h b/cas/include/cas/node/Ln.h index 5dfc245..8914573 100644 --- a/cas/include/cas/node/Ln.h +++ b/cas/include/cas/node/Ln.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Ln : public Log { public: - explicit Ln(ExprPtr argument); + explicit Ln(const ExprPtr& argument); Ln() = delete; @@ -19,7 +19,7 @@ class Ln : public Log { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; @@ -35,7 +35,7 @@ class Ln : public Log { std::string explicitText() override; - static LnPtr from(ExprPtr argument) { return std::make_shared(argument); } + static LnPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Log.h b/cas/include/cas/node/Log.h index 60c393d..b6635aa 100644 --- a/cas/include/cas/node/Log.h +++ b/cas/include/cas/node/Log.h @@ -11,11 +11,11 @@ CAS_NAMESPACE class Log : public Expr { public: - explicit Log(ExprPtr base, ExprPtr argument); + explicit Log(const ExprPtr& base, const ExprPtr& argument); - explicit Log(double base, ExprPtr argument); + explicit Log(double base, const ExprPtr& argument); - explicit Log(ExprPtr argument); + explicit Log(const ExprPtr& argument); Log() = delete; @@ -23,7 +23,7 @@ class Log : public Expr { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; @@ -43,12 +43,12 @@ class Log : public Expr { ExprPtr getArgument() const { return argument; } - static LogPtr from(ExprPtr base, ExprPtr argument) { return std::make_shared(base, argument); } - static LogPtr from(double base, ExprPtr argument) { return std::make_shared(base, argument); } - static LogPtr from(ExprPtr argument) { return std::make_shared(argument); } + static LogPtr from(const ExprPtr& base, const ExprPtr& argument) { return std::make_shared(base, argument); } + static LogPtr from(double base, const ExprPtr& argument) { return std::make_shared(base, argument); } + static LogPtr from(const ExprPtr& argument) { return std::make_shared(argument); } protected: - explicit Log(const ExpressionProperties& props, ExprPtr base, ExprPtr argument); + explicit Log(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& argument); bool argumentNeedsParentheses(); diff --git a/cas/include/cas/node/Max.h b/cas/include/cas/node/Max.h index d70b769..9fb0efb 100644 --- a/cas/include/cas/node/Max.h +++ b/cas/include/cas/node/Max.h @@ -23,7 +23,7 @@ class Max : public NaryExpression { ExprPtr simplified() override; - static MaxPtr from(std::vector expressions) { return std::make_shared(expressions); } + static MaxPtr from(const std::vector& expressions) { return std::make_shared(expressions); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Min.h b/cas/include/cas/node/Min.h index 3893d5b..2830a2d 100644 --- a/cas/include/cas/node/Min.h +++ b/cas/include/cas/node/Min.h @@ -23,7 +23,7 @@ class Min : public NaryExpression { ExprPtr simplified() override; - static MinPtr from(std::vector expressions) { return std::make_shared(expressions); } + static MinPtr from(const std::vector& expressions) { return std::make_shared(expressions); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Mod.h b/cas/include/cas/node/Mod.h index 07fa95a..6ff63cc 100644 --- a/cas/include/cas/node/Mod.h +++ b/cas/include/cas/node/Mod.h @@ -11,12 +11,12 @@ CAS_NAMESPACE class Mod : public Expr { public: - explicit Mod(ExprPtr dividend, ExprPtr divisor); + explicit Mod(const ExprPtr& dividend, const ExprPtr& divisor); Mod() = delete; ~Mod() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; ExprPtr simplified() override; @@ -28,7 +28,7 @@ class Mod : public Expr { ExprPtr getDividend() const { return dividend; } ExprPtr getDivisor() const { return divisor; } - static ModPtr from(ExprPtr dividend, ExprPtr divisor) { return std::make_shared(dividend, divisor); } + static ModPtr from(const ExprPtr& dividend, const ExprPtr& divisor) { return std::make_shared(dividend, divisor); } private: ExprPtr dividend; diff --git a/cas/include/cas/node/NaryExpression.h b/cas/include/cas/node/NaryExpression.h index 678c276..13213ad 100644 --- a/cas/include/cas/node/NaryExpression.h +++ b/cas/include/cas/node/NaryExpression.h @@ -16,7 +16,7 @@ class NaryExpression : public Expr { ~NaryExpression() override = default; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; std::string latex() override; diff --git a/cas/include/cas/node/Negate.h b/cas/include/cas/node/Negate.h index ed8dbdc..b198f8f 100644 --- a/cas/include/cas/node/Negate.h +++ b/cas/include/cas/node/Negate.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Negate : public UnaryExpression { public: - explicit Negate(ExprPtr expression); + explicit Negate(const ExprPtr& expression); Negate() = delete; @@ -19,7 +19,7 @@ class Negate : public UnaryExpression { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; @@ -35,7 +35,7 @@ class Negate : public UnaryExpression { std::string explicitText() override; - static NegatePtr from(ExprPtr expression) { return std::make_shared(expression); } + static NegatePtr from(const ExprPtr& expression) { return std::make_shared(expression); } protected: bool needsParentheses(); diff --git a/cas/include/cas/node/Operator.h b/cas/include/cas/node/Operator.h index e92f4e9..d75a366 100644 --- a/cas/include/cas/node/Operator.h +++ b/cas/include/cas/node/Operator.h @@ -20,7 +20,7 @@ class Operator : public Expr { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; std::string text() override; @@ -34,7 +34,7 @@ class Operator : public Expr { protected: virtual double operate(double a, double b) = 0; - virtual bool needsParentheses(ExprPtr expression) = 0; + virtual bool needsParentheses(const ExprPtr& expression) = 0; protected: const double neutral; diff --git a/cas/include/cas/node/Power.h b/cas/include/cas/node/Power.h index 5819b36..f92ff18 100644 --- a/cas/include/cas/node/Power.h +++ b/cas/include/cas/node/Power.h @@ -11,9 +11,9 @@ CAS_NAMESPACE class Power : public Expr { public: - explicit Power(ExprPtr base, ExprPtr exponent); + explicit Power(const ExprPtr& base, const ExprPtr& exponent); - explicit Power(ExprPtr base, double exponent); + explicit Power(const ExprPtr& base, double exponent); Power() = delete; @@ -21,7 +21,7 @@ class Power : public Expr { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; @@ -41,10 +41,10 @@ class Power : public Expr { ExprPtr getExponent() const { return exponent; } - static PowerPtr from(ExprPtr base, ExprPtr exponent) { return std::make_shared(base, exponent); } + static PowerPtr from(const ExprPtr& base, const ExprPtr& exponent) { return std::make_shared(base, exponent); } protected: - explicit Power(const ExpressionProperties& props, ExprPtr base, ExprPtr exponent); + explicit Power(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& exponent); bool baseNeedsParentheses(); diff --git a/cas/include/cas/node/Prod.h b/cas/include/cas/node/Prod.h index b4a642e..8e8633a 100644 --- a/cas/include/cas/node/Prod.h +++ b/cas/include/cas/node/Prod.h @@ -32,7 +32,7 @@ class Prod : public Operator { protected: double operate(double a, double b) override { return a * b; }; - bool needsParentheses(ExprPtr expression) override; + bool needsParentheses(const ExprPtr& expression) override; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Root.h b/cas/include/cas/node/Root.h index 37714ae..9503a3a 100644 --- a/cas/include/cas/node/Root.h +++ b/cas/include/cas/node/Root.h @@ -11,9 +11,9 @@ CAS_NAMESPACE class Root : public Power { public: - explicit Root(const ExpressionProperties& props, ExprPtr base, ExprPtr root); - explicit Root(ExprPtr base, ExprPtr root); - explicit Root(ExprPtr base, double root); + explicit Root(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& root); + explicit Root(const ExprPtr& base, const ExprPtr& root); + explicit Root(const ExprPtr& base, double root); Root() = delete; ~Root() override = default; @@ -28,8 +28,8 @@ class Root : public Power { ExprPtr getRoot() const { return getExponent(); } - static RootPtr from(ExprPtr base, ExprPtr root) { return std::make_shared(base, root); } - static RootPtr from(ExprPtr base, double root) { return std::make_shared(base, root); } + static RootPtr from(const ExprPtr& base, const ExprPtr& root) { return std::make_shared(base, root); } + static RootPtr from(const ExprPtr& base, double root) { return std::make_shared(base, root); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Round.h b/cas/include/cas/node/Round.h index 7d8fc5f..87d911e 100644 --- a/cas/include/cas/node/Round.h +++ b/cas/include/cas/node/Round.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Round : public BracketExpression { public: - explicit Round(ExprPtr argument); + explicit Round(const ExprPtr& argument); Round() = delete; @@ -23,7 +23,7 @@ class Round : public BracketExpression { ExprPtr simplified() override; - static RoundPtr from(ExprPtr argument) { return std::make_shared(argument); } + static RoundPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Sign.h b/cas/include/cas/node/Sign.h index 09af4dd..b5729b1 100644 --- a/cas/include/cas/node/Sign.h +++ b/cas/include/cas/node/Sign.h @@ -11,13 +11,13 @@ CAS_NAMESPACE class Sign : public UnaryExpression { public: - explicit Sign(ExprPtr argument); + explicit Sign(const ExprPtr& argument); Sign() = delete; ~Sign() override = default; double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; @@ -25,7 +25,7 @@ class Sign : public UnaryExpression { std::string latex() override; - static SignPtr from(ExprPtr argument) { return std::make_shared(argument); } + static SignPtr from(const ExprPtr& argument) { return std::make_shared(argument); } private: bool needsParentheses(); diff --git a/cas/include/cas/node/Sqrt.h b/cas/include/cas/node/Sqrt.h index c9b5ccf..e99189c 100644 --- a/cas/include/cas/node/Sqrt.h +++ b/cas/include/cas/node/Sqrt.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Sqrt : public Root { public: - explicit Sqrt(ExprPtr base); + explicit Sqrt(const ExprPtr& base); Sqrt() = delete; ~Sqrt() override = default; @@ -25,7 +25,7 @@ class Sqrt : public Root { std::string text() override; std::string explicitText() override; - static SqrtPtr from(ExprPtr base) { return std::make_shared(base); } + static SqrtPtr from(const ExprPtr& base) { return std::make_shared(base); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Sum.h b/cas/include/cas/node/Sum.h index 21911ea..8ca3e52 100644 --- a/cas/include/cas/node/Sum.h +++ b/cas/include/cas/node/Sum.h @@ -32,7 +32,7 @@ class Sum : public Operator { protected: double operate(double a, double b) override { return a + b; }; - bool needsParentheses(ExprPtr) override { return false; }; + bool needsParentheses(const ExprPtr&) override { return false; }; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/UnaryExpression.h b/cas/include/cas/node/UnaryExpression.h index 277398d..b6e1a86 100644 --- a/cas/include/cas/node/UnaryExpression.h +++ b/cas/include/cas/node/UnaryExpression.h @@ -28,7 +28,7 @@ class UnaryExpression : public Expr { std::string explicitText() override; protected: - explicit UnaryExpression(const ExpressionProperties& properties, ExprPtr argument); + explicit UnaryExpression(const ExpressionProperties& properties, const ExprPtr& argument); protected: ExprPtr argument; diff --git a/cas/include/cas/node/Var.h b/cas/include/cas/node/Var.h index b5741cc..51523a8 100644 --- a/cas/include/cas/node/Var.h +++ b/cas/include/cas/node/Var.h @@ -17,7 +17,7 @@ class Var : public Expr { double evaluate(const VariableMap& variables) override; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; ExprPtr clone() override; diff --git a/cas/include/cas/node/trig/ArcCos.h b/cas/include/cas/node/trig/ArcCos.h index aae6f77..a1b7d0a 100644 --- a/cas/include/cas/node/trig/ArcCos.h +++ b/cas/include/cas/node/trig/ArcCos.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class ArcCos : public InverseTrigExpression { public: - explicit ArcCos(ExprPtr argument); + explicit ArcCos(const ExprPtr& argument); ArcCos() = delete; ~ArcCos() override = default; @@ -20,7 +20,7 @@ class ArcCos : public InverseTrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static ArcCosPtr from(ExprPtr argument) { return std::make_shared(argument); } + static ArcCosPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcCot.h b/cas/include/cas/node/trig/ArcCot.h index e35e525..4ac098d 100644 --- a/cas/include/cas/node/trig/ArcCot.h +++ b/cas/include/cas/node/trig/ArcCot.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class ArcCot : public InverseTrigExpression { public: - explicit ArcCot(ExprPtr argument); + explicit ArcCot(const ExprPtr& argument); ArcCot() = delete; ~ArcCot() override = default; @@ -20,7 +20,7 @@ class ArcCot : public InverseTrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static ArcCotPtr from(ExprPtr argument) { return std::make_shared(argument); } + static ArcCotPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcCsc.h b/cas/include/cas/node/trig/ArcCsc.h index c82562f..e33f2d1 100644 --- a/cas/include/cas/node/trig/ArcCsc.h +++ b/cas/include/cas/node/trig/ArcCsc.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class ArcCsc : public InverseTrigExpression { public: - explicit ArcCsc(ExprPtr argument); + explicit ArcCsc(const ExprPtr& argument); ArcCsc() = delete; ~ArcCsc() override = default; @@ -20,7 +20,7 @@ class ArcCsc : public InverseTrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static ArcCscPtr from(ExprPtr argument) { return std::make_shared(argument); } + static ArcCscPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcSec.h b/cas/include/cas/node/trig/ArcSec.h index 7e85a56..5ff00d1 100644 --- a/cas/include/cas/node/trig/ArcSec.h +++ b/cas/include/cas/node/trig/ArcSec.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class ArcSec : public InverseTrigExpression { public: - explicit ArcSec(ExprPtr argument); + explicit ArcSec(const ExprPtr& argument); ArcSec() = delete; ~ArcSec() override = default; @@ -20,7 +20,7 @@ class ArcSec : public InverseTrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static ArcSecPtr from(ExprPtr argument) { return std::make_shared(argument); } + static ArcSecPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcSin.h b/cas/include/cas/node/trig/ArcSin.h index 4569f16..0b5b9bb 100644 --- a/cas/include/cas/node/trig/ArcSin.h +++ b/cas/include/cas/node/trig/ArcSin.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class ArcSin : public InverseTrigExpression { public: - explicit ArcSin(ExprPtr argument); + explicit ArcSin(const ExprPtr& argument); ArcSin() = delete; ~ArcSin() override = default; @@ -20,7 +20,7 @@ class ArcSin : public InverseTrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static ArcSinPtr from(ExprPtr argument) { return std::make_shared(argument); } + static ArcSinPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/ArcTan.h b/cas/include/cas/node/trig/ArcTan.h index 61a058d..bc0e105 100644 --- a/cas/include/cas/node/trig/ArcTan.h +++ b/cas/include/cas/node/trig/ArcTan.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class ArcTan : public InverseTrigExpression { public: - explicit ArcTan(ExprPtr argument); + explicit ArcTan(const ExprPtr& argument); ArcTan() = delete; ~ArcTan() override = default; @@ -20,7 +20,7 @@ class ArcTan : public InverseTrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static ArcTanPtr from(ExprPtr argument) { return std::make_shared(argument); } + static ArcTanPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Cos.h b/cas/include/cas/node/trig/Cos.h index 62da892..a7f7004 100644 --- a/cas/include/cas/node/trig/Cos.h +++ b/cas/include/cas/node/trig/Cos.h @@ -12,7 +12,7 @@ CAS_NAMESPACE class Cos : public TrigExpression { public: - explicit Cos(ExprPtr argument); + explicit Cos(const ExprPtr& argument); Cos() = delete; ~Cos() override = default; @@ -21,7 +21,7 @@ class Cos : public TrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static CosPtr from(ExprPtr argument) { return std::make_shared(argument); } + static CosPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Cot.h b/cas/include/cas/node/trig/Cot.h index 74fcc46..489c651 100644 --- a/cas/include/cas/node/trig/Cot.h +++ b/cas/include/cas/node/trig/Cot.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Cot : public TrigExpression { public: - explicit Cot(ExprPtr argument); + explicit Cot(const ExprPtr& argument); Cot() = delete; ~Cot() override = default; @@ -20,7 +20,7 @@ class Cot : public TrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static CotPtr from(ExprPtr argument) { return std::make_shared(argument); } + static CotPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Csc.h b/cas/include/cas/node/trig/Csc.h index 6fb9a73..93063b4 100644 --- a/cas/include/cas/node/trig/Csc.h +++ b/cas/include/cas/node/trig/Csc.h @@ -11,7 +11,7 @@ CAS_NAMESPACE class Csc : public TrigExpression { public: - explicit Csc(ExprPtr argument); + explicit Csc(const ExprPtr& argument); Csc() = delete; ~Csc() override = default; @@ -20,7 +20,7 @@ class Csc : public TrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static CscPtr from(ExprPtr argument) { return std::make_shared(argument); } + static CscPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/InverseTrigExpression.h b/cas/include/cas/node/trig/InverseTrigExpression.h index 066de80..ee57a16 100644 --- a/cas/include/cas/node/trig/InverseTrigExpression.h +++ b/cas/include/cas/node/trig/InverseTrigExpression.h @@ -17,7 +17,7 @@ class InverseTrigExpression : public TrigExpression { std::string latex() override; protected: - explicit InverseTrigExpression(const ExpressionProperties& props, ExprPtr argument); + explicit InverseTrigExpression(const ExpressionProperties& props, const ExprPtr& argument); }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Sec.h b/cas/include/cas/node/trig/Sec.h index 1405eb8..eb723d6 100644 --- a/cas/include/cas/node/trig/Sec.h +++ b/cas/include/cas/node/trig/Sec.h @@ -12,7 +12,7 @@ CAS_NAMESPACE class Sec : public TrigExpression { public: - explicit Sec(ExprPtr argument); + explicit Sec(const ExprPtr& argument); Sec() = delete; ~Sec() override = default; @@ -21,7 +21,7 @@ class Sec : public TrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static SecPtr from(ExprPtr argument) { return std::make_shared(argument); } + static SecPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Sin.h b/cas/include/cas/node/trig/Sin.h index 1f8ccf0..21a8505 100644 --- a/cas/include/cas/node/trig/Sin.h +++ b/cas/include/cas/node/trig/Sin.h @@ -12,7 +12,7 @@ CAS_NAMESPACE class Sin : public TrigExpression { public: - explicit Sin(ExprPtr argument); + explicit Sin(const ExprPtr& argument); Sin() = delete; ~Sin() override = default; @@ -21,7 +21,7 @@ class Sin : public TrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static SinPtr from(ExprPtr argument) { return std::make_shared(argument); } + static SinPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/Tan.h b/cas/include/cas/node/trig/Tan.h index d4b597a..1a4ea60 100644 --- a/cas/include/cas/node/trig/Tan.h +++ b/cas/include/cas/node/trig/Tan.h @@ -12,7 +12,7 @@ CAS_NAMESPACE class Tan : public TrigExpression { public: - explicit Tan(ExprPtr argument); + explicit Tan(const ExprPtr& argument); Tan() = delete; ~Tan() override = default; @@ -21,7 +21,7 @@ class Tan : public TrigExpression { ExprPtr _derivative(char variable) override; ExprPtr simplified() override; - static TanPtr from(ExprPtr argument) { return std::make_shared(argument); } + static TanPtr from(const ExprPtr& argument) { return std::make_shared(argument); } }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/trig/TrigExpression.h b/cas/include/cas/node/trig/TrigExpression.h index 02b401f..059126a 100644 --- a/cas/include/cas/node/trig/TrigExpression.h +++ b/cas/include/cas/node/trig/TrigExpression.h @@ -23,7 +23,7 @@ class TrigExpression : public UnaryExpression { TrigExpression() = delete; ~TrigExpression() override = default; - bool _equals(ExprPtr expression) override; + bool _equals(const ExprPtr& expression) override; std::string latex() override; std::wstring stringify() override; @@ -32,7 +32,7 @@ class TrigExpression : public UnaryExpression { static const std::unordered_map unitCircle; protected: - explicit TrigExpression(const ExpressionProperties& props, ExprPtr argument); + explicit TrigExpression(const ExpressionProperties& props, const ExprPtr& argument); bool needsParentheses(); }; diff --git a/cas/include/cas/plot/Function.h b/cas/include/cas/plot/Function.h index d54c612..0c94d05 100644 --- a/cas/include/cas/plot/Function.h +++ b/cas/include/cas/plot/Function.h @@ -18,7 +18,7 @@ class Function : public IMath, public IRepresentableMath { Function* derivative(char var) override; Function* simplifiedDerivative(char var); Function* simplified() override; - bool isEquivalent(Function* expression) override; + bool isEquivalent(Function* const & expression) override; std::string latex() override; std::wstring stringify() override; @@ -35,7 +35,7 @@ class Function : public IMath, public IRepresentableMath { const VarSet& getVariables() const; protected: - explicit Function(const std::string& strFunction, ExprPtr expr, const VarSet& variables, const std::string& name = "z"); + explicit Function(const std::string& strFunction, const ExprPtr& expr, const VarSet& variables, const std::string& name = "z"); private: const size_t uid; diff --git a/cas/src/core/node/Abs.cpp b/cas/src/core/node/Abs.cpp index 34953d9..ac720fb 100644 --- a/cas/src/core/node/Abs.cpp +++ b/cas/src/core/node/Abs.cpp @@ -9,7 +9,7 @@ CAS_NAMESPACE -Abs::Abs(ExprPtr argument) +Abs::Abs(const ExprPtr& argument) : BracketExpression({ExpressionType::ABSOLUTE_VALUE, "absolute_value", "abs"}, argument, L"|", L"|", "\\left|", "\\right|") {} double Abs::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/BracketExpression.cpp b/cas/src/core/node/BracketExpression.cpp index d15be58..6e18c0b 100644 --- a/cas/src/core/node/BracketExpression.cpp +++ b/cas/src/core/node/BracketExpression.cpp @@ -8,14 +8,14 @@ CAS_NAMESPACE -BracketExpression::BracketExpression(const ExpressionProperties& properties, ExprPtr argument, +BracketExpression::BracketExpression(const ExpressionProperties& properties, const ExprPtr& argument, const wchar_t* openBracket, const wchar_t* closeBracket, const char* openBracketLatex, const char* closeBracketLatex) : UnaryExpression(properties, argument), openBracket(openBracket), closeBracket(closeBracket), openBracketLatex(openBracketLatex), closeBracketLatex(closeBracketLatex) {} -bool BracketExpression::_equals(ExprPtr other) { +bool BracketExpression::_equals(const ExprPtr& other) { auto* otherBracketFunction = dynamic_cast(other.get()); return argument->equals(otherBracketFunction->argument); } diff --git a/cas/src/core/node/Cbrt.cpp b/cas/src/core/node/Cbrt.cpp index 9e3fd84..76e5eab 100644 --- a/cas/src/core/node/Cbrt.cpp +++ b/cas/src/core/node/Cbrt.cpp @@ -12,7 +12,7 @@ CAS_NAMESPACE -Cbrt::Cbrt(ExprPtr base) +Cbrt::Cbrt(const ExprPtr& base) : Root({ExpressionType::CUBE_ROOT, "cube_root", "cbrt"}, base, Const::n(3)) {} double Cbrt::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/Ceil.cpp b/cas/src/core/node/Ceil.cpp index 1a7ecbd..4602695 100644 --- a/cas/src/core/node/Ceil.cpp +++ b/cas/src/core/node/Ceil.cpp @@ -9,7 +9,7 @@ CAS_NAMESPACE -Ceil::Ceil(ExprPtr argument) +Ceil::Ceil(const ExprPtr& argument) : BracketExpression({ExpressionType::CEIL, "ceiling", "ceil"}, argument, L"\u2308", L"\u2309", "\\lceil", "\\rceil") {} diff --git a/cas/src/core/node/Const.cpp b/cas/src/core/node/Const.cpp index ec9c3b5..85a51c5 100644 --- a/cas/src/core/node/Const.cpp +++ b/cas/src/core/node/Const.cpp @@ -26,7 +26,7 @@ double Const::evaluate(const VariableMap&) { return value; } -bool Const::_equals(ExprPtr expression) { +bool Const::_equals(const ExprPtr& expression) { return floatingsEqual(value, expression->evaluate()); } diff --git a/cas/src/core/node/Divide.cpp b/cas/src/core/node/Divide.cpp index 99bb02f..59057bf 100644 --- a/cas/src/core/node/Divide.cpp +++ b/cas/src/core/node/Divide.cpp @@ -13,7 +13,7 @@ CAS_NAMESPACE -Divide::Divide(ExprPtr dividend, ExprPtr divisor) +Divide::Divide(const ExprPtr& dividend, const ExprPtr& divisor) : Expr({ExpressionType::DIVIDE, "divide", "div"}), dividend(dividend), divisor(divisor) { dividend->setParent(this); divisor->setParent(this); @@ -23,7 +23,7 @@ double Divide::evaluate(const VariableMap& variables) { return dividend->evaluate(variables) / divisor->evaluate(variables); } -bool Divide::_equals(ExprPtr expression) { +bool Divide::_equals(const ExprPtr& expression) { auto* divide = dynamic_cast(expression.get()); return dividend->equals(divide->dividend) && divisor->equals(divide->divisor); } diff --git a/cas/src/core/node/Exp.cpp b/cas/src/core/node/Exp.cpp index da5de31..a3aaf77 100644 --- a/cas/src/core/node/Exp.cpp +++ b/cas/src/core/node/Exp.cpp @@ -10,7 +10,7 @@ CAS_NAMESPACE -Exp::Exp(ExprPtr exponent) +Exp::Exp(const ExprPtr& exponent) : Power({ExpressionType::EXPONENTIAL, "exponential", "exp"}, Const::E(), exponent) {} double Exp::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/Expression.cpp b/cas/src/core/node/Expression.cpp index 0c7e799..a65b308 100644 --- a/cas/src/core/node/Expression.cpp +++ b/cas/src/core/node/Expression.cpp @@ -48,7 +48,7 @@ double Expr::evaluate() { return evaluate({}); } -bool Expr::equals(ExprPtr expression) { +bool Expr::equals(const ExprPtr& expression) { if (this == expression.get()) return true; @@ -58,7 +58,7 @@ bool Expr::equals(ExprPtr expression) { return _equals(expression); } -bool Expr::_equals(ExprPtr) { +bool Expr::_equals(const ExprPtr&) { throw std::runtime_error("Expression::equals() is not implemented for " + properties.getName()); } @@ -78,11 +78,11 @@ ExprPtr Expr::simplified() { throw std::runtime_error("Expression::simplified() is not implemented for " + properties.getName()); } -bool Expr::isEquivalent(ExprPtr) { +bool Expr::isEquivalent(const ExprPtr&) { throw std::runtime_error("Expression::isEquivalent() is not implemented for " + properties.getName()); } -ProdPtr Expr::multiply(ExprPtr expression) { +ProdPtr Expr::multiply(const ExprPtr& expression) { return std::make_shared(std::vector{shared_from_this(), expression}); } @@ -90,7 +90,7 @@ ProdPtr Expr::multiply(double value) { return std::make_shared(std::vector{shared_from_this(), Const::n(value)}); } -SumPtr Expr::add(ExprPtr expression) { +SumPtr Expr::add(const ExprPtr& expression) { return std::make_shared(std::vector{shared_from_this(), expression}); } @@ -98,7 +98,7 @@ SumPtr Expr::add(double value) { return add(Const::n(value)); } -SumPtr Expr::subtract(ExprPtr expression) { +SumPtr Expr::subtract(const ExprPtr& expression) { const NegatePtr& negate = Negate::from(expression); return std::make_shared(std::vector{shared_from_this(), negate}); } @@ -107,7 +107,7 @@ SumPtr Expr::subtract(double value) { return subtract(Const::n(value)); } -DividePtr Expr::divide(ExprPtr expression) { +DividePtr Expr::divide(const ExprPtr& expression) { return std::make_shared(shared_from_this(), expression); } @@ -119,7 +119,7 @@ NegatePtr Expr::negate() { return std::make_shared(shared_from_this()); } -PowerPtr Expr::power(ExprPtr expression) { +PowerPtr Expr::power(const ExprPtr& expression) { return std::make_shared(shared_from_this(), expression); } @@ -131,7 +131,7 @@ ExpPtr Expr::exp() { return std::make_shared(shared_from_this()); } -LogPtr Expr::log(ExprPtr base) { +LogPtr Expr::log(const ExprPtr& base) { return std::make_shared(base, shared_from_this()); } LogPtr Expr::log(double base) { @@ -141,7 +141,7 @@ LogPtr Expr::log(double base) { LnPtr Expr::ln() { return std::make_shared(shared_from_this()); } -RootPtr Expr::root(ExprPtr root) { +RootPtr Expr::root(const ExprPtr& root) { return std::make_shared(shared_from_this(), root); } @@ -214,7 +214,7 @@ SignPtr Expr::sign() { return std::make_shared(shared_from_this()); } -ModPtr Expr::mod(ExprPtr expression) { +ModPtr Expr::mod(const ExprPtr& expression) { return std::make_shared(shared_from_this(), expression); } @@ -256,11 +256,11 @@ bool Expr::operator<(const cas::Expr& expression) const { return diff < 0; } -bool Expr::lessThan(cas::ExprPtr expression) const { +bool Expr::lessThan(const ExprPtr& expression) const { return *this < *expression; } -bool Expr::compare(cas::ExprPtr left, cas::ExprPtr right) { +bool Expr::compare(const ExprPtr& left, const ExprPtr& right) { return left->lessThan(right); } @@ -284,7 +284,7 @@ bool Expr::isOfType(ExpressionType type) const { return properties.getType() == type; } -bool Expr::isOfSameType(ExprPtr expression) const { +bool Expr::isOfSameType(const ExprPtr& expression) const { return isOfType(expression->getProperties().getType()); } diff --git a/cas/src/core/node/Floor.cpp b/cas/src/core/node/Floor.cpp index cab9005..1aba474 100644 --- a/cas/src/core/node/Floor.cpp +++ b/cas/src/core/node/Floor.cpp @@ -9,7 +9,7 @@ CAS_NAMESPACE -Floor::Floor(ExprPtr argument) +Floor::Floor(const ExprPtr& argument) : BracketExpression({ExpressionType::FLOOR, "floor_value", "floor"}, argument, L"\u230A", L"\u230B", "\\lfloor", "\\rfloor") {} double Floor::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/Ln.cpp b/cas/src/core/node/Ln.cpp index 2453e83..8b9d776 100644 --- a/cas/src/core/node/Ln.cpp +++ b/cas/src/core/node/Ln.cpp @@ -11,14 +11,14 @@ CAS_NAMESPACE -Ln::Ln(ExprPtr argument) +Ln::Ln(const ExprPtr& argument) : Log({ExpressionType::NATURAL_LOGARITHM, "natural_logarithm", "ln"}, Const::E(), argument) {} double Ln::evaluate(const VariableMap& variables) { return std::log(argument->evaluate(variables)); } -bool Ln::_equals(ExprPtr expression) { +bool Ln::_equals(const ExprPtr& expression) { if (expression->isOfType(ExpressionType::NATURAL_LOGARITHM)) { auto* ln = dynamic_cast(expression.get()); return argument->equals(ln->argument); diff --git a/cas/src/core/node/Log.cpp b/cas/src/core/node/Log.cpp index fc66f8b..e89adfb 100644 --- a/cas/src/core/node/Log.cpp +++ b/cas/src/core/node/Log.cpp @@ -13,26 +13,26 @@ CAS_NAMESPACE -Log::Log(const ExpressionProperties& props, ExprPtr base, ExprPtr argument) +Log::Log(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& argument) : Expr(props), base(base), argument(argument) { base->setParent(this); argument->setParent(this); } -Log::Log(ExprPtr base, ExprPtr argument) +Log::Log(const ExprPtr& base, const ExprPtr& argument) : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, base, argument) {} -Log::Log(double base, ExprPtr argument) +Log::Log(double base, const ExprPtr& argument) : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, Const::n(base), argument) {} -Log::Log(ExprPtr argument) +Log::Log(const ExprPtr& argument) : Log({ExpressionType::LOGARITHM, "logarithm", "log"}, Const::n(10), argument) {} double Log::evaluate(const VariableMap& variables) { return std::log(argument->evaluate(variables)) / std::log(base->evaluate(variables)); } -bool Log::_equals(ExprPtr expression) { +bool Log::_equals(const ExprPtr& expression) { if (expression->isOfType(ExpressionType::LOGARITHM)) { auto* log = dynamic_cast(expression.get()); return base->equals(log->base) && argument->equals(log->argument); diff --git a/cas/src/core/node/Max.cpp b/cas/src/core/node/Max.cpp index d79d175..c2cedb7 100644 --- a/cas/src/core/node/Max.cpp +++ b/cas/src/core/node/Max.cpp @@ -12,7 +12,7 @@ Max::Max(std::vector expressions) : NaryExpression({ExpressionType::MAX, "maximum", "max"}, std::move(expressions)) {} double Max::evaluate(const VariableMap& variables) { - auto functor = [&](ExprPtr a, ExprPtr b) { + auto functor = [&](const ExprPtr& a, const ExprPtr& b) { return a->evaluate(variables) > b->evaluate(variables); }; @@ -36,11 +36,11 @@ ExprPtr Max::simplified() { std::vector simplifiedExpressions; simplifiedExpressions.reserve(expressions.size()); - std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](ExprPtr expr) { + std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](const ExprPtr& expr) { return expr->simplified(); }); - bool (*isConstant)(ExprPtr) = [](ExprPtr expression) { + bool (*isConstant)(const ExprPtr&) = [](const ExprPtr& expression) { return expression->isOfType(ExpressionType::CONSTANT); }; @@ -49,7 +49,7 @@ ExprPtr Max::simplified() { if (constantCount > 1) { bool allConstant = std::all_of(simplifiedExpressions.begin(), simplifiedExpressions.end(), isConstant); if (allConstant) { - double maxElement = (*std::max_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](ExprPtr a, ExprPtr b) { + double maxElement = (*std::max_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](const ExprPtr& a, const ExprPtr& b) { return a->evaluate() > b->evaluate(); }))->evaluate(); diff --git a/cas/src/core/node/Min.cpp b/cas/src/core/node/Min.cpp index d9392bf..cd6f084 100644 --- a/cas/src/core/node/Min.cpp +++ b/cas/src/core/node/Min.cpp @@ -12,7 +12,7 @@ Min::Min(std::vector expressions) : NaryExpression({ExpressionType::MIN, "minimum", "min"}, std::move(expressions)) {} double Min::evaluate(const VariableMap& variables) { - auto functor = [&](ExprPtr a, ExprPtr b) { + auto functor = [&](const ExprPtr& a, const ExprPtr& b) { return a->evaluate(variables) < b->evaluate(variables); }; @@ -36,11 +36,11 @@ ExprPtr Min::simplified() { std::vector simplifiedExpressions; simplifiedExpressions.reserve(expressions.size()); - std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](ExprPtr expr) { + std::transform(expressions.begin(), expressions.end(), simplifiedExpressions.begin(), [](const ExprPtr& expr) { return expr->simplified(); }); - bool (*isConstant)(ExprPtr) = [](ExprPtr expression) { + bool (*isConstant)(const ExprPtr&) = [](const ExprPtr& expression) { return expression->isOfType(ExpressionType::CONSTANT); }; @@ -49,7 +49,7 @@ ExprPtr Min::simplified() { if (constantCount > 1) { bool allConstant = std::all_of(simplifiedExpressions.begin(), simplifiedExpressions.end(), isConstant); if (allConstant) { - double minElement = (*std::min_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](ExprPtr a, ExprPtr b) { + double minElement = (*std::min_element(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](const ExprPtr& a, const ExprPtr& b) { return a->evaluate() < b->evaluate(); }))->evaluate(); diff --git a/cas/src/core/node/Mod.cpp b/cas/src/core/node/Mod.cpp index 0c0f4c1..e46653e 100644 --- a/cas/src/core/node/Mod.cpp +++ b/cas/src/core/node/Mod.cpp @@ -9,7 +9,7 @@ CAS_NAMESPACE -Mod::Mod(ExprPtr dividend, ExprPtr divisor) +Mod::Mod(const ExprPtr& dividend, const ExprPtr& divisor) : Expr({ExpressionType::MODULO, "modulo", "mod"}), dividend(dividend), divisor(divisor) { if (divisor->isOfType(ExpressionType::CONSTANT) && divisor->evaluate() == 0) { @@ -24,7 +24,7 @@ double Mod::evaluate(const VariableMap& variables) { return std::fmod(dividend->evaluate(variables), divisor->evaluate(variables)); } -bool Mod::_equals(ExprPtr expression) { +bool Mod::_equals(const ExprPtr& expression) { if (this == expression.get()) return true; diff --git a/cas/src/core/node/NaryExpression.cpp b/cas/src/core/node/NaryExpression.cpp index 28d49aa..139aab5 100644 --- a/cas/src/core/node/NaryExpression.cpp +++ b/cas/src/core/node/NaryExpression.cpp @@ -17,7 +17,7 @@ NaryExpression::NaryExpression(const ExpressionProperties& props, } } -bool NaryExpression::_equals(ExprPtr expression) { +bool NaryExpression::_equals(const ExprPtr& expression) { if (this == expression.get()) return true; diff --git a/cas/src/core/node/Negate.cpp b/cas/src/core/node/Negate.cpp index c9e82a5..6e5288e 100644 --- a/cas/src/core/node/Negate.cpp +++ b/cas/src/core/node/Negate.cpp @@ -10,14 +10,14 @@ CAS_NAMESPACE -Negate::Negate(ExprPtr expression) +Negate::Negate(const ExprPtr& expression) : UnaryExpression({ExpressionType::NEGATE, "negate", "neg"}, expression) {} double Negate::evaluate(const VariableMap& variables) { return -argument->evaluate(variables); } -bool Negate::_equals(ExprPtr expr) { +bool Negate::_equals(const ExprPtr& expr) { auto* negate = dynamic_cast(expr.get()); return argument->equals(negate->argument); } diff --git a/cas/src/core/node/Operator.cpp b/cas/src/core/node/Operator.cpp index 764bcce..8db557d 100644 --- a/cas/src/core/node/Operator.cpp +++ b/cas/src/core/node/Operator.cpp @@ -21,7 +21,7 @@ double Operator::evaluate(const VariableMap& variables) { return result; } -bool Operator::_equals(ExprPtr expression) { +bool Operator::_equals(const ExprPtr& expression) { if (this == expression.get()) return true; diff --git a/cas/src/core/node/Power.cpp b/cas/src/core/node/Power.cpp index 326259a..e0adb0a 100644 --- a/cas/src/core/node/Power.cpp +++ b/cas/src/core/node/Power.cpp @@ -13,23 +13,23 @@ CAS_NAMESPACE -Power::Power(const ExpressionProperties& props, ExprPtr base, ExprPtr exponent) +Power::Power(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& exponent) : Expr(props), base(base), exponent(exponent) { // this->base->setParent(shared_from_this()); // this->exponent->setParent(shared_from_this()); } -Power::Power(ExprPtr base, ExprPtr exponent) +Power::Power(const ExprPtr& base, const ExprPtr& exponent) : Power({ExpressionType::POWER, "power", "pow"}, base, exponent) {} -Power::Power(ExprPtr base, double exponent) +Power::Power(const ExprPtr& base, double exponent) : Power({ExpressionType::POWER, "power", "pow"}, base, Const::n(exponent)) {} double Power::evaluate(const VariableMap& variables) { return pow(base->evaluate(variables), exponent->evaluate(variables)); } -bool Power::_equals(ExprPtr expression) { +bool Power::_equals(const ExprPtr& expression) { auto* power = dynamic_cast(expression.get()); return base->equals(power->base) && exponent->equals(power->exponent); } diff --git a/cas/src/core/node/Product.cpp b/cas/src/core/node/Product.cpp index 7ebd233..e9188bf 100644 --- a/cas/src/core/node/Product.cpp +++ b/cas/src/core/node/Product.cpp @@ -76,13 +76,13 @@ ExprPtr Prod::simplified() { if (simplifiedExpressions.size() == 1) return simplifiedExpressions[0]; - std::sort(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](ExprPtr a, ExprPtr b) { + std::sort(simplifiedExpressions.begin(), simplifiedExpressions.end(), [](const ExprPtr& a, const ExprPtr& b) { return a->lessThan(b); }); return Prod::from({simplifiedExpressions}); } -bool Prod::needsParentheses(ExprPtr expression) { +bool Prod::needsParentheses(const ExprPtr& expression) { return expression->getProperties().getType() == ExpressionType::SUM; } diff --git a/cas/src/core/node/Root.cpp b/cas/src/core/node/Root.cpp index d3fa98a..7f6070e 100644 --- a/cas/src/core/node/Root.cpp +++ b/cas/src/core/node/Root.cpp @@ -12,13 +12,13 @@ CAS_NAMESPACE -Root::Root(const ExpressionProperties& props, ExprPtr base, ExprPtr root) +Root::Root(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& root) : Power(props, base, root) {} -Root::Root(ExprPtr base, ExprPtr root) +Root::Root(const ExprPtr& base, const ExprPtr& root) : Root({ExpressionType::ROOT, "root", "root"}, base, root) {} -Root::Root(ExprPtr base, double root) +Root::Root(const ExprPtr& base, double root) : Root(base, Const::n(root)) {} double Root::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/Round.cpp b/cas/src/core/node/Round.cpp index d3c0df8..74b5861 100644 --- a/cas/src/core/node/Round.cpp +++ b/cas/src/core/node/Round.cpp @@ -7,7 +7,7 @@ CAS_NAMESPACE -Round::Round(ExprPtr argument) +Round::Round(const ExprPtr& argument) : BracketExpression({ExpressionType::ROUND, "round", "round"}, argument, L"\u230A", L"\u2309", "\\lfloor", "\\rceil") {} double Round::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/Sign.cpp b/cas/src/core/node/Sign.cpp index 62a2473..4bfbcd4 100644 --- a/cas/src/core/node/Sign.cpp +++ b/cas/src/core/node/Sign.cpp @@ -10,7 +10,7 @@ CAS_NAMESPACE -Sign::Sign(ExprPtr argument) +Sign::Sign(const ExprPtr& argument) : UnaryExpression({ExpressionType::SIGN, "sign", "sign"}, argument) {} double Sign::evaluate(const VariableMap& variables) { @@ -19,7 +19,7 @@ double Sign::evaluate(const VariableMap& variables) { : 0; } -bool Sign::_equals(ExprPtr expression) { +bool Sign::_equals(const ExprPtr& expression) { if (this == expression.get()) return true; diff --git a/cas/src/core/node/Sqrt.cpp b/cas/src/core/node/Sqrt.cpp index ae47e91..a62345b 100644 --- a/cas/src/core/node/Sqrt.cpp +++ b/cas/src/core/node/Sqrt.cpp @@ -12,7 +12,7 @@ CAS_NAMESPACE -Sqrt::Sqrt(ExprPtr base) +Sqrt::Sqrt(const ExprPtr& base) : Root({ExpressionType::SQUARE_ROOT, "square_root", "sqrt"}, base, Const::n(2)) {} double Sqrt::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/UnaryExpression.cpp b/cas/src/core/node/UnaryExpression.cpp index 6d489a9..d2fdbc6 100644 --- a/cas/src/core/node/UnaryExpression.cpp +++ b/cas/src/core/node/UnaryExpression.cpp @@ -11,7 +11,7 @@ CAS_NAMESPACE -UnaryExpression::UnaryExpression(const ExpressionProperties& properties, ExprPtr argument) +UnaryExpression::UnaryExpression(const ExpressionProperties& properties, const ExprPtr& argument) : Expr(properties), argument(argument) { this->argument->setParent(this); } diff --git a/cas/src/core/node/Var.cpp b/cas/src/core/node/Var.cpp index 35776a9..f97c6c4 100644 --- a/cas/src/core/node/Var.cpp +++ b/cas/src/core/node/Var.cpp @@ -22,7 +22,7 @@ double Var::evaluate(const VariableMap& variables) { return variables.at(symbol); } -bool Var::_equals(ExprPtr expression) { +bool Var::_equals(const ExprPtr& expression) { auto* var = dynamic_cast(expression.get()); return var->getSymbol() == symbol; } diff --git a/cas/src/core/node/trig/ArcCos.cpp b/cas/src/core/node/trig/ArcCos.cpp index 9c72abe..d3a59ce 100644 --- a/cas/src/core/node/trig/ArcCos.cpp +++ b/cas/src/core/node/trig/ArcCos.cpp @@ -11,7 +11,7 @@ CAS_NAMESPACE -ArcCos::ArcCos(ExprPtr argument) +ArcCos::ArcCos(const ExprPtr& argument) : InverseTrigExpression({ExpressionType::ARC_COS, "arccos", "acos"}, argument) {} double ArcCos::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/trig/ArcCot.cpp b/cas/src/core/node/trig/ArcCot.cpp index 70872f5..9bf7c4c 100644 --- a/cas/src/core/node/trig/ArcCot.cpp +++ b/cas/src/core/node/trig/ArcCot.cpp @@ -12,7 +12,7 @@ CAS_NAMESPACE -ArcCot::ArcCot(ExprPtr argument) +ArcCot::ArcCot(const ExprPtr& argument) : InverseTrigExpression({ExpressionType::ARC_COT, "arccot", "acot"}, argument) {} double ArcCot::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/trig/ArcCsc.cpp b/cas/src/core/node/trig/ArcCsc.cpp index 49db0c2..f8a8fa8 100644 --- a/cas/src/core/node/trig/ArcCsc.cpp +++ b/cas/src/core/node/trig/ArcCsc.cpp @@ -13,7 +13,7 @@ CAS_NAMESPACE -ArcCsc::ArcCsc(ExprPtr argument) +ArcCsc::ArcCsc(const ExprPtr& argument) : InverseTrigExpression({ExpressionType::ARC_CSC, "arccsc", "acsc"}, argument) {} double ArcCsc::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/trig/ArcSec.cpp b/cas/src/core/node/trig/ArcSec.cpp index 09ea167..208b49c 100644 --- a/cas/src/core/node/trig/ArcSec.cpp +++ b/cas/src/core/node/trig/ArcSec.cpp @@ -14,7 +14,7 @@ CAS_NAMESPACE -ArcSec::ArcSec(ExprPtr argument) +ArcSec::ArcSec(const ExprPtr& argument) : InverseTrigExpression({ExpressionType::ARC_SEC, "arcsec", "asec"}, argument) {} double ArcSec::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/trig/ArcSin.cpp b/cas/src/core/node/trig/ArcSin.cpp index 39b6bc0..9a3123e 100644 --- a/cas/src/core/node/trig/ArcSin.cpp +++ b/cas/src/core/node/trig/ArcSin.cpp @@ -11,7 +11,7 @@ CAS_NAMESPACE -ArcSin::ArcSin(ExprPtr argument) +ArcSin::ArcSin(const ExprPtr& argument) : InverseTrigExpression({ExpressionType::ARC_SIN, "arcsin", "asin"}, argument) {} double ArcSin::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/trig/ArcTan.cpp b/cas/src/core/node/trig/ArcTan.cpp index 90ad753..327e2e1 100644 --- a/cas/src/core/node/trig/ArcTan.cpp +++ b/cas/src/core/node/trig/ArcTan.cpp @@ -11,7 +11,7 @@ CAS_NAMESPACE -ArcTan::ArcTan(ExprPtr argument) +ArcTan::ArcTan(const ExprPtr& argument) : InverseTrigExpression({ExpressionType::ARC_TAN, "arctan", "atan"}, argument) {} double ArcTan::evaluate(const VariableMap& variables) { diff --git a/cas/src/core/node/trig/Cos.cpp b/cas/src/core/node/trig/Cos.cpp index c3aa87f..8bdc5d5 100644 --- a/cas/src/core/node/trig/Cos.cpp +++ b/cas/src/core/node/trig/Cos.cpp @@ -13,7 +13,7 @@ CAS_NAMESPACE -Cos::Cos(ExprPtr argument) : TrigExpression({ExpressionType::COS, "cosine", "cos"}, argument) {} +Cos::Cos(const ExprPtr& argument) : TrigExpression({ExpressionType::COS, "cosine", "cos"}, argument) {} double Cos::evaluate(const VariableMap& variables) { return std::cos(argument->evaluate(variables)); diff --git a/cas/src/core/node/trig/Cot.cpp b/cas/src/core/node/trig/Cot.cpp index bbea163..91a95fc 100644 --- a/cas/src/core/node/trig/Cot.cpp +++ b/cas/src/core/node/trig/Cot.cpp @@ -13,7 +13,7 @@ CAS_NAMESPACE -Cot::Cot(ExprPtr argument) : TrigExpression({ExpressionType::COT, "cotangent", "cot"}, argument) {} +Cot::Cot(const ExprPtr& argument) : TrigExpression({ExpressionType::COT, "cotangent", "cot"}, argument) {} double Cot::evaluate(const VariableMap& variables) { return 1.0 / std::tan(argument->evaluate(variables)); diff --git a/cas/src/core/node/trig/Csc.cpp b/cas/src/core/node/trig/Csc.cpp index 51cbe99..2395ce4 100644 --- a/cas/src/core/node/trig/Csc.cpp +++ b/cas/src/core/node/trig/Csc.cpp @@ -11,7 +11,7 @@ CAS_NAMESPACE -Csc::Csc(ExprPtr argument) : TrigExpression({ExpressionType::CSC, "cosecant", "csc"}, argument) {} +Csc::Csc(const ExprPtr& argument) : TrigExpression({ExpressionType::CSC, "cosecant", "csc"}, argument) {} double Csc::evaluate(const VariableMap& variables) { return 1.0 / std::sin(argument->evaluate(variables)); diff --git a/cas/src/core/node/trig/InverseTrigExpression.cpp b/cas/src/core/node/trig/InverseTrigExpression.cpp index 47768c8..f20468b 100644 --- a/cas/src/core/node/trig/InverseTrigExpression.cpp +++ b/cas/src/core/node/trig/InverseTrigExpression.cpp @@ -7,7 +7,7 @@ CAS_NAMESPACE -InverseTrigExpression::InverseTrigExpression(const ExpressionProperties& props, ExprPtr argument) +InverseTrigExpression::InverseTrigExpression(const ExpressionProperties& props, const ExprPtr& argument) : TrigExpression(props, argument) {} std::string InverseTrigExpression::latex() { diff --git a/cas/src/core/node/trig/Sec.cpp b/cas/src/core/node/trig/Sec.cpp index a79238c..87810b8 100644 --- a/cas/src/core/node/trig/Sec.cpp +++ b/cas/src/core/node/trig/Sec.cpp @@ -10,7 +10,7 @@ CAS_NAMESPACE -Sec::Sec(ExprPtr argument) : TrigExpression({ExpressionType::SEC, "secant", "sec"}, argument) {} +Sec::Sec(const ExprPtr& argument) : TrigExpression({ExpressionType::SEC, "secant", "sec"}, argument) {} double Sec::evaluate(const VariableMap& variables) { return 1.0 / std::cos(argument->evaluate(variables)); diff --git a/cas/src/core/node/trig/Sin.cpp b/cas/src/core/node/trig/Sin.cpp index 620e861..44f0b64 100644 --- a/cas/src/core/node/trig/Sin.cpp +++ b/cas/src/core/node/trig/Sin.cpp @@ -11,7 +11,7 @@ CAS_NAMESPACE -Sin::Sin(ExprPtr argument) : TrigExpression({ExpressionType::SIN, "sinus", "sin"}, argument) {} +Sin::Sin(const ExprPtr& argument) : TrigExpression({ExpressionType::SIN, "sinus", "sin"}, argument) {} double Sin::evaluate(const VariableMap& variables) { return std::sin(argument->evaluate(variables)); diff --git a/cas/src/core/node/trig/Tan.cpp b/cas/src/core/node/trig/Tan.cpp index 1d0e2ce..ad78b8f 100644 --- a/cas/src/core/node/trig/Tan.cpp +++ b/cas/src/core/node/trig/Tan.cpp @@ -12,7 +12,7 @@ CAS_NAMESPACE -Tan::Tan(ExprPtr argument) : TrigExpression({ExpressionType::TAN, "tangent", "tan"}, argument) {} +Tan::Tan(const ExprPtr& argument) : TrigExpression({ExpressionType::TAN, "tangent", "tan"}, argument) {} double Tan::evaluate(const VariableMap& variables) { return std::tan(argument->evaluate(variables)); diff --git a/cas/src/core/node/trig/TrigExpression.cpp b/cas/src/core/node/trig/TrigExpression.cpp index 7e4ad40..44d2b34 100644 --- a/cas/src/core/node/trig/TrigExpression.cpp +++ b/cas/src/core/node/trig/TrigExpression.cpp @@ -34,10 +34,10 @@ const std::unordered_map TrigExpression::unitCircl {math::PI_11_6, {math::PI_11_6, Const::n(3)->sqrt()->divide(2), Const::n(-1)->divide(2), Const::n(-1)->divide(Const::n(3)->sqrt())}}, }; -TrigExpression::TrigExpression(const ExpressionProperties& properties, ExprPtr argument) +TrigExpression::TrigExpression(const ExpressionProperties& properties, const ExprPtr& argument) : UnaryExpression(properties, argument) {} -bool TrigExpression::_equals(ExprPtr other) { +bool TrigExpression::_equals(const ExprPtr& other) { auto* otherTrigFunction = dynamic_cast(other.get()); return argument->equals(otherTrigFunction->argument); } diff --git a/cas/src/core/plot/Function.cpp b/cas/src/core/plot/Function.cpp index e70d80d..4e4e288 100644 --- a/cas/src/core/plot/Function.cpp +++ b/cas/src/core/plot/Function.cpp @@ -24,7 +24,7 @@ Function::Function(std::string strFunction, const std::string& name, bool simpli } } -Function::Function(const std::string& strFunction, cas::ExprPtr expr, const cas::VarSet& variables, const std::string& name) +Function::Function(const std::string& strFunction, const ExprPtr& expr, const cas::VarSet& variables, const std::string& name) : uid(nextId()), strExpr(strFunction), expr(expr), name(name), filename(generateFilename()), variables(variables) {} double Function::evaluate(const VariableMap& vars) { @@ -60,7 +60,7 @@ Function* Function::simplified() { return new Function(pExpression->text(), pExpression, this->variables, this->name + "_s"); } -bool Function::isEquivalent(Function* expression) { +bool Function::isEquivalent(Function* const & expression) { return expr->isEquivalent(expression->expr); } From 64cd255691f79f7cd90875e7284d71e3f453df57 Mon Sep 17 00:00:00 2001 From: Abd-El-Aziz Zayed Date: Thu, 5 Jan 2023 17:51:53 -0500 Subject: [PATCH 3/6] Fix cmake files --- cas/src/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cas/src/CMakeLists.txt b/cas/src/CMakeLists.txt index e61d9ae..335050d 100644 --- a/cas/src/CMakeLists.txt +++ b/cas/src/CMakeLists.txt @@ -69,8 +69,7 @@ set(CAS_SRC_HEADERS ../include/cas/node/IMath.h ../include/cas/latex/LatexRenderer.h ../include/cas/data/ExpressionParser.h - ../include/cas/data/VariableMap.h - ../include/cas/plot/Surface.h) + ../include/cas/data/VariableMap.h) set(CAS_SRC_SOURCES core/node/Const.cpp From be00eea6d8309bb167f1c9418b8e7d2ed85124bc Mon Sep 17 00:00:00 2001 From: Abd-El-Aziz Zayed Date: Thu, 5 Jan 2023 17:55:15 -0500 Subject: [PATCH 4/6] include mem --- cas/include/cas/node/Expression.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cas/include/cas/node/Expression.h b/cas/include/cas/node/Expression.h index 9e68620..2656b82 100644 --- a/cas/include/cas/node/Expression.h +++ b/cas/include/cas/node/Expression.h @@ -9,6 +9,7 @@ #include "IRepresentableMath.h" #include "cas/data/ExpressionProperties.h" #include "cas/data/ExpressionType.h" +#include CAS_NAMESPACE From a43aca33213ec879d653814c47efcb0e7d327daa Mon Sep 17 00:00:00 2001 From: Abd-El-Aziz Zayed Date: Tue, 6 Jun 2023 21:41:19 -0400 Subject: [PATCH 5/6] Update cpr --- CMakeLists.txt | 2 +- cas/src/CMakeLists.txt | 2 +- cas/src/core/data/VariableMap.cpp | 2 +- src/render/metal/Window.h | 2 +- src/render/metal/main.mm | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f186668..87ce4b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(ComputerAlgebraSystem LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_EXTENSIONS OFF) # Don't use compiler extensions so we have a portable codebase. set(CMAKE_CXX_STANDARD_REQUIRED ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON) diff --git a/cas/src/CMakeLists.txt b/cas/src/CMakeLists.txt index 335050d..b9544ce 100644 --- a/cas/src/CMakeLists.txt +++ b/cas/src/CMakeLists.txt @@ -5,7 +5,7 @@ include(FetchContent) FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git - GIT_TAG f88fd7737de3e640c61703eb57a0fa0ce00c60cd) + GIT_TAG 2553fc41450301cd09a9271c8d2c3e0cf3546b73) FetchContent_MakeAvailable(cpr) set(CPR_BUILD_TESTS OFF CACHE BOOL "Build the tests" FORCE) diff --git a/cas/src/core/data/VariableMap.cpp b/cas/src/core/data/VariableMap.cpp index b97623c..cf80452 100644 --- a/cas/src/core/data/VariableMap.cpp +++ b/cas/src/core/data/VariableMap.cpp @@ -248,7 +248,7 @@ VariableMapIterator& VariableMapIterator::operator++() { if (letter == 'z' + 1) { letter = 'A'; } - } while ((letter >= 'a' && letter <= 'z' || letter >= 'A' && letter <= 'Z') && + } while (((letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z')) && !variableMap.contains(letter)); return *this; diff --git a/src/render/metal/Window.h b/src/render/metal/Window.h index bf41abf..ae7b30c 100644 --- a/src/render/metal/Window.h +++ b/src/render/metal/Window.h @@ -29,7 +29,7 @@ class Window { public: - explicit Window(const char* title, id device, Grid& grid) : device(device), grid(grid), title(title) { + explicit Window(const char* title, id device, Grid& grid) : title(title), device(device), grid(grid) { glfwSetErrorCallback([](int error, const char* description) { printf("Glfw Error %d: %s\n", error, description); }); diff --git a/src/render/metal/main.mm b/src/render/metal/main.mm index 1da4ed6..e79d505 100644 --- a/src/render/metal/main.mm +++ b/src/render/metal/main.mm @@ -1,11 +1,11 @@ #include +#include "cas/data/VariableMap.h" + #include "Grid.h" #include "Surface.h" #include "Window.h" -#include "cas/data/VariableMap.h" - #import #import #import @@ -28,10 +28,10 @@ MTLVertexDescriptor* getVertexDescriptor() { MTLVertexDescriptor* vertexDescriptor = [MTLVertexDescriptor new]; - vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3;// position + vertexDescriptor.attributes[0].format = MTLVertexFormatFloat3; // position vertexDescriptor.attributes[0].offset = 0; vertexDescriptor.attributes[0].bufferIndex = 0; - vertexDescriptor.attributes[1].format = MTLVertexFormatFloat4;// color + vertexDescriptor.attributes[1].format = MTLVertexFormatFloat4; // color vertexDescriptor.attributes[1].offset = sizeof(simd::float3); vertexDescriptor.attributes[1].bufferIndex = 0; vertexDescriptor.layouts[0].stride = sizeof(Vertex); From 9f58e936a6b75012c42ac8bdb37413b76419feb5 Mon Sep 17 00:00:00 2001 From: Abd-El-Aziz Zayed Date: Mon, 18 Dec 2023 20:28:57 -0500 Subject: [PATCH 6/6] add stuff --- .clang-tidy | 2 +- .gitignore | 1 + CMakeLists.txt | 1 + build.bat | 8 ++--- build.sh | 8 ++--- cas/include/cas/data/ExpressionProperties.h | 34 --------------------- cas/include/cas/latex/LatexRenderer.h | 2 +- cas/include/cas/node/Expression.h | 17 ++++++++++- cas/include/cas/plot/Function.h | 2 +- cas/include/cas/util/StringUtils.h | 10 ------ cas/src/CMakeLists.txt | 1 - cas/src/core/data/ExpressionProperties.cpp | 24 --------------- cas/src/core/node/Power.cpp | 4 +-- src/render/metal/Window.h | 2 +- src/render/metal/main.mm | 8 ++--- 15 files changed, 36 insertions(+), 88 deletions(-) delete mode 100644 cas/include/cas/data/ExpressionProperties.h delete mode 100644 cas/src/core/data/ExpressionProperties.cpp diff --git a/.clang-tidy b/.clang-tidy index d7b77cd..a77e383 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -97,7 +97,7 @@ modernize-use-bool-literals, modernize-use-emplace, modernize-use-equals-default, modernize-use-equals-delete, -# modernize-use-nodiscard, +modernize-use-nodiscard, modernize-use-noexcept, modernize-use-nullptr, modernize-use-override, diff --git a/.gitignore b/.gitignore index 9adfa9e..db088bc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ _deps cmake-build-*/ build-*/ +builds/ *_include.cmake bin/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 87ce4b4..91971e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ if (CMAKE_BUILD_TYPE MATCHES Debug) endif() # Enable ASAN and UBSAN + # TODO: Fix sanitizers for Windows and Linux if (MSVC) add_compile_options(/fsanitize=address,undefined) add_link_options(/fsanitize=address,undefined) diff --git a/build.bat b/build.bat index 9b6b95f..db09cc7 100644 --- a/build.bat +++ b/build.bat @@ -17,10 +17,10 @@ IF "%#%" "-eq" "0" ( ) IF "%build_debug%" "-eq" "1" ( - cmake "-DCMAKE_BUILD_TYPE=Debug" "-S" "." "-B" "build-debug" - cmake "--build" "build-debug" + cmake "-DCMAKE_BUILD_TYPE=Debug" "-S" "." "-B" "builds/debug" + cmake "--build" "builds/debug" ) IF "%build_release%" "-eq" "1" ( - cmake "-DCMAKE_BUILD_TYPE=Release" "-S" "." "-B" "build-release" - cmake "--build" "build-release" + cmake "-DCMAKE_BUILD_TYPE=Release" "-S" "." "-B" "builds/release" + cmake "--build" "builds/release" ) \ No newline at end of file diff --git a/build.sh b/build.sh index 47da317..50779aa 100755 --- a/build.sh +++ b/build.sh @@ -28,12 +28,12 @@ fi # Build the debug version if specified if [ $build_debug -eq 1 ]; then - cmake -DCMAKE_BUILD_TYPE=Debug -S . -B build-debug - cmake --build build-debug + cmake -DCMAKE_BUILD_TYPE=Debug -S . -B builds/debug + cmake --build builds/debug fi # Build the release version if specified if [ $build_release -eq 1 ]; then - cmake -DCMAKE_BUILD_TYPE=Release -S . -B build-release - cmake --build build-release + cmake -DCMAKE_BUILD_TYPE=Release -S . -B builds/release + cmake --build builds/release fi \ No newline at end of file diff --git a/cas/include/cas/data/ExpressionProperties.h b/cas/include/cas/data/ExpressionProperties.h deleted file mode 100644 index 0afe600..0000000 --- a/cas/include/cas/data/ExpressionProperties.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// Created by Abd-El-Aziz Zayed on 2022-08-31. -// - -#ifndef CAS_EXPRESSIONPROPERTIES_H -#define CAS_EXPRESSIONPROPERTIES_H - -#include "ExpressionType.h" -#include - -CAS_NAMESPACE - -// TODO redesign so this is never copied - -class ExpressionProperties { -public: - ExpressionProperties(ExpressionType type, std::string name, std::string shortName); - bool operator==(const ExpressionProperties& other) const; - - uint16_t getOrder() const; - ExpressionType getType() const; - std::string getName() const; - std::string getShortName() const; - -private: - const uint16_t order; - const ExpressionType type; - const std::string name; - const std::string shortName; -}; - -CAS_NAMESPACE_END - -#endif//CAS_EXPRESSIONPROPERTIES_H diff --git a/cas/include/cas/latex/LatexRenderer.h b/cas/include/cas/latex/LatexRenderer.h index a3c74cf..1089909 100644 --- a/cas/include/cas/latex/LatexRenderer.h +++ b/cas/include/cas/latex/LatexRenderer.h @@ -26,7 +26,7 @@ class LatexRenderer { private: const std::string prefix = "lr_"; - const std::string resFolder = "../res/latex"; + const std::string resFolder = "../../res/latex"; }; CAS_NAMESPACE_END diff --git a/cas/include/cas/node/Expression.h b/cas/include/cas/node/Expression.h index 2656b82..19db750 100644 --- a/cas/include/cas/node/Expression.h +++ b/cas/include/cas/node/Expression.h @@ -7,12 +7,27 @@ #include "IMath.h" #include "IRepresentableMath.h" -#include "cas/data/ExpressionProperties.h" #include "cas/data/ExpressionType.h" #include CAS_NAMESPACE +struct ExpressionProperties { +public: + ExpressionProperties(ExpressionType type, std::string name, std::string shortName) + : order(static_cast(type)), type(type), name(std::move(name)), shortName(std::move(shortName)) {} + + uint16_t order; + ExpressionType type; + std::string name; + std::string shortName; + + uint16_t getOrder() const { return order; } + ExpressionType getType() const { return type; } + std::string getName() const { return name; } + std::string getShortName() const { return shortName; } +}; + class Const; class Var; diff --git a/cas/include/cas/plot/Function.h b/cas/include/cas/plot/Function.h index 0c94d05..405005b 100644 --- a/cas/include/cas/plot/Function.h +++ b/cas/include/cas/plot/Function.h @@ -12,7 +12,7 @@ CAS_NAMESPACE class Function : public IMath, public IRepresentableMath { public: explicit Function(std::string strFunction, const std::string& name = "z", bool simplify = true); - ~Function() = default; + virtual ~Function() = default; double evaluate(const VariableMap& vars) override; Function* derivative(char var) override; diff --git a/cas/include/cas/util/StringUtils.h b/cas/include/cas/util/StringUtils.h index 71b8e59..7dc0955 100644 --- a/cas/include/cas/util/StringUtils.h +++ b/cas/include/cas/util/StringUtils.h @@ -10,16 +10,6 @@ #include #include -inline std::wstring toWstring(const std::string& string) { - std::wstring_convert> converter; - return converter.from_bytes(string); -} - -inline std::string toString(const std::wstring& wString) { - std::wstring_convert> converter; - return converter.to_bytes(wString); -} - inline void replaceAll(std::string& str, const std::string& from, const std::string& to) { size_t start_pos = 0; while ((start_pos = str.find(from, start_pos)) != std::string::npos) { diff --git a/cas/src/CMakeLists.txt b/cas/src/CMakeLists.txt index b9544ce..de06036 100644 --- a/cas/src/CMakeLists.txt +++ b/cas/src/CMakeLists.txt @@ -112,7 +112,6 @@ set(CAS_SRC_SOURCES core/node/trig/ArcCot.cpp core/node/trig/ArcCsc.cpp core/node/trig/InverseTrigExpression.cpp - core/data/ExpressionProperties.cpp core/data/VariableMap.cpp core/latex/LatexRenderer.cpp core/plot/Function.cpp diff --git a/cas/src/core/data/ExpressionProperties.cpp b/cas/src/core/data/ExpressionProperties.cpp deleted file mode 100644 index b7a4f4f..0000000 --- a/cas/src/core/data/ExpressionProperties.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// Created by Abd-El-Aziz Zayed on 2022-09-22. -// - -#include "cas/data/ExpressionProperties.h" - -CAS_NAMESPACE - -ExpressionProperties::ExpressionProperties(ExpressionType type, std::string name, std::string shortName) - : order(static_cast(type)), type(type), name(std::move(name)), shortName(std::move(shortName)) {} - -bool ExpressionProperties::operator==(const ExpressionProperties& other) const { - return type == other.type && order == other.order && name == other.name && shortName == other.shortName; -} - -uint16_t ExpressionProperties::getOrder() const { return order; } - -ExpressionType ExpressionProperties::getType() const { return type; } - -std::string ExpressionProperties::getName() const { return name; } - -std::string ExpressionProperties::getShortName() const { return shortName; } - -CAS_NAMESPACE_END \ No newline at end of file diff --git a/cas/src/core/node/Power.cpp b/cas/src/core/node/Power.cpp index e0adb0a..9b8badb 100644 --- a/cas/src/core/node/Power.cpp +++ b/cas/src/core/node/Power.cpp @@ -15,8 +15,8 @@ CAS_NAMESPACE Power::Power(const ExpressionProperties& props, const ExprPtr& base, const ExprPtr& exponent) : Expr(props), base(base), exponent(exponent) { - // this->base->setParent(shared_from_this()); - // this->exponent->setParent(shared_from_this()); + this->base->setParent(this); + this->exponent->setParent(this); } Power::Power(const ExprPtr& base, const ExprPtr& exponent) diff --git a/src/render/metal/Window.h b/src/render/metal/Window.h index ae7b30c..bf41abf 100644 --- a/src/render/metal/Window.h +++ b/src/render/metal/Window.h @@ -29,7 +29,7 @@ class Window { public: - explicit Window(const char* title, id device, Grid& grid) : title(title), device(device), grid(grid) { + explicit Window(const char* title, id device, Grid& grid) : device(device), grid(grid), title(title) { glfwSetErrorCallback([](int error, const char* description) { printf("Glfw Error %d: %s\n", error, description); }); diff --git a/src/render/metal/main.mm b/src/render/metal/main.mm index e79d505..72dbdb0 100644 --- a/src/render/metal/main.mm +++ b/src/render/metal/main.mm @@ -106,7 +106,7 @@ int main() { id device = MTLCreateSystemDefaultDevice(); id commandQueue = [device newCommandQueue]; - id library = getLibrary(device, "../src/render/metal/shader.metal"); + id library = getLibrary(device, "../../src/render/metal/shader.metal"); id vertexFunction = [library newFunctionWithName:@"vertexMain"]; // struct with both functions id fragmentFunction = [library newFunctionWithName:@"fragmentMain"]; @@ -117,15 +117,15 @@ int main() { MTLDepthStencilDescriptor* depthStencilDescriptor = getDepthStencilDescriptor(); id depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor]; - NSArray* axis = loadMesh(device, vertexDescriptor, "../res/models/axis.obj"); + NSArray* axis = loadMesh(device, vertexDescriptor, "../../res/models/axis.obj"); // ==================== WORLD/GRID Setup ==================== Grid grid; Window window("Computer Algebra System", device, grid); - cas::VariableMap variables = {{'x', 0}, {'y', 0}}; + cas::VariableMap variables = {{'x', 0}, {'y', 0}, {'a', 0}}; std::vector> surfaces { std::make_shared(device, "x^2 + y^2", grid, variables), - std::make_shared(device, "x^2 * y^2", grid, variables), + std::make_shared(device, "x^2 * y^2 + a", grid, variables), std::make_shared(device, "sin(x*y)", grid, variables), std::make_shared(device, "abs(x * y)", grid, variables), std::make_shared(device, "floor(round(ceil(x + y)))", grid, variables)};