#!/usr/bin/env catnip
# Calcul symbolique avec SymPy
# Variables, dérivation, intégration, résolution d'équations
#
# DEPS: sympy
sympy = import('sympy')
# Symboles (avec hypothèses: réels)
x = sympy.Symbol("x", real=True)
y = sympy.Symbol("y", real=True)
t = sympy.Symbol("t", real=True)
print("⇒ Expressions et simplification")
p = x ** 2 + 2 * x + 1
print(" p(x) =", p)
print(" factor(p) =", sympy.factor(p))
print(" p(3) =", p.subs(x, 3))
print(" p(3) numérique =", sympy.N(p.subs(x, 3), 8))
identite = sympy.sin(x) ** 2 + sympy.cos(x) ** 2
print(" sin(x)^2 + cos(x)^2 =", identite)
print(" simplifié =", sympy.simplify(identite))
print()
print("⇒ Développement / factorisation")
expanded = sympy.expand((x + y) ** 4)
print(" expand((x+y)^4) =", expanded)
print(" factor(expand(...)) =", sympy.factor(expanded))
print()
print("⇒ Dérivées")
f = sympy.exp(-x ** 2)
df = sympy.diff(f, x)
d2f = sympy.diff(f, x, 2)
print(" f(x) =", f)
print(" f'(x) =", df)
print(" f''(x) =", d2f)
# Dérivées partielles et gradient
g = x ** 2 * sympy.sin(y)
grad_g = list(sympy.diff(g, x), sympy.diff(g, y))
print(" g(x,y) =", g)
print(" ∂g/∂x =", grad_g[0])
print(" ∂g/∂y =", grad_g[1])
print(" grad(g) =", grad_g)
print()
print("⇒ Intégrales")
print(" ∫ x^2 dx =", sympy.integrate(x ** 2, x))
int_0_1 = sympy.integrate(x ** 2, tuple(x, 0, 1))
print(" ∫_0^1 x^2 dx =", int_0_1)
print(" valeur numérique =", sympy.N(int_0_1, 10))
# Intégrale impropre gaussienne
gauss = sympy.integrate(sympy.exp(-x ** 2), tuple(x, -sympy.oo, sympy.oo))
print(" ∫_{-∞}^{+∞} exp(-x^2) dx =", gauss)
print(" valeur numérique =", sympy.N(gauss, 10))
print()
print("⇒ Équations")
sols = sympy.solve(x ** 2 - 5 * x + 6, x)
print(" x^2 - 5x + 6 = 0 ->", sols)
# Système linéaire
sol_sys = sympy.solve(list(x + y - 5, x - y - 1), list(x, y))
print(" x+y=5, x-y=1 ->", sol_sys)
# Équation différentielle: f' + f = 0
f_sym = sympy.Function("f")
ode = sympy.Eq(f_sym(t).diff(t) + f_sym(t), 0)
sol_ode = sympy.dsolve(ode, f_sym(t))
print(" f'(t)+f(t)=0 ->", sol_ode)
print()
print("⇒ Limites et séries")
print(" lim(sin(x)/x, x->0) =", sympy.limit(sympy.sin(x) / x, x, 0))
print(" lim((1+1/x)^x, x->∞) =", sympy.limit((1 + 1 / x) ** x, x, sympy.oo))
taylor = sympy.series(sympy.cos(x), x, 0, n=6)
print(" série de Taylor de cos(x) à l'ordre 5 =", taylor)
print()
print("⇒ Matrices symboliques")
M = sympy.Matrix(list(list(1, x), list(x, 1)))
print(" M =", M)
print(" det(M) =", M.det())
print(" M^{-1} =", M.inv())
print(" valeurs propres =", M.eigenvals())