now support power operation
This commit is contained in:
parent
e042a9f9d5
commit
292b99e821
6 changed files with 92 additions and 18 deletions
|
|
@ -28,7 +28,7 @@ LeGrandChien/
|
|||
|
||||
```bash
|
||||
# Dépendances requises
|
||||
pip install numpy matplotlib tqdm
|
||||
pip install numpy matplotlib tqdm inspect dis
|
||||
```
|
||||
|
||||
## API Principale
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue