## 3 Outils pour l’Analyse

### 3.1 Dérivées

La fonction `diff` permet de calculer la dérivée d’une expression par rapport à une ou plusieurs de ses variables. Pour dériver une fonction f, on peut appliquer `diff` à l’expression f(x), mais alors le résultat est une expression. Si on souhaite définir la fonction dérivée, il faut utiliser `function_diff`.

    E:=x^2-1; diff(E);
    f:=unapply(E,x); diff(f(x));
    f1:=function_diff(f);f1(x);

Il ne faut pas définir la fonction dérivée par `f1(x):=diff(f(x))`, car dans cette définition, `x` aurait deux sens incompatibles : c’est d’une part la variable formelle de dérivation et d’autre part l’argument de la fonction `f1`. D’autre part, cette définition évaluerait `diff` à chaque appel de la fonction (car le membre de droite d’une affectation n’est jamais évalué), ce qui serait inefficace.
Il faut utiliser `f1:=function_diff(f)`, ou `f1:=unapply(diff(f(x)),x)`.

La fonction `diff` s’applique à n’importe quelle combinaison de variables, et permet de calculer des dérivées partielles successives.

    E:=sin(x*y)
    diff(E,x)
    diff(E,y)
    diff(E,x,y)-diff(E,y,x)
    simplify(ans())
    diff(E,x$2,y$3)

Si le deuxième argument de `diff` est une liste, une liste de dérivées est retournée. Par exemple pour calculer le gradient de sin(xy) : `diff(sin(x*y),[x,y])` (on peut aussi utiliser `grad`). Des commandes particulières permettent de calculer les combinaisons classiques de dérivées partielles.

Dérivées
`diff(ex,t)` | dérivée d’une expression par rapport à t
`function_diff(f)` | fonction dérivée d’une fonction
`diff(ex,x$n,y$m)` | dérivées partielles
`grad` | gradient
`divergence` | divergence
`curl` | rotationnel
`laplacian` | laplacien
`hessian` | matrice hessienne

### 3.2 Limites et développements limités

La fonction `limit` calcule les limites finies ou infinies, quand elles existent. On peut demander une limite à gauche ou à droite à l’aide d’un quatrième argument (+1 ou -1). Quand la fonction dépend d’un paramètre, la limite obtenue peut dépendre des hypothèses faites, avec la fonction `assume`, sur ce paramètre.

    limit(1/x,x,0)
    limit(1/x,x,0,1)
    limit(1/x,x,0,-1)
    limit(a/x,x,0,1)
    assume(a>0)
    limit(a/x,x,0,1)

Pour les développements limités, deux fonctions sont disponibles, `series` et `taylor`. La différence est que l’ordre du développement doit être spécifié pour `series`, il est égal à 6 par défaut pour `taylor`.

L’ordre du développement limité demandé est utilisé par `Xcas` en interne pour faire ses développements. En cas de simplifications, l’ordre du développement obtenu pourra être inférieur, il faudra alors recommencer le calcul avec un ordre plus grand. L’expression retournée est constituée du polynôme de Taylor, plus un reste dans lequel apparaît une fonction `order_size` qui est telle que pour tout a>0, xa`order_size`(x) tend vers 0 quand x tend vers 0. Pour supprimer le reste et ne garder que le polynôme de Taylor, on peut utiliser `convert` avec l’option `polynom`.

    taylor(1/(x^2+1),0)
    taylor(1/(x^2+a^2),x=0)
    series(1/(x^2+1),0,11)
    series(1/(x^2+1),+infinity,11)
    series(tan(x),pi/4,3)
    series(sin(x)^3/((1-cos(x))*tan(x)),0,4)
    series(sin(x)^3/((1-cos(x))*tan(x)),0,6)
    series(tan(sin(x))-sin(tan(x)),0,13)
    convert(ans(),polynom)
    series(f(x),0,3)
    g:=f@f; series(g(x),0,2)

Limites et développements limités
`limit(ex,x,a)` | limite en a
`limit(ex,x,a,1)` | limite à droite en a
`limit(ex,x,a,-1)` | limite à gauche en a
`taylor(ex,a)` | développement limité en a ordre 6
`series(ex,a,n)` | développement limité en a ordre n

### 3.3 Primitives et intégrales

La fonction `int` calcule une primitive d’une expressionpar rapport à x ou par rapport à la variable donnée en argument. Si l’expression comporte plusieurs variables, il vaut préciser la variable d’intégration. Si on ajoute deux arguments a et b après la variable d’intégration, on calcule l’intégrale sur l’intervalle [a,b]. Eventuellement les bornes de l’intégrale peuvent être des expressions, ce qui permet de calculer des intégrales multiples.

    int(x^2-1)
    int(x^2-1,x,-1,1)
    int(x*y,x)
    int(x*y,y,0,x)
    int(int(x*y,y,0,x),x,0,1)

Pour calculer une intégrale, un logiciel de calcul formel recherche une primitive puis l’évalue entre les bornes, afin d’obtenir une valeur exacte. Dans certains cas, il est inutile de calculer une primitive, soit parce qu’il n’en existe pas qui s’exprime avec les fonctions élémentaires, soit parce qu’un calcul numérique est plus adapté (par exemple si le temps de calcul de la primitive est trop long, si la fonction présente des singularités dans l’intervalle d’intégration, etc…). Dans ce cas, on demande une valeur approchée en utilisant `evalf`, ou bien on utilise directement la fonction `romberg`, qui est appelée par `evalf`.

    int(exp(-x^2))
    int(exp(-x^2),x,0,10)
    evalf(int(exp(-x^2),x,0,10))
    romberg(exp(-x^2),x,0,10)
    ans()/sqrt(pi))

