summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2022-04-16 13:22:31 -0500
committerHombreLaser <sebastian-440@live.com>2022-04-16 13:22:31 -0500
commit4a2d657cc5bf8ea685a0daaec803363bc2c7822c (patch)
tree454d831c4f12499691c779e40b1f9f2638bb8dc9
parente0957d3990c5c592bf19883054505d82e9d8096f (diff)
Añadida implementación dle diferenciados.
-rw-r--r--differentiator.cpp77
-rw-r--r--expression_base.cpp4
-rw-r--r--expressions.cpp40
-rw-r--r--include/differentiator.hpp5
-rw-r--r--include/expressions.hpp25
-rw-r--r--include/lexer.hpp3
-rw-r--r--include/parser.hpp4
7 files changed, 142 insertions, 16 deletions
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<Literal *>(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 <string>
#ifndef DIFFERENTIATOR_H
#define DIFFERENTIATOR_H
+#include <string>
+#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 <string>
-#include "lexer.hpp"
#ifndef EXPRESSIONS_H
#define EXPRESSIONS_H
+#include <string>
+#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 <string>
-
#ifndef LEXER_H
#define LEXER_H
+#include <string>
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 <string>
#include <vector>
#include "expressions.hpp"
#include "lexer.hpp"
-#ifndef PARSER_H
-#define PARSER_H
class Parser{
private: