diff --git a/README.md b/README.md index 4af201d..ebbdfa5 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ LeGrandChien/ ```bash # Dépendances requises -pip install numpy matplotlib tqdm +pip install numpy matplotlib tqdm inspect dis ``` ## API Principale diff --git a/double_pendule.py b/double_pendule.py index ca6deb4..5c9776d 100644 --- a/double_pendule.py +++ b/double_pendule.py @@ -2,8 +2,6 @@ import legrandchien as lgc import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np -import cProfile -import pstats g = lgc.Const(-10) m1 = lgc.Const(1) @@ -20,8 +18,8 @@ y1 = r1 * lgc.sin(theta1) x2 = x1 + r2 * lgc.cos(theta2) y2 = y1 + r2 * lgc.sin(theta2) -T = 0.5 * m1 * (x1.diff()*x1.diff() + y1.diff()*y1.diff()) -T += 0.5 * m2 * (x2.diff()*x2.diff() + y2.diff()*y2.diff()) +T = 0.5 * m1 * (x1.diff()**2 + y1.diff()**2) +T += 0.5 * m2 * (x2.diff()**2 + y2.diff()**2) V = m1 * g * x1 V += m2 * g * x2 diff --git a/double_pendule_a_ressort.py b/double_pendule_a_ressort.py index 0144980..a2a024d 100644 --- a/double_pendule_a_ressort.py +++ b/double_pendule_a_ressort.py @@ -22,8 +22,8 @@ y1 = r1 * lgc.sin(theta1) x2 = x1 + r2 * lgc.cos(theta2) y2 = y1 + r2 * lgc.sin(theta2) -T = 0.5 * m1 * (x1.diff()*x1.diff() + y1.diff()*y1.diff()) -T += 0.5 * m2 * (x2.diff()*x2.diff() + y2.diff()*y2.diff()) +T = 0.5 * m1 * (x1.diff()**2 + y1.diff()**2) +T += 0.5 * m2 * (x2.diff()**2 + y2.diff()**2) V = m1 * g * x1 V += m2 * g * x2 diff --git a/legrandchien.py b/legrandchien.py index b9234ae..d254411 100644 --- a/legrandchien.py +++ b/legrandchien.py @@ -29,6 +29,12 @@ class Const: def copy(self): return Const(self.value) + + def simplify(self): + pass + + def __str__(self): + return str(self.value) def __add__(self, other): if other.type == "Const": @@ -177,6 +183,15 @@ class Const: def __truediv__(self, other): if isinstance(other, (int, float)): return Const(other) / self + + def __pow__(self, other): + if isinstance(other, (int, float)): + return Equation( + Operation.CONST, + None, + None, + self.value ** other + ) # var class class Var: @@ -363,6 +378,15 @@ class Var: def __rtruediv__(self, other): if isinstance(other, (int, float)): return Const(other) / self + + def __pow__(self, other): + if isinstance(other, (int, float)): + return Equation( + Operation.POW, + Equation(Operation.VAR, None, None, self.copy()), + Equation(Operation.CONST, None, None, Const(other)), + None + ) # equation class class Equation: @@ -401,6 +425,16 @@ class Equation: return self.value.diff() * Equation(Operation.COS, None, None, self.value.copy()) if self.op == Operation.COS: return Const(-1) * self.value.diff() * Equation(Operation.SIN, None, None, self.value.copy()) + if self.op == Operation.POW: + n = self.right.value.value + return Equation(Operation.CONST, None, None, Const(n)) *\ + Equation( + Operation.POW, + self.left.copy(), + Equation(Operation.CONST, None, None, Const(n - 1)), + None + ) *\ + self.left.diff() def partial(self, var_name): if self.op == Operation.CONST: @@ -423,6 +457,16 @@ class Equation: return self.value.partial(var_name) * Equation(Operation.COS, None, None, self.value.copy()) if self.op == Operation.COS: return Const(-1) * self.value.partial(var_name) * Equation(Operation.SIN, None, None, self.value.copy()) + if self.op == Operation.POW: + n = self.right.value.value + return Equation(Operation.CONST, None, None, Const(n)) *\ + Equation( + Operation.POW, + self.left.copy(), + Equation(Operation.CONST, None, None, Const(n - 1)), + None + ) *\ + self.left.partial(var_name) def compile(self): if self.compiled_function is not None: @@ -473,6 +517,11 @@ class Equation: val_code, var_count = self.value._generate_code_recursive(var_count) return (f"np.cos({val_code})", var_count) + elif self.op == Operation.POW: + left_code, var_count = self.left._generate_code_recursive(var_count) + right_code, var_count = self.right._generate_code_recursive(var_count) + return (f"({left_code}) ** ({right_code})", var_count) + return ("0", var_count) def evaluate(self, dico): @@ -506,7 +555,7 @@ class Equation: dico[var.name] = 0. # print([var.name for var in unknown]) - # print(equations[0]) + print(equations[0]) assert(len(unknown) == len(equations)) n = len(unknown) @@ -603,12 +652,12 @@ class Equation: if self.op in {Operation.SIN, Operation.COS}: self.value.simplify() - if self.op == Operation.CONST: + elif self.op == Operation.CONST: pass - if self.op == Operation.VAR: + elif self.op == Operation.VAR: pass - if self.op == Operation.ADD: + elif self.op == Operation.ADD: if self.left.op == Operation.CONST and self.right.op == Operation.CONST: self.op = Operation.CONST self.value = Const(self.left.value.value + self.right.value.value) @@ -625,7 +674,7 @@ class Equation: self.value = self.left.value self.left = self.left.left - if self.op == Operation.SUB: + elif self.op == Operation.SUB: if self.left.op == Operation.CONST and self.right.op == Operation.CONST: self.op = Operation.CONST self.value = Const(self.left.value.value - self.right.value.value) @@ -634,7 +683,7 @@ class Equation: elif self.right.op == Operation.CONST and self.right.value.value == 0: self = self.left - if self.op == Operation.MULT: + elif self.op == Operation.MULT: if self.left.op == Operation.CONST and self.right.op == Operation.CONST: self.op = Operation.CONST self.value = Const(self.left.value.value * self.right.value.value) @@ -661,19 +710,36 @@ class Equation: self.value = self.left.value self.left = self.left.left - if self.op == Operation.SIN: + elif self.op == Operation.SIN: if self.value.op == Operation.CONST: self.op = Operation.CONST self.left = None self.right = None self.value = Const(np.sin(self.value.value)) - if self.op == Operation.COS: + elif self.op == Operation.COS: if self.value.op == Operation.CONST: self.op = Operation.CONST self.left = None self.right = None self.value = Const(np.cos(self.value.value)) + + elif self.op == Operation.POW: + if self.right.value.value == 0: + self.op = Operation.CONST + self.left = None + self.right = None + self.value = Const(1) + elif self.right.value.value == 1: + self.op = self.left.op + self.right = self.left.right + self.value = self.left.value + self.left = self.left.left + elif self.left.op == Operation.CONST: + self.op = Operation.CONST + self.value = Const(self.left.value.value ** self.right.value.value) + self.left = None + self.right = None def __str__(self): if self.op == Operation.CONST: @@ -692,6 +758,8 @@ class Equation: return f"sin({str(self.value)})" if self.op == Operation.COS: return f"cos({str(self.value)})" + if self.op == Operation.POW: + return f"({str(self.left)})**({str(self.right)})" def __add__(self, other): if other.type == "Const": @@ -780,6 +848,15 @@ class Equation: def __rtruediv__(self, other): if isinstance(other, (int, float)): return Const(other) / self + + def __pow__(self, other): + if isinstance(other, (int, float)): + return Equation( + Operation.POW, + self.copy(), + Equation(Operation.CONST, None, None, Const(other)), + None + ) def cos(value): if isinstance(value, (float, int)): diff --git a/pendule_a_ressort.py b/pendule_a_ressort.py index 421660e..6eba8b7 100644 --- a/pendule_a_ressort.py +++ b/pendule_a_ressort.py @@ -14,7 +14,7 @@ r = lgc.Var() x = r * lgc.cos(theta) y = r * lgc.sin(theta) -T = 0.5 * m * (x.diff()*x.diff() + y.diff()*y.diff()) +T = 0.5 * m * (x.diff()**2 + y.diff()**2) V = m * g * r * lgc.cos(theta) + k * (r - r0) * (r - r0) L = T - V diff --git a/pendule_simple.py b/pendule_simple.py index 6151969..59a333a 100644 --- a/pendule_simple.py +++ b/pendule_simple.py @@ -8,12 +8,11 @@ m = lgc.Const(1) r = lgc.Const(1) theta = lgc.Var() -print(theta.name) x = r * lgc.cos(theta) y = r * lgc.sin(theta) -T = 0.5 * m * (x.diff()*x.diff() + y.diff()*y.diff()) +T = 0.5 * m * (x.diff()**2 + y.diff()**2) V = m * g * r * lgc.cos(theta) L = T - V