Intégrales
`int(E)` | primitive d’une expression
`int(E,x,a,b)` | intégrale exacte
`romberg(E,x,a,b)` | intégrale approchée

### 3.4 Résolution d’équations

Comme pour les intégrales on distingue :

- la résolution exacte qui renvoie toutes les solutions lorsque c’est possible (par exemple pour certaines équations polynomiales ou s’y ramenant)
- la résolution approchée qui calcule par un algorithme itératif une valeur proche d’une des solutions.

La résolution exacte s’effectue à l’aide de `solve`, dont le premier argument est une équation. Le membre de droite est supposé nul s’il n’est pas précisé. Par défaut `solve` ne retourne pas les solutions complexes. Pour les obtenir, il faut cocher `Complexe` dans la configuration du CAS (`Cfg->Configuration de CAS` ou sur la barre-bouton `Config :exact...`)
Exécutez les commandes suivantes avant et après avoir activé l’option `Complex`.

    solve(x^2-a*x+2,x)
    solve(x^2+2,x)
    solve(x^3=1,x)

Les racines exactes sont calculées pour les polynômes de degré 1 et 2 (les formules de Cardan et Ferrari pour les degrés 3 et 4 ne sont pas utilisées, car les solutions obtenues ne sont pas facilement maniables). En degré supérieur, la fonction `solve` affiche un message d’erreur et renvoie une liste vide.

Pour les équations trigonométriques, les solutions principales sont renvoyées. Pour obtenir toutes les solutions, il faut activer l’option `All_trig_sol`. Comparer les commandes suivantes avec et sans cette option.

    solve(cos(x),x)
    solve(cos(x)+sin(x),x)

La fonction `solve` peut aussi résoudre des systèmes d’équations. Le premier argument est la liste des équations, le second est la liste des variables.

    solve([x^2+y-2,x+y^2-2],[x,y])

La fonction de résolution approchée est `fsolve`. Elle propose en option différents algorithmes (menus `Calc->Num_solve_eq` et `Calc->Num_solve_syst`). Le plus célèbre est l’algorithme de Newton, qui a de multiples variantes. Le principe général de tous ces algorithmes est de calculer les termes successifs d’une suite qui converge vers une solution de l’équation ou du système proposé. Il faut pour cela choisir selon les cas un point de départ, ou un intervalle de recherche.

    fsolve((x^5+2*x+1)=0,x,1,newton_solver)
    newton(x^5+2*x+1,x,1.0)
    newton(x^5+2*x+1,x,1+i)
    newton(x^5+2*x+1,x,-1+i)

Equations
`solve(eq,x)` | résolution exacte d’une équation
`solve([eq1,eq2],[x,y])` | résolution exacte d’un système
`fsolve(eq,x)` | résolution approchée d’une équation
`fsolve([eq1,eq2],[x,y])` | résolution approchée d’un système
`newton` | méthode de Newton
`linsolve` | système linéaire
`proot` | racines approchées d’un polynôme

### 3.5 Equations différentielles

Comme dans les deux sections précédentes, on distingue le calcul exact, qui n’est pas toujours possible, du calcul approché. La résolution exacte s’effectue par `desolve`. Les dérivées de la fonction inconnue y peuvent s’écrire y′, y″, qui sont traduits en `diff(y)`, `diff(diff(y))`. Si on ne spécifie pas de condition initiale, le résultat est donné en fonction de constantes arbitraires.

    desolve(y'=y,y)
    desolve(y''+2*y'+y=0,y)
    desolve((x^2-1)*y'+2*y=0,y)

Les conditions initiales sont vues comme des équations supplémentaires, qui forment une liste avec l’équation différentielle.

    desolve([y'=y,y(0)=1],y)
    desolve([y"+2*y'+y=0,y(0)=1],y)
    desolve([y"+2*y'+y=0,y(0)=1,y'(0)=1],y)
    desolve([y"+2*y'+y=0,y(0)=1,y(1)=0],y)
    desolve([(x^2-1)*y'+2*y=0,y(0)=1],y)
    desolve((t^2-1)*diff(y(t),t)+2*y(t)=0,y(t))

La fonction `odesolve` permet de résoudre par des méthodes numériques une équation différentielle y′=f(x,y) passant par un point (x0,y0). Par exemple

    odesolve(sin(x*y),[x,y],[0,1],2)

permet de calculer y(2) où y(x) est la solution de y′(x)=sin(xy), telle que y(0)=1. La fonction `plotode` représente graphiquement la solution d’une équation différentielle, `plotfield` représente le champ des tangentes. La fonction `interactive_odeplot` représente le champ des tangentes et permet de cliquer sur le graphique pour tracer les solutions passant par les points cliqués.

    plotfield(sin(x*y),[x,y])
    plotode(sin(x*y),[x,y],[0,1])
    erase()
    interactive_plotode(sin(x*y),[x,y])

Equations différentielles
`desolve` | résolution exacte
`odesolve` | résolution approchée
`plotode` | tracé de trajectoire
`plotfield` | tracé d’un champ de vecteurs
`interactive_plotode` | interface cliquable