From 4a2d657cc5bf8ea685a0daaec803363bc2c7822c Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Sat, 16 Apr 2022 13:22:31 -0500 Subject: Añadida implementación dle diferenciados. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- differentiator.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++ expression_base.cpp | 4 +-- expressions.cpp | 40 ++++++++++++++++++++++-- include/differentiator.hpp | 5 +-- include/expressions.hpp | 25 +++++++++++---- include/lexer.hpp | 3 +- include/parser.hpp | 4 +-- 7 files changed, 142 insertions(+), 16 deletions(-) create mode 100644 differentiator.cpp diff --git a/differentiator.cpp b/differentiator.cpp new file mode 100644 index 0000000..739c19a --- /dev/null +++ b/differentiator.cpp @@ -0,0 +1,77 @@ +/* PIA - Lenguajes Modernos de Programación + * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS + * Luis Sebastián Martínez Vega - LCC */ + +#include "include/differentiator.hpp" +#include "include/expressions.hpp" + +Differentiator::Differentiator() { + differential = NULL; + ptr = NULL; +} + +// Regla del constante. f(x)=c, f'(x)=0. +Expression *Differentiator::visit(Literal *expr) { + return new Literal(0); +} + +// Regla de la variable. f(x)=x, f'(x)=1 +Expression *Differentiator::visit(Variable *expr) { + return new Literal(1); +} + +// Reglas de funciones trigonométricas. +Expression *Differentiator::visit(Function *expr) { + Expression *diff; + + switch (expr->getFunctionName()) { + case i_sin: + diff = new MultiplicationExpression(new Function(expr->getArg()->copy(), i_cos), expr->getArg()->diff(this)); + + return diff; + case i_cos: + diff = new MultiplicationExpression(new NegationExpression(new Function(expr->getArg()->copy(), i_sin)), expr->getArg()->diff(this)); + + return diff; + case i_tan: + diff = new MultiplicationExpression(new PowerExpression(new Function(expr->getArg()->copy(), i_sec), new Literal(2)), + expr->getArg()->diff(this)); + + return diff; + case i_csc: + diff = new MultiplicationExpression(new MultiplicationExpression(new NegationExpression(new Function(expr->getArg()->copy(), i_csc)), + new Function(expr->getArg()->copy(), i_ctg)), expr->getArg()->diff(this)); + + return diff; + case i_sec: + diff = new MultiplicationExpression(new MultiplicationExpression(new Function(expr->getArg()->copy(), i_sec), + new Function(expr->getArg()->copy(), i_tan)), expr->getArg()->diff(this)); + + return diff; + case i_ctg: + diff = new MultiplicationExpression(new NegationExpression(new PowerExpression(new Function(expr->getArg()->copy(), i_csc), + new Literal(2))), expr->getArg()->copy()); + + return diff; + } +} + +Expression *Differentiator::visit(NegationExpression *expr) { + return new NegationExpression(expr->diff(this)); +} + +Expression *Differentiator::visit(AddExpression *expr) { + return new AddExpression(expr->getLeft()->diff(this), expr->getRight()->diff(this)); +} + +Expression *Differentiator::visit(SubExpression *expr) { + return new SubExpression(expr->getLeft()->diff(this), expr->getRight()->diff(this)); +} + +// Regla de la potencia. f(x)=x^c, f'(x)=c*x^(c-1)}*f'(x). +Expression *Differentiator::visit(PowerExpression *expr) { + Literal *c = dynamic_cast(expr->getRight()); + + return new MultiplicationExpression(new MultiplicationExpression(c->copy(), new PowerExpression(expr->getLeft()->copy(), new Literal(c->getValue() - 1))), + expr->getLeft()->diff(this)); +} diff --git a/expression_base.cpp b/expression_base.cpp index 3202328..2457571 100644 --- a/expression_base.cpp +++ b/expression_base.cpp @@ -11,11 +11,11 @@ using std::string; Expression::Expression(Expression *left, Expression *right, token_type type) : left(left), right(right), type(type) {} -const Expression *Expression::getLeft() { +const Expression *Expression::getLeft() const { return left; } -const Expression *Expression::getRight() { +const Expression *Expression::getRight() const { return right; } diff --git a/expressions.cpp b/expressions.cpp index 08520f7..c7d80e3 100644 --- a/expressions.cpp +++ b/expressions.cpp @@ -25,6 +25,10 @@ float Literal::eval(int arg) { return getValue(); } +Expression *Literal::copy() { + return new Literal(value); +} + // Función. Function::Function(Expression *arg, trig_functions name) : Expression(NULL, NULL, function) { this->arg = arg; @@ -35,11 +39,11 @@ Function::~Function() { delTree(); } -const Expression *Function::getArg() { +const Expression *Function::getArg() const { return arg; } -trig_functions Function::getFunctionName() { +trig_functions Function::getFunctionName() const { return function_name; } @@ -99,6 +103,10 @@ void Function::setRepr() { repr += ')'; } +Expression *Function::copy() { + return new Function(arg->copy(), function_name); +} + // Variable. Variable::Variable(char name) : Expression(NULL, NULL, variable) { this->name = name; @@ -115,6 +123,10 @@ float Variable::eval(int arg) { return arg; } +Expression *Variable::copy() { + return new Variable(name); +} + // Suma. AddExpression::AddExpression(Expression *left, Expression *right) : Expression(left, right, sum) {} @@ -130,6 +142,10 @@ float AddExpression::eval(int arg) { return right_val + left_val; } +Expression *AddExpression::copy() { + return new AddExpression(left->copy(), right->copy()); +} + // Substracción. SubExpression::SubExpression(Expression *left, Expression *right) : Expression(left, right, substraction) {} @@ -145,6 +161,10 @@ float SubExpression::eval(int arg) { return right_val - left_val; } +Expression *SubExpression::copy() { + return new SubExpression(left->copy(), right->copy()); +} + // Negación. NegationExpression::NegationExpression(Expression *right) : Expression(NULL, right, substraction) {} @@ -164,6 +184,10 @@ float NegationExpression::eval(int arg) { return -1 * expr_value; } +Expression *NegationExpression::copy() { + return new NegationExpression(right->copy()); +} + // División. DivisionExpression::DivisionExpression(Expression *left, Expression *right) : Expression(left, right, division) {} @@ -179,6 +203,10 @@ float DivisionExpression::eval(int arg) { return left_val / right_val; } +Expression *DivisionExpression::copy() { + return new DivisionExpression(left->copy(), right->copy()); +} + // Multiplicación. MultiplicationExpression::MultiplicationExpression(Expression *left, Expression *right) @@ -195,6 +223,10 @@ float MultiplicationExpression::eval(int arg) { return left_val * right_val; } +Expression *MultiplicationExpression::copy() { + return new MultiplicationExpression(left->copy(), right->copy()); +} + // Potencia. PowerExpression::PowerExpression(Expression *left, Expression *right) : Expression(left, right, power) {} @@ -209,3 +241,7 @@ float PowerExpression::eval(int arg) { return std::pow(left_val, right_val); } + +Expression *PowerExpression::copy() { + return new PowerExpression(left->copy(), right->copy()); +} diff --git a/include/differentiator.hpp b/include/differentiator.hpp index 172166f..f14f2d5 100644 --- a/include/differentiator.hpp +++ b/include/differentiator.hpp @@ -2,10 +2,11 @@ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS * Luis Sebastián Martínez Vega - LCC */ -#include "expressions.hpp" -#include #ifndef DIFFERENTIATOR_H #define DIFFERENTIATOR_H +#include +#include "expressions.hpp" + class Differentiator { private: diff --git a/include/expressions.hpp b/include/expressions.hpp index b7a2921..3191436 100644 --- a/include/expressions.hpp +++ b/include/expressions.hpp @@ -2,10 +2,10 @@ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS * Luis Sebastián Martínez Vega - LCC */ -#include -#include "lexer.hpp" #ifndef EXPRESSIONS_H #define EXPRESSIONS_H +#include +#include "lexer.hpp" /* Debido a que en eval() llamamos a la respectiva función trigonométrica, hay un conflicto entre @@ -23,14 +23,18 @@ enum trig_functions { i_ctg }; +class Differentiator; // Forward declaration. + class Expression { public: Expression(Expression *left, Expression *right, token_type type); virtual ~Expression() = default; std::string getRepr(); - const Expression *getLeft(); - const Expression *getRight(); + Expression *diff(const Differentiator *d); + Expression *getLeft(); + Expression *getRight(); virtual float eval(int arg) = 0; + virtual Expression *copy() = 0; // Regresa una copia de la expresión actual. protected: Expression *left; Expression *right; @@ -48,6 +52,7 @@ public: ~Literal(); int getValue(); float eval(int arg) override; + Expression *copy() override; protected: void setRepr() override; }; @@ -59,9 +64,10 @@ private: public: Function(Expression *arg, trig_functions name); ~Function(); - const Expression *getArg(); + Expression *getArg(); float eval(int arg) override; - trig_functions getFunctionName(); + trig_functions getFunctionName() const; + Expression *copy() override; protected: void delTree(); void setRepr() override; @@ -74,6 +80,7 @@ public: explicit Variable(char name); ~Variable(); float eval(int arg) override; + Expression *copy() override; protected: void setRepr() override; }; @@ -83,6 +90,7 @@ public: AddExpression(Expression *left, Expression *right); ~AddExpression(); float eval(int arg) override; + Expression *copy() override; }; class SubExpression : public Expression { @@ -90,6 +98,7 @@ public: SubExpression(Expression *left, Expression *right); ~SubExpression(); float eval(int arg) override; + Expression *copy() override; }; class NegationExpression : public Expression { @@ -97,6 +106,7 @@ public: explicit NegationExpression(Expression *right); ~NegationExpression(); float eval(int arg) override; + Expression *copy() override; protected: void setRepr() override; }; @@ -106,6 +116,7 @@ public: DivisionExpression(Expression *left, Expression *right); ~DivisionExpression(); float eval(int arg) override; + Expression *copy() override; }; class MultiplicationExpression : public Expression { @@ -113,6 +124,7 @@ public: MultiplicationExpression(Expression *left, Expression *right); ~MultiplicationExpression(); float eval(int arg) override; + Expression *copy() override; }; class PowerExpression : public Expression { @@ -120,6 +132,7 @@ public: PowerExpression(Expression *left, Expression *right); ~PowerExpression(); float eval(int arg) override; + Expression *copy() override; }; #endif /* EXPRESSIONS_H */ diff --git a/include/lexer.hpp b/include/lexer.hpp index 9c12d03..6b3960d 100644 --- a/include/lexer.hpp +++ b/include/lexer.hpp @@ -2,10 +2,9 @@ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS * Luis Sebastián Martínez Vega - LCC */ -#include - #ifndef LEXER_H #define LEXER_H +#include enum token_type{ sum, diff --git a/include/parser.hpp b/include/parser.hpp index 3f0032b..567ef03 100644 --- a/include/parser.hpp +++ b/include/parser.hpp @@ -2,12 +2,12 @@ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS * Luis Sebastián Martínez Vega - LCC */ +#ifndef PARSER_H +#define PARSER_H #include #include #include "expressions.hpp" #include "lexer.hpp" -#ifndef PARSER_H -#define PARSER_H class Parser{ private: -- cgit v1.2.3