More is less

vendredi 18 août 2017

Sympy

sympy est un module python de calcul formel (calcul symbolique). Il n'a pas à rougir de ses concurrents sauf peut-être pour la rapidité d'exécution. Nous aborderons ici quelques calculs d'analyse du niveau de terminale.

Table des matières

Démarrage rapide

Installation

Le module sympy a peu de dépendances. Selon la distribution il s'installe avec :

Archlinux
sudo pacman -S python-sympy
Debian, ubuntu, ...
sudo apt-get install python-sympy
Fedora
sudo dnf install python3-sympy

On peut aussi l'installer avec git.

Doc officielle

Premiers pas

Comme d'habitude il faut importer le module, ou seulement certaines fonctionnalités.

from sympy import *

Au départ aucune variable n'est définie. Si on veut utiliser x on tape

x = Symbol('x') # or x = symbols('x')

On peut définir plus d'une variable :

x, y, t = symbols('x y t')

Ou carrément :

from sympy.abc import x, y, z, t, eta, mu

Exemple de session interactive :

>>> from sympy import *
>>> from sympy.abc import a, b, c, x, t
>>> solve(a*x**2 + b*x + c, x)
[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]
>>>

C'est une vérification des racines de l'équation du second degré : $ax^{2}+bx+c=0$.

Remarques:

sympy ne semble pas se soucier du signe de $\sqrt{b^{2}-4ac}$

On peut avoir un affichage plus «agréable» avec pprint(_) (pretty print)

>>> pprint(_)
⎡        _____________   ⎛       _____________⎞ ⎤
⎢       ╱           2    ⎜      ╱           2 ⎟ ⎥
⎢-b + ╲╱  -4⋅a⋅c + b    -⎝b + ╲╱  -4⋅a⋅c + b  ⎠ ⎥
⎢─────────────────────, ────────────────────────⎥
⎣         2⋅a                     2⋅a           ⎦
>>> 

Quelques calculs

Ici on factorise une expression puis on dérive. Les fonctions factor et diff ne transforment pas l'expression en place. Elles renvoient le résultat escompté.

>>> x = 4*t**2 - 6*t
>>> factor(x)
2*t*(2*t - 3)
>>> x
4*t**2 - 6*t
>>> diff(x, t)
8*t - 6

Pour d'autres exemples de calcul voyez la doc officielle Sympy Tutorial

Sympy quel intérêt ?

Il existe de nombreux logiciels libres ou propriétaires de calcul formel. Pour celui qui connait un peu (ou beaucoup) python, il offre les avantages de python.

Table des matières

Diff : dérivée

Un brin d'histoire

Au XVIIe siecle une des préoccupations des mathématiciens était la pente de la tangente à courbe. C'est à Leibniz (1) qu'on doit les bases du calcul différentiel et de la notation dx.

Il avait démontré les formules :

$$d(u+v)=du +dv$$

$$ d(λu)=λdu$$

$$ d(u.v)=v.du+u.dv

$$d\left(\frac{u}{v}\right)=\frac{vdu-udv}{v^{2}}$$.

En étudiant ce qu'il apppelle le triangle caractéristique (figure ci-dessus (2)) il a établi la relation entre dérivée et tangente.

Rappels

Par définition, le nombre dérivé en $a$ de la fonction $f$ est la limite, si elle existe, de :

$$f\prime(a)=\lim_{e\to 0} \frac{f(a+e) -f(a)}{e}$$

C'est la pente de la tangente en a.

Les formules de Leibniz ci-dessus se traduisent par :

$$(u+v)\prime=u\prime+v\prime$$

$$(λu)\prime=λu\prime$$

$$(uv)\prime=u\primev + uv\prime$$

$$(\frac{u}{v})\prime=\frac{u\primev-uv\prime}{v^{2}}$$

Avec ces formules on peut presque tout faire, à condition de connaitre les dérivées des fonctions usuelles. Sur le web il y a pléthore de sites et de fiches qui les donnent et qui parfois les démontrent.

En voici quelques unes

$f(x)$ $ax + b$ $x^{n}$ $$\frac{1}{x}$$ $\sqrt{x}$ $\cos{x}$ $\sin{x}$$\tan{x}$ $ln x$ $$e^{x}$$
$f'(x)$ $a$ $nx^{n-1}$ $$-\frac{1}{x^{2}}$$ $$\frac{1}{2\sqrt{x}}$$ $-\sin{x}$$\cos{x}$$$1+\tan^{2}{x}$$$$\frac{1}{x}$$$$e^{x}$$

On peut se servir de sympy pour se rafraichir la mémoire :

>>> from sympy import *
>>> x, a, b, n = symbols('x a b n')
>>> diff(a*x+b, x)
a
>>> diff(x**n, x)
n*x**n/x
>>> diff(1/x)  # en mode interactif on peut oublier de préciser la variable
-1/x**2        # dans un script sympy lève une exeption
>>> diff(sqrt(x))
1/(2*sqrt(x))
>>> diff(cos(x))
-sin(x)
>>> diff(tan(x), x)
tan(x)**2 + 1  # une autre forme est 1/cos(x)**2, car cos(x)**2 + sin(x)**2 = 1

Ainsi donc, en mode interactif sympy accepte diff(exp(x)). Dans un script, non. On doit préciser la variable de dérivation diff(exp(x), x).

Doc officielle

Table des matières

Integrate

Histoire

En cette fin de XVIIe tous les matheux comprenaient le lien entre différenciation et intégration. C'est encore à Leibnitz qu'ont doit la formule $dS=ydx$.

Intégrale indéfinie (primitive)

Exemple :

