all partial derivation
This commit is contained in:
parent
073de786f5
commit
431570ce73
3 changed files with 143 additions and 31 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
__pycache__
|
||||||
22
example.py
22
example.py
|
|
@ -1,7 +1,21 @@
|
||||||
from legrandchien import *
|
import legrandchien as lgc
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
k = Const(3)
|
g = lgc.Const(-10)
|
||||||
kk = Const(4)
|
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))
|
||||||
151
legrandchien.py
151
legrandchien.py
|
|
@ -20,13 +20,20 @@ class Const:
|
||||||
self.value = value
|
self.value = value
|
||||||
self.type = "Const"
|
self.type = "Const"
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate(self, dico):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
return Const(self.value)
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) + Equation(
|
) + Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -38,7 +45,7 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) + Equation(
|
) + Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -50,16 +57,20 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) + other
|
) + other
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) + self
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) - Equation(
|
) - Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -71,7 +82,7 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) - Equation(
|
) - Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -83,16 +94,20 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) - other
|
) - other
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) - self
|
||||||
|
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) * Equation(
|
) * Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -104,7 +119,7 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) * Equation(
|
) * Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -116,16 +131,20 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) * other
|
) * other
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) * self
|
||||||
|
|
||||||
def __truediv__(self, other):
|
def __truediv__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) / Equation(
|
) / Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -137,7 +156,7 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) / Equation(
|
) / Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -149,8 +168,12 @@ class Const:
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.value
|
self.copy()
|
||||||
) / other
|
) / other
|
||||||
|
|
||||||
|
def __truediv__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) / self
|
||||||
|
|
||||||
# var class
|
# var class
|
||||||
class Var:
|
class Var:
|
||||||
|
|
@ -159,13 +182,22 @@ class Var:
|
||||||
self.type = "Var"
|
self.type = "Var"
|
||||||
self.degree = degree
|
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):
|
def __add__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) + Equation(
|
) + Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -177,7 +209,7 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) + Equation(
|
) + Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -189,16 +221,20 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) + other
|
) + other
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) + self
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) - Equation(
|
) - Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -210,7 +246,7 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) - Equation(
|
) - Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -222,16 +258,20 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) - other
|
) - other
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) - self
|
||||||
|
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) * Equation(
|
) * Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -243,7 +283,7 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) * Equation(
|
) * Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -255,16 +295,20 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) * other
|
) * other
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) * self
|
||||||
|
|
||||||
def __truediv__(self, other):
|
def __truediv__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return Equation(
|
return Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) / Equation(
|
) / Equation(
|
||||||
Operation.CONST,
|
Operation.CONST,
|
||||||
None,
|
None,
|
||||||
|
|
@ -276,7 +320,7 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) / Equation(
|
) / Equation(
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
|
|
@ -288,8 +332,12 @@ class Var:
|
||||||
Operation.VAR,
|
Operation.VAR,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
self.name
|
self.copy()
|
||||||
) / other
|
) / other
|
||||||
|
|
||||||
|
def __rtruediv__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) / self
|
||||||
|
|
||||||
# equation class
|
# equation class
|
||||||
class Equation:
|
class Equation:
|
||||||
|
|
@ -305,13 +353,13 @@ class Equation:
|
||||||
return Const(self.value.value)
|
return Const(self.value.value)
|
||||||
if self.op == Operation.VAR:
|
if self.op == Operation.VAR:
|
||||||
return Var(self.value.name, self.value.degree)
|
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):
|
def diff(self):
|
||||||
if self.op == Operation.CONST:
|
if self.op == Operation.CONST:
|
||||||
return Const(0)
|
return Equation(Operation.CONST, None, None, Const(0))
|
||||||
if self.op == Operation.VAR:
|
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:
|
if self.op == Operation.ADD:
|
||||||
return self.left.diff() + self.right.diff()
|
return self.left.diff() + self.right.diff()
|
||||||
if self.op == Operation.SUB:
|
if self.op == Operation.SUB:
|
||||||
|
|
@ -322,6 +370,39 @@ class Equation:
|
||||||
return (self.left.diff()*self.right.copy() - self.left.copy()*self.right.diff()) \
|
return (self.left.diff()*self.right.copy() - self.left.copy()*self.right.diff()) \
|
||||||
/ (self.right.copy()*self.right.copy())
|
/ (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):
|
def __add__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return self + Equation(
|
return self + Equation(
|
||||||
|
|
@ -340,6 +421,10 @@ class Equation:
|
||||||
if other.type == "Equation":
|
if other.type == "Equation":
|
||||||
return Equation(Operation.ADD, self, other, None)
|
return Equation(Operation.ADD, self, other, None)
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) + self
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return self - Equation(
|
return self - Equation(
|
||||||
|
|
@ -358,6 +443,10 @@ class Equation:
|
||||||
if other.type == "Equation":
|
if other.type == "Equation":
|
||||||
return Equation(Operation.SUB, self, other, None)
|
return Equation(Operation.SUB, self, other, None)
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) - self
|
||||||
|
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return self * Equation(
|
return self * Equation(
|
||||||
|
|
@ -376,6 +465,10 @@ class Equation:
|
||||||
if other.type == "Equation":
|
if other.type == "Equation":
|
||||||
return Equation(Operation.MULT, self, other, None)
|
return Equation(Operation.MULT, self, other, None)
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) * self
|
||||||
|
|
||||||
def __truediv__(self, other):
|
def __truediv__(self, other):
|
||||||
if other.type == "Const":
|
if other.type == "Const":
|
||||||
return self / Equation(
|
return self / Equation(
|
||||||
|
|
@ -393,3 +486,7 @@ class Equation:
|
||||||
)
|
)
|
||||||
if other.type == "Equation":
|
if other.type == "Equation":
|
||||||
return Equation(Operation.DIV, self, other, None)
|
return Equation(Operation.DIV, self, other, None)
|
||||||
|
|
||||||
|
def __rtruediv__(self, other):
|
||||||
|
if isinstance(other, (int, float)):
|
||||||
|
return Const(other) / self
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue