diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/example.py b/example.py index 0a8f06e..c276946 100644 --- a/example.py +++ b/example.py @@ -1,7 +1,21 @@ -from legrandchien import * +import legrandchien as lgc if __name__ == "__main__": - k = Const(3) - kk = Const(4) + g = lgc.Const(-10) + m = lgc.Const(1) - eq = k + kk + x = lgc.Var("x") + + T = 0.5 * m * x.diff() * x.diff() + V = m * g * x + L = T - V + + dL = L.diff() + + dico = { + "x" : 0, + "d_x" : 1, + "d_d_x" : 1, + } + + print(dL.evaluate(dico)) \ No newline at end of file diff --git a/legrandchien.py b/legrandchien.py index 14f94fe..202792e 100644 --- a/legrandchien.py +++ b/legrandchien.py @@ -20,13 +20,20 @@ class Const: self.value = value self.type = "Const" + + def evaluate(self, dico): + return self.value + + def copy(self): + return Const(self.value) + def __add__(self, other): if other.type == "Const": return Equation( Operation.CONST, None, None, - self.value + self.copy() ) + Equation( Operation.CONST, None, @@ -38,7 +45,7 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) + Equation( Operation.VAR, None, @@ -50,16 +57,20 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) + other + def __radd__(self, other): + if isinstance(other, (int, float)): + return Const(other) + self + def __sub__(self, other): if other.type == "Const": return Equation( Operation.CONST, None, None, - self.value + self.copy() ) - Equation( Operation.CONST, None, @@ -71,7 +82,7 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) - Equation( Operation.VAR, None, @@ -83,16 +94,20 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) - other + def __rsub__(self, other): + if isinstance(other, (int, float)): + return Const(other) - self + def __mul__(self, other): if other.type == "Const": return Equation( Operation.CONST, None, None, - self.value + self.copy() ) * Equation( Operation.CONST, None, @@ -104,7 +119,7 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) * Equation( Operation.VAR, None, @@ -116,16 +131,20 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) * other + def __rmul__(self, other): + if isinstance(other, (int, float)): + return Const(other) * self + def __truediv__(self, other): if other.type == "Const": return Equation( Operation.CONST, None, None, - self.value + self.copy() ) / Equation( Operation.CONST, None, @@ -137,7 +156,7 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) / Equation( Operation.VAR, None, @@ -149,8 +168,12 @@ class Const: Operation.CONST, None, None, - self.value + self.copy() ) / other + + def __truediv__(self, other): + if isinstance(other, (int, float)): + return Const(other) / self # var class class Var: @@ -159,13 +182,22 @@ class Var: self.type = "Var" self.degree = degree + def copy(self): + return Var(self.name, self.degree) + + def diff(self, n=1): + return Var("d_"+self.name, self.degree+n) + + def evaluate(self, dico): + return dico[self.name] + def __add__(self, other): if other.type == "Const": return Equation( Operation.VAR, None, None, - self.name + self.copy() ) + Equation( Operation.CONST, None, @@ -177,7 +209,7 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) + Equation( Operation.VAR, None, @@ -189,16 +221,20 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) + other + def __radd__(self, other): + if isinstance(other, (int, float)): + return Const(other) + self + def __sub__(self, other): if other.type == "Const": return Equation( Operation.VAR, None, None, - self.name + self.copy() ) - Equation( Operation.CONST, None, @@ -210,7 +246,7 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) - Equation( Operation.VAR, None, @@ -222,16 +258,20 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) - other + def __rsub__(self, other): + if isinstance(other, (int, float)): + return Const(other) - self + def __mul__(self, other): if other.type == "Const": return Equation( Operation.VAR, None, None, - self.name + self.copy() ) * Equation( Operation.CONST, None, @@ -243,7 +283,7 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) * Equation( Operation.VAR, None, @@ -255,16 +295,20 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) * other + def __rmul__(self, other): + if isinstance(other, (int, float)): + return Const(other) * self + def __truediv__(self, other): if other.type == "Const": return Equation( Operation.VAR, None, None, - self.name + self.copy() ) / Equation( Operation.CONST, None, @@ -276,7 +320,7 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) / Equation( Operation.VAR, None, @@ -288,8 +332,12 @@ class Var: Operation.VAR, None, None, - self.name + self.copy() ) / other + + def __rtruediv__(self, other): + if isinstance(other, (int, float)): + return Const(other) / self # equation class class Equation: @@ -305,13 +353,13 @@ class Equation: return Const(self.value.value) if self.op == Operation.VAR: return Var(self.value.name, self.value.degree) - return Operation(self.op, self.left.copy(), self.right.copy(), None) + return Equation(self.op, self.left.copy(), self.right.copy(), None) def diff(self): if self.op == Operation.CONST: - return Const(0) + return Equation(Operation.CONST, None, None, Const(0)) if self.op == Operation.VAR: - return Var(self.value.name, self.value.degree+1) + return Equation(Operation.VAR, None, None, Var("d_"+self.value.name, self.value.degree+1)) if self.op == Operation.ADD: return self.left.diff() + self.right.diff() if self.op == Operation.SUB: @@ -322,6 +370,39 @@ class Equation: return (self.left.diff()*self.right.copy() - self.left.copy()*self.right.diff()) \ / (self.right.copy()*self.right.copy()) + def partial(self, var_name): + if self.op == Operation.CONST: + return Equation(Operation.CONST, None, None, Const(0)) + if self.op == Operation.VAR: + if self.value.name == var_name: + return Equation(Operation.CONST, None, None, Const(1)) + else: + return Equation(Operation.CONST, None, None, Const(0)) + if self.op == Operation.ADD: + return self.left.partial(var_name) + self.right.partial(var_name) + if self.op == Operation.SUB: + return self.left.partial(var_name) - self.right.partial(var_name) + if self.op == Operation.MULT: + return self.left.partial(var_name)*self.right.copy() + self.left.copy()*self.right.partial(var_name) + if self.op == Operation.DIV: + return (self.left.partial(var_name)*self.right.copy() - self.left.copy()*self.right.partial(var_name)) \ + / (self.right.copy()*self.right.copy()) + + 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) + + def __add__(self, other): if other.type == "Const": return self + Equation( @@ -340,6 +421,10 @@ class Equation: if other.type == "Equation": return Equation(Operation.ADD, self, other, None) + def __radd__(self, other): + if isinstance(other, (int, float)): + return Const(other) + self + def __sub__(self, other): if other.type == "Const": return self - Equation( @@ -358,6 +443,10 @@ class Equation: if other.type == "Equation": return Equation(Operation.SUB, self, other, None) + def __rsub__(self, other): + if isinstance(other, (int, float)): + return Const(other) - self + def __mul__(self, other): if other.type == "Const": return self * Equation( @@ -376,6 +465,10 @@ class Equation: if other.type == "Equation": return Equation(Operation.MULT, self, other, None) + def __rmul__(self, other): + if isinstance(other, (int, float)): + return Const(other) * self + def __truediv__(self, other): if other.type == "Const": return self / Equation( @@ -393,3 +486,7 @@ class Equation: ) if other.type == "Equation": return Equation(Operation.DIV, self, other, None) + + def __rtruediv__(self, other): + if isinstance(other, (int, float)): + return Const(other) / self