>>> from sympy import *
>>> var('x')
x
>>> integrate(x*log(x), x)
x**2*log(x)/2 - x**2/4
>>> diff(_, x)
x*log(x)

Parfois sympy n'y arrive pas. Il rame un peu, puis affiche l'intégrale demandée :

>>> integrate(x*sqrt(4 - x)*sin(x), x)
Integral(x*sqrt(-x + 4)*sin(x), x)

En fait la primitive ne peut pas s'écrire avec les fonctions usuelles.

Intégrale définie

Commençons par un exemple historique. Archimède avait calculé l'aire sous la parabole au IIIe siècle avant J.C. On va demander à sympy l'intégrale

$$\int_{-1}^{1} (1 - x^{2}) \mathrm{d}x = \left[x - \frac{x^{3}}{3}\right]_{-1}^{1} = \frac{4}{3}$$

>>> integrate(1 - x**2, (x, -1, 1))
4/3

Ce qui est bien vrai.

Un autre exemple classique : l'intégrale de Gauss

$$\int_{-\infty}^{\infty} e^{-x^{2}}dx = \sqrt{\pi}$$

>>> integrate(exp(-x**2), (x, -oo, oo))
sqrt(pi)

Cependant l'intégrale indéfinie donne :

>>> integrate(exp(-x**2), x)
sqrt(pi)*erf(x)/2

Ce qui est tout à fait juste. Voir l'intégrale de Gauss et la fonction d'erreur de Gauss.

Table des matières

Limit

La signature de limit est limit(f, x, xlim, dir='+'). Voici quelques calculs.

$$\lim_{x \to \frac{\pi}{2}^+} (x - \frac{\pi}{2})\tan{x} \quad et \quad \lim_{x \to 0^+ } x\ln{x}$$

>>> limit((x - pi/2)*tan(x), x, pi/2)
-1
>>> y=x*log(x)
>>> y.limit(x, 0)
0

Par défaut le calcul se fait à gauche.

Histoire

Jusqu'au XIXe, le vocabulaire et les notations étaient approximatives. Même chez Gauss, qui pourtant était une teigne. C'est avec Bolzano et Weierstass que la définition avec les quantificateurs a été adoptée ($\forall \epsilon > 0, \exists \eta > 0, |x - x_0| < \eta \Rightarrow |f(x) - f(x_0)| < \epsilon$). Quand on écrivait ça au tableau, les sourcils se fronçaient. Depuis un demi-siècle l'analyse non standard permet d'utiliser les i-petit et les i-grand comme du temps de Leibniz, mais avec toute la rigueur nécessaire.

Enseignement

En lycée on écrit sans vergogne $+\infty$, $-\infty$, $0^+$, et $0^-$. Mais n'ose pas écrire $f(\infty)$ ou $f(0^-)$. Qu'est-ce ça apporte d'écrire $\lim_{x \to 0^+ }$ ? Surtout que les nouveaux programmes stipulent On ne donne pas de définition formelle de la notion de limite.

Voici un module en python qui définit une class Func qui utilise sympy et qui calcule f(oo), f('0+') sans s'encombrer de la notation limit(f, x, x0, '+').

#!/usr/bin/env python3
# nsa.py Non standard analysis
# (c) 2017 Released under the GPL by marnout à free pt fr
#
from sympy import *
from builtins import eval as beval
#
class Func():
   """
   Non-standard analysis
   Function using infinitesimal numbers, e.g. '2-' oo
   Usage:
      >>> from sympy import *
      >>> from nsa import Func
      >>> var('x')
      x
      >>> f = Func(x, x/(x - 2))
      >>> f(1)
      -1
      >>> f('2+')
      oo
      >>> f(oo)
      1
      >>> f(-oo)
      1
      >>> f('2-')
      -oo
   """
   #
   def __init__(self, var, expr):
      """
      :var e.g. x
      :expr expression e.g. x/(x**2 - 4) 
      """
      self.x, self.expr = var, expr
   #  
   def __call__(self, arg):
      """
      : arg argument e.g. 2, oo, -oo, '1+', '1-'
      return numerical evaluation of expr at arg
      """
      if arg == oo or arg == -oo:
         return self.expr.limit(self.x, arg)
      elif isinstance(arg, str) and len(arg) > 1 and arg[-1] in "+-":
         n, s = arg[:-1], arg[-1]
         return self.expr.limit(self.x, float(n), s)
      elif N(arg).is_real:
         return self.expr.subs(self.x, arg)
   #     
   def prime(self, a=None):
      " derivative: symbolic if a == None, else at 'a' "
      prime = diff(self.expr, self.x)
      if a == None: return prime
      else: return prime.subs(self.x, a)



if __name__ == '__main__':

   #smart print from mourad
   def sprint(s): print(s,"=", eval(s))
   # variable
   var('t')
   # function
   f = Func(t, t/(t - 1))
   # display function
   pprint(f.expr)
   # tests
   sprint("f(5)")
   sprint("f(oo)")
   sprint("f('1+')")
   sprint("f.prime(2)")

Table des matières

(1)

Une polémique entre les supporters de Leibnitz et Newton dure encore. Newton a accusé Leibnitz de plagiat. Mais nos notations sont bien celles de Leibnitz. Des fluantes et fluxions de Newton il ne reste qu'une chimère évanescente. On peut avoir été un génie et con à la fois.

(2)

Cette image a été réalisée par un module python plotter.py. Pourquoi coder encore un module alors que matplotlib existe déjà. C'est que matplotlib a été écrit pour MATLIB, qui est un logiciel propriétaire. En plus mon plotter.py me permet de plotter à ma guise.


Réalisé avec Qlam - LGPL