diff --git a/legrandchien.py b/legrandchien.py index 42fa1b7..b116d70 100644 --- a/legrandchien.py +++ b/legrandchien.py @@ -358,6 +358,7 @@ class Equation: self.right = right self.value = value self.type = "Equation" + self.compiled_function = None def copy(self): if self.op == Operation.CONST: @@ -408,24 +409,44 @@ 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()) + + def compile(self): + if self.compiled_function is not None: + return self.compiled_function + + if self.op == Operation.CONST: + self.compiled_function = lambda dico : self.value.value + if self.op == Operation.VAR: + self.compiled_function = lambda dico : dico[self.value.name] + if self.op == Operation.ADD: + left_func = self.left.compile() + right_func = self.right.compile() + self.compiled_function = lambda dico : left_func(dico) + right_func(dico) + if self.op == Operation.SUB: + left_func = self.left.compile() + right_func = self.right.compile() + self.compiled_function = lambda dico : left_func(dico) - right_func(dico) + if self.op == Operation.MULT: + left_func = self.left.compile() + right_func = self.right.compile() + self.compiled_function = lambda dico : left_func(dico) * right_func(dico) + if self.op == Operation.DIV: + left_func = self.left.compile() + right_func = self.right.compile() + self.compiled_function = lambda dico : left_func(dico) / right_func(dico) + if self.op == Operation.SIN: + value_func = self.value.compile() + self.compiled_function = lambda dico : np.sin(value_func(dico)) + if self.op == Operation.COS: + value_func = self.value.compile() + self.compiled_function = lambda dico : np.cos(value_func(dico)) + + return self.compiled_function def evaluate(self, dico): - if self.op == Operation.CONST: - return self.value.value - if self.op == Operation.VAR: - return dico[self.value.name] - if self.op == Operation.ADD: - return self.left.evaluate(dico) + self.right.evaluate(dico) - if self.op == Operation.SUB: - return self.left.evaluate(dico) - self.right.evaluate(dico) - if self.op == Operation.MULT: - return self.left.evaluate(dico) * self.right.evaluate(dico) - if self.op == Operation.DIV: - return self.left.evaluate(dico) / self.right.evaluate(dico) - if self.op == Operation.SIN: - return np.sin(self.value.evaluate(dico)) - if self.op == Operation.COS: - return np.cos(self.value.evaluate(dico)) + if self.compiled_function is None: + self.compile() + return self.compiled_function(dico) def solve(self, dico, tmax=10, dt=0.01): self.simplify()