Calcul Formel - Philippe J. Giabbanelli
Transcription
Calcul Formel - Philippe J. Giabbanelli
Cours / TP : Frederic Eyssette Cours 1 : 03/02/06 Calcul Formel : Principes de Maple Nota : partiel le vendredi 10 mars dans l’après-midi sur machine I. Utiliser l’aide On appelle l’aide avec ?ifactor ou en mettant le curseur dans la commande puis help > help on… Pour savoir les constantes que connaît maple : ?constants. On verra catalan, gamma, Pi… (≠ pi !!) Maple est essentiellement une bibliothèque de fonctions mathématiques. Il faut utiliser l’aide ! Elle se présente sous la forme suivante : ifactor --description rapide— paramètres n entier méthode (optionnel) Description technique (des références mathématiques à lire en dernier recours…) Exemples (très utile) See Also : liens vers une fonction proche Si on a ouvert trop de fenêtres : window > close all help. Si on veut une aide globale structurée par thèmes : help > contents. II. Nombres Les entiers et les rationnels sont de taille aussi grande que besoin est. En conséquence, les opérations sur ces objets ont un temps qui dépend de leur taille. a := 10^29 - 10^11 – 1 ; # allocation avec un :=. Un ‘ ;’ affiche le résultat, et ‘ :’ ne l’affiche pas. ifactor(a, easy) ; # on cherche la factorisation en petits (easy) nombres premiers de a → (353)(499)_c24 # la constante non factorisée est à 24 chiffres On peut demander des évaluations ou approximations. Par exemple pour (2+3√5)12 : c := (2+3*sqrt(5))^12 ; evalf(c) ; → .1901704756e12 expand(c); → 95144562001+42496880328√5 Comment savoir le nombre de 0 à la fin de 300! ? On le calcule et on regarde sa décomposition en facteurs premiers. Il ressort (2)296(3)148(5)74 ; pour faire un 10 il faut des 5 et des 2, il y en a ici 74, d’où 74 zéro qui terminent 300 !. Les nombres approchés peuvent être de taille aussi grande qu’on veut : c’est notre choix. Par exemple, comparons eπ√163 et le nombre entier le plus proche : l’écart est de seulement 10-12 ! Il faudra donc beaucoup de chiffre pour voir que eπ√163 n’est pas un nombre entier. evalf nous donne 0,2..1018 (i.e. un nombre à 18 chiffres). Pour voir que ce nombre n’est pas un entier il faut au moins 18 chiffres avant la virgule, et 12 après. Comme les dernières décimales ne sont jamais justes, si on a besoin de 30 chiffres justes on en prend 35. Notons qu’il y a une propagation des erreurs : si un nombre est approché, tout le calcul le devient. Autres fonctions utiles : - calcul modulaire. irem(a, b) donne le reste (reminder) et iquo(a, b) le quotient. Exemple : a := 23: b := 4: c := irem(a, b) + b*iquo(a,b) ; - rationalize tente d’enlever toutes les racines du dénominateur. Exemple : a := 1/(sqrt(2)+sqrt(3)) ; rationalize(%) ; → √3 - √2 - evala évalue des racines. Exemple : z := sqrt(2) + sqrt(3) ; evala(z^4 – 10*z^2 + 1) ; → 0 Cours de Calcul Formel (Maple) 1 Tapé par Philippe Giabbanelli III. Polynômes solve(x^3 + x + 5) ; va chercher les racines exactes du polynôme. Le résultat est une formule compliquée avec des notations pour compacter l’affichage, comme %2 = (540 + 12√2037)1/3 ; comme Maple voit que l’expression revient souvent, il introduit des notations. En degré 3 et 4 les formules sont atroces, mais à partir du degré 5 un théorème dit qu’il n’existe plus de formule qui donne les racines en fonction des coefficients (les théorèmes de non-existence sont difficiles). solve(p1) ; avec p1 de degré 5 répond RootOf(p1) et on peut ensuite utiliser cette expression, par exemple dans « soit α la racine de p1 », même si on ne peut la calculer. fsolve(p1) ; donne des racines approchées ; par défaut elles sont réelles, mais elles peuvent être complexes sur demande avec fsolve(p1, complex) ; Pour avoir un polynôme au hasard on utilise randpoly, qui est réglé par défaut sur 5. p1 := randpoly(x) ; → -56 -7x5 + 22x4 -55x3 -94x² + 87x p2 := randpoly(x, degree=12, terms=13); # de degré 12 avec 13 termes, pour ne pas en avoir de nuls IV. Analyse Pour savoir la liste des fonctions que Maple connaît : ?inifcns (fonctions initialement connues). diff permet de faire la dérivée. Ce n’est pas une opération difficile, il suffit d’avoir une bonne base de données et d’appliquer des règles de calcul. Le problème c’est de simplifier le résultat, ce que le dérivateur ne fait pas par défaut : il faut appeler simplify. a := ln(x/(x^2+1)) : b := diff(a, x) : simplify(b); # on lui demande de simplifier son résultat On peut dériver plusieurs fois : diff (diff (diff (x^5,x),x),x) ; → 60x² Pour cela on utilise une écriture condensée : diff (x^5,x,x,x) ; On peut également faire des dérivées partielles : diff (…, x, y, z) ; où on dérive 3 fois, une par rapport à x, puis par rapport à y et par rapport à z. int fait l’intégration : c’est nettement plus difficile que la dérivée. On peut spécifier les bornes (∫ba ), ou obtenir les primitives. int( sin(x), x=0..Pi ); → 2 int( sin(x), x) ; → -cos(x) On peut essayer int(1/p1, x) ; mais ceci devrait décomposer en éléments simples, donc calculer les racines… Si on ne sait pas calculer ces racines, alors Maple donne une formule où interviennent des α qui sont racines du polynôme : Σ blablablabla α = RootOf(p1) int(exp(-x^3)) ; ne donnera pas de primitive, car elle ne peut pas s’écrire avec les fonctions usuelles (th.). On aura soit ∫e-x^3 sur un vieux Maple, soit une expression faisant intervenir la fonction de Whittaker. Par exemple, ∫(p1/p2) ne s’écrit pas nécessairement avec des polynômes : on a besoin d’introduire de nouvelles fonctions. Ainsi, ∫(1/x) est simplement une nouvelle fonction qu’on nomme log… Autre exemple : ∫e-x² (distribution quasi-gaussienne) ne peut s’exprimer avec les fonctions usuelles. Pour obtenir le développement de Taylor d’une fonction, on utilise taylor(fonction, point, degré). taylor(sin(x), x=0, 18) ; #polynôme de Taylor de degré 18 en 0 de sin(x) taylor(sin(x), x=r, 18); #polynôme de Taylor de degré 18 en un point r quelconque Enfin, on pourra utiliser la fonction limit(expression, point, spécifications). limit(1/x, x = 0, left) ; → -∞ # la limite de 1/x en 0limit(1/x, x = infinity) ; →0 limit(1/x, x = 0) ; → undefined # par défaut on fait une recherche dans les réels Cours de Calcul Formel (Maple) Tapé par Philippe Giabbanelli 2 V. Graphiques Avec plot on fait toutes sortes de graphiques en deux dimensions. plot(sin(x), x = -3..3) ; # affiche sin(x) pour x variant entre -3 et 3 plot(sin(x), x = 0..3, y = 0.1..1) ; # affiche sin(x) pour x entre 0 et 3 et y entre 0,1 et 1 plot([x,x^2,x^3],x=0..1); # affiche une famille de fonctions : x, x², x3 plot([sin(5*t),cos(7*t),t=0..2*Pi]); # courbe paramétrée Un point qui se déplace dans un plan n’est plus un graphe de fonction mais une courbe paramétrée avec x(t) et y(t). Purement physique. De même, on peut réaliser le tout en 3d : plot3d(sin(x^2+y^2),x=-2..2,y=-2..2); Pour connaître les graphiques spéciaux (animations, courbes dans l’espace...) : ?plots (consulter librairie). Le programme ne calcule que certains points et les relie ensuite. On peut lui demander de n’afficher que les points calculés. Le pas est adaptatif, c’est-à-dire que pour les grosses variations de la fonction il fait plus de points que pour des petites variations. C’est un bon algorithme. Si on veut construire un exemple plus compliqué, il est fortement conseillé de procéder par morceaux. Par exemple, traçons sin et ses développements limités en 0. On prend dl := taylor(sin(x), x = 0,5) ; puis plot(dl, x = -10..10); Or, cela ne marche pas. Pourquoi ? Car taylor répond x – x3/6 + O(x3), et le O(x3) pose problème. Comme on ne peut calculer O(x3), on le supprime pour le graphique ; autrement dit, on fait une conversion du type développement limité au type polynôme. dl := convert(taylor(sin(x), x = 0, 5), polynom) ; → x – x3/6 On a maintenant une fonction traçable. Comment en sortir une famille ? On utilise seq afin de se donner des suites. D’où : dls := seq (convert (taylor (sin x), x = 0, i), polynom), i = 3..20) ; VI. Principes de programmation On donne la syntaxe nom_fonction := proc(paramètres), et on termine par un end; Notons que pour passer à la ligne suivante sans exécuter on utilise maj+entrée… pgcd1 := proc(a, b) if b = 0 then a else pgcd1(b, irem(a, b)) fi end; On utilise un peu le même principe que dans le shell unix : un if appelle un fi. pgcd1(6, 9) ; → 3 On peut cherche à le programmer de manière itérative. Attention : Maple refuse qu’on utilise les paramètres d’une procédure comme des variables locales. On ne peut faire la moindre affectation dessus. Donc, avant de travailler, on fait des copies locales. pgcd2 := proc (a0, b0) local r, a, b ; while b <> 0 do r := irem (a, b), a:=b, b:= r od # <> signifie ≠ a; # le résultat à rendre end; La syntaxe la plus générale est for __ from __ to __ by __ while __ do __ od On peut ensuite mélanger largement. Par exemple sans from, on démarre automatiquement de 1… On peut adjoindre au description au début de la fonction : description « calcule un pgcd » ; Quelques exemples : for i from 6 by 2 to 100 do print(i) end do; # affiche les nombres pairs de 6 à 100 for z in {1, 2, 3, 4} do print(z) od; # affiche l’ensemble 1 2 3 4 Notons qu’on peut également mettre des break; c’est-à-dire une instruction de sortie de boucle. Cours de Calcul Formel (Maple) 3 Tapé par Philippe Giabbanelli VII. Introduction aux problèmes d’algèbre linéaire Résoudre un système d’équations linéaire est une technique fondamentale (et sera le sujet de l’examen…). a11x1 + … + a1mxm = y1 La seule chose délicate est de savoir ce que l’on veut exploiter de ce … système. Regarder quelques problèmes simples de l’algèbre linéaire. an1x1 + … + anmxm = ym - - - On veut savoir si V1, ..., Vn sont linéairement indépendants. ◊ On regarde si la seule solution de λ1V1 + … + λnVn = 0 est λ1 = … = λn = 0. On veut extraire une base de V1, ..., Vn. ◊ Soit λ1V1 + … + λnVn = 0. Si λ1 = … = λn = 0 est la seule solution, alors c’est une base. Sinon on élimine les vecteurs qui peuvent s’écrire en fonctions des autres, à partir des valeurs des λi. C’est simplement une exploitation plus fine de la solution du système. Des problèmes d’applications linéaires |Rm → |Rn ( x1 ) (a11x1 + … + a1mxm) (a11 a1m) ( x1 ) (…)→ ( … ) = ( ... ) ( ... ) ( xm ) (an1x1 + … + anmxm) (an1 anm) ( xm ) On cherche le noyau : quels sont les vecteurs dont l’image est nulle ? On cherche l’image : comment sont toutes les images possibles ? Des problèmes de sous-ensemble vectoriels : comment s’en donner un ? Dans |Rn on peut le donner soit par des vecteurs générateurs V1, ..., Vn, soit par des équations linéaires où ce sont alors les { V | V satisfait le système d’équations}. Les vecteurs générateurs ne sont pas forcément indépendants : il faut en extraire une base. Les équations du système ne sont pas forcément indépendantes : il faut enlever le superflu. Enfin, il faut savoir passer entre système d’équation et engendré par des vecteurs. Il y a différentes techniques de résolution. La méthode de Gauss consiste à partir du système et faire apparaître des zéro ; à la fin on dit que le système est échelonné, et non ‘triangularisé’ ce qui laisserait entendre qu’on obtient une matrice triangulaire. En effet, le système est ‘échelonné’ dans le système où sur chaque ligne il doit y avoir moins d’éléments non nuls que sur la ligne précédente. Il y a d’autres méthodes que celles de Gauss (c.f. méthodes numériques). En effet, Gauss fonctionne mal là où les calculs sont approchés ; si on a des nombres de tailles très variables, c’est déconseillé. C’est la méthode à utiliser uniquement dans le cadre de calculs exacts. Pourquoi ne pas faire uniquement du calcul exact ? On le paye sur la taille des fractions obtenues. Plus on descend dans les lignes et plus elles sont compliquées… Cela étant, Gauss nous permet de discuter des systèmes dont les coefficients dépendent d’un paramètre, ce qui n’est pas pour le calcul numérique. VIII. Quelques autres notions de Maple On peut demander le type d’une expression. whattype(2*x + 3 – x) ; # la réponse est que c’est une somme whattype(2*x) ; # ici, c’est un produit On peut considérer que la réponse donnée est celle de la racine de l’arbre contenant l’expression. On peut modifier le comportement de Maple avec interface. Par exemple, pour voir davantage des fonctions définies dans Maple, on doit modifier le niveau de blabla affiché relatif aux procédures. print(unassign) ; → proc() … end # par défaut, Maple ne nous affichera que ceci interface(verboseproc=2) ; # on monte le niveau de blabla print(unassign) ; → proc() # maintenant on peut voir davantage du contenu local i, j, n ; global assign ; blablablabla Cours de Calcul Formel (Maple) 4 Tapé par Philippe Giabbanelli