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 ```bash
# Dépendances requises # Dépendances requises
pip install numpy matplotlib tqdm pip install numpy matplotlib tqdm inspect dis
``` ```
## API Principale ## API Principale

View file

@ -2,8 +2,6 @@ import legrandchien as lgc
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import matplotlib.animation as animation import matplotlib.animation as animation
import numpy as np import numpy as np
import cProfile
import pstats
g = lgc.Const(-10) g = lgc.Const(-10)
m1 = lgc.Const(1) m1 = lgc.Const(1)
@ -20,8 +18,8 @@ y1 = r1 * lgc.sin(theta1)
x2 = x1 + r2 * lgc.cos(theta2) x2 = x1 + r2 * lgc.cos(theta2)
y2 = y1 + r2 * lgc.sin(theta2) y2 = y1 + r2 * lgc.sin(theta2)
T = 0.5 * m1 * (x1.diff()*x1.diff() + y1.diff()*y1.diff()) T = 0.5 * m1 * (x1.diff()**2 + y1.diff()**2)
T += 0.5 * m2 * (x2.diff()*x2.diff() + y2.diff()*y2.diff()) T += 0.5 * m2 * (x2.diff()**2 + y2.diff()**2)
V = m1 * g * x1 V = m1 * g * x1
V += m2 * g * x2 V += m2 * g * x2

View file

@ -22,8 +22,8 @@ y1 = r1 * lgc.sin(theta1)
x2 = x1 + r2 * lgc.cos(theta2) x2 = x1 + r2 * lgc.cos(theta2)
y2 = y1 + r2 * lgc.sin(theta2) y2 = y1 + r2 * lgc.sin(theta2)
T = 0.5 * m1 * (x1.diff()*x1.diff() + y1.diff()*y1.diff()) T = 0.5 * m1 * (x1.diff()**2 + y1.diff()**2)
T += 0.5 * m2 * (x2.diff()*x2.diff() + y2.diff()*y2.diff()) T += 0.5 * m2 * (x2.diff()**2 + y2.diff()**2)
V = m1 * g * x1 V = m1 * g * x1
V += m2 * g * x2 V += m2 * g * x2

View file

@ -29,6 +29,12 @@ class Const:
def copy(self): def copy(self):
return Const(self.value) return Const(self.value)
def simplify(self):
pass
def __str__(self):
return str(self.value)
def __add__(self, other): def __add__(self, other):
if other.type == "Const": if other.type == "Const":
@ -177,6 +183,15 @@ class Const:
def __truediv__(self, other): def __truediv__(self, other):
if isinstance(other, (int, float)): if isinstance(other, (int, float)):
return Const(other) / self return Const(other) / self
def __pow__(self, other):
if isinstance(other, (int, float)):
return Equation(
Operation.CONST,
None,
None,
self.value ** other
)
# var class # var class
class Var: class Var:
@ -363,6 +378,15 @@ class Var:
def __rtruediv__(self, other): def __rtruediv__(self, other):
if isinstance(other, (int, float)): if isinstance(other, (int, float)):
return Const(other) / self 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 # equation class
class Equation: class Equation:
@ -401,6 +425,16 @@ class Equation:
return self.value.diff() * Equation(Operation.COS, None, None, self.value.copy()) return self.value.diff() * Equation(Operation.COS, None, None, self.value.copy())
if self.op == Operation.COS: if self.op == Operation.COS:
return Const(-1) * self.value.diff() * Equation(Operation.SIN, None, None, self.value.copy()) 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): def partial(self, var_name):
if self.op == Operation.CONST: 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()) return self.value.partial(var_name) * Equation(Operation.COS, None, None, self.value.copy())
if self.op == Operation.COS: if self.op == Operation.COS:
return Const(-1) * self.value.partial(var_name) * Equation(Operation.SIN, None, None, self.value.copy()) 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): def compile(self):
if self.compiled_function is not None: if self.compiled_function is not None:
@ -473,6 +517,11 @@ class Equation:
val_code, var_count = self.value._generate_code_recursive(var_count) val_code, var_count = self.value._generate_code_recursive(var_count)
return (f"np.cos({val_code})", 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) return ("0", var_count)
def evaluate(self, dico): def evaluate(self, dico):
@ -506,7 +555,7 @@ class Equation:
dico[var.name] = 0. dico[var.name] = 0.
# print([var.name for var in unknown]) # print([var.name for var in unknown])
# print(equations[0]) print(equations[0])
assert(len(unknown) == len(equations)) assert(len(unknown) == len(equations))
n = len(unknown) n = len(unknown)
@ -603,12 +652,12 @@ class Equation:
if self.op in {Operation.SIN, Operation.COS}: if self.op in {Operation.SIN, Operation.COS}:
self.value.simplify() self.value.simplify()
if self.op == Operation.CONST: elif self.op == Operation.CONST:
pass pass
if self.op == Operation.VAR: elif self.op == Operation.VAR:
pass pass
if self.op == Operation.ADD: elif self.op == Operation.ADD:
if self.left.op == Operation.CONST and self.right.op == Operation.CONST: if self.left.op == Operation.CONST and self.right.op == Operation.CONST:
self.op = Operation.CONST self.op = Operation.CONST
self.value = Const(self.left.value.value + self.right.value.value) self.value = Const(self.left.value.value + self.right.value.value)
@ -625,7 +674,7 @@ class Equation:
self.value = self.left.value self.value = self.left.value
self.left = self.left.left 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: if self.left.op == Operation.CONST and self.right.op == Operation.CONST:
self.op = Operation.CONST self.op = Operation.CONST
self.value = Const(self.left.value.value - self.right.value.value) 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: elif self.right.op == Operation.CONST and self.right.value.value == 0:
self = self.left 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: if self.left.op == Operation.CONST and self.right.op == Operation.CONST:
self.op = Operation.CONST self.op = Operation.CONST
self.value = Const(self.left.value.value * self.right.value.value) self.value = Const(self.left.value.value * self.right.value.value)
@ -661,19 +710,36 @@ class Equation:
self.value = self.left.value self.value = self.left.value
self.left = self.left.left self.left = self.left.left
if self.op == Operation.SIN: elif self.op == Operation.SIN:
if self.value.op == Operation.CONST: if self.value.op == Operation.CONST:
self.op = Operation.CONST self.op = Operation.CONST
self.left = None self.left = None
self.right = None self.right = None
self.value = Const(np.sin(self.value.value)) self.value = Const(np.sin(self.value.value))
if self.op == Operation.COS: elif self.op == Operation.COS:
if self.value.op == Operation.CONST: if self.value.op == Operation.CONST:
self.op = Operation.CONST self.op = Operation.CONST
self.left = None self.left = None
self.right = None self.right = None
self.value = Const(np.cos(self.value.value)) 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): def __str__(self):
if self.op == Operation.CONST: if self.op == Operation.CONST:
@ -692,6 +758,8 @@ class Equation:
return f"sin({str(self.value)})" return f"sin({str(self.value)})"
if self.op == Operation.COS: if self.op == Operation.COS:
return f"cos({str(self.value)})" return f"cos({str(self.value)})"
if self.op == Operation.POW:
return f"({str(self.left)})**({str(self.right)})"
def __add__(self, other): def __add__(self, other):
if other.type == "Const": if other.type == "Const":
@ -780,6 +848,15 @@ class Equation:
def __rtruediv__(self, other): def __rtruediv__(self, other):
if isinstance(other, (int, float)): if isinstance(other, (int, float)):
return Const(other) / self 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): def cos(value):
if isinstance(value, (float, int)): if isinstance(value, (float, int)):

View file

@ -14,7 +14,7 @@ r = lgc.Var()
x = r * lgc.cos(theta) x = r * lgc.cos(theta)
y = r * lgc.sin(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) V = m * g * r * lgc.cos(theta) + k * (r - r0) * (r - r0)
L = T - V L = T - V

View file

@ -8,12 +8,11 @@ m = lgc.Const(1)
r = lgc.Const(1) r = lgc.Const(1)
theta = lgc.Var() theta = lgc.Var()
print(theta.name)
x = r * lgc.cos(theta) x = r * lgc.cos(theta)
y = r * lgc.sin(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) V = m * g * r * lgc.cos(theta)
L = T - V L = T - V