now support power operation

This commit is contained in:
Didictateur 2026-02-17 18:52:11 +01:00
parent e042a9f9d5
commit 292b99e821
6 changed files with 92 additions and 18 deletions

View file

@ -28,7 +28,7 @@ LeGrandChien/
```bash
# Dépendances requises
pip install numpy matplotlib tqdm
pip install numpy matplotlib tqdm inspect dis
```
## API Principale

View file

@ -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

View file

@ -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

View file

@ -30,6 +30,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":
return Equation(
@ -178,6 +184,15 @@ class Const:
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:
def __init__(self, name=None, degree=0) -> None:
@ -364,6 +379,15 @@ class Var:
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:
def __init__(self, op, left, right, value):
@ -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,20 +710,37 @@ 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:
return str(self.value.value)
@ -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":
@ -781,6 +849,15 @@ class Equation:
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)):
return Equation(Operation.CONST, None, None, np.cos(value))

View file

@ -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

View file

@ -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