• Aucun résultat trouvé

Séries formelles

Dans le document Calcul mathématique avec Sage (Page 166-171)

Une série formelle est une série entière vue comme une simple suite de coeffi- cients, sans considération de convergence. Plus précisément, si A est un anneau

commutatif, on appelle séries formelles (en anglais formal power series) d’indé- terminée x à coefficients dans A les sommes formelles P∞

n=0anxn où (an) est une suite quelconque d’éléments de A. Munies des opérations d’addition et de multiplication naturelles ∞ X n=0 anxn+ ∞ X n=0 bnxn= ∞ X n=0 (an+ bn)xn, Xn=0 anxn Xn=0 bnxn  = ∞ X n=0  X i+j=n aibj  xn, les séries formelles forment un anneau noté A[[x]].

Dans un système de calcul formel, ces séries sont utiles pour représenter des fonctions analytiques dont on n’a pas d’écriture exacte. Comme toujours, l’ordinateur fait les calculs, mais c’est à l’utilisateur de leur donner un sens mathématique. À lui par exemple de s’assurer que les séries qu’il manipule sont convergentes.

Les séries formelles interviennent aussi abondamment en combinatoire, en tant que séries génératrices. Nous verrons un exemple de ce type en §15.1.2.

7.5.1 Opérations sur les séries tronquées

L’anneau de séries formelles Q[[x]] s’obtient par

sage: R.<x> = PowerSeriesRing(QQ)

ou en abrégé R.<x> = QQ[[]]5. Les éléments de A[['x']] sont des séries tron-

quées, c’est-à-dire des objets de la forme

f = f0+ f1x +· · · + fn−1xn−1+ O(xn).

Ils jouent le rôle d’approximations des séries « mathématiques » infinies, tout comme les éléments de RR représentent des approximations de réels. L’anneau A[['x']]est donc un anneau inexact.

Chaque série possède son propre ordre de troncature6, et la précision est

suivie automatiquement au cours des calculs :

sage: R.<x> = QQ[[]]

sage: f = 1 + x + O(x^2); g = x + 2*x^2 + O(x^4)

sage: f + g 1 + 2*x + O(x^2)

sage: f * g x + 3*x^2 + O(x^3)

Il existe des séries de précision infinie, qui correspondent exactement aux poly- nômes :

5. Ou à partir de Q[x], par QQ['x'].completion('x').

6. D’un certain point de vue, c’est la principale différence entre un polynôme modulo xnet

une série tronquée à l’ordre n : les opérations sur ces deux sortes d’objets sont analogues, mais les éléments de A[[x]]/hxni ont, eux, tous la même « précision ».

sage: (1 + x^3).prec() +Infinity

Une précision par défaut est utilisée quand il est nécessaire de tronquer un résultat exact. Elle se règle à la création de l’anneau, ou ensuite par la méthode set_default_prec:

sage: R.<x> = PowerSeriesRing(Reals(24), default_prec=4)

sage: 1/(1 + RR.pi() * x)^2

1.00000 - 6.28319*x + 29.6088*x^2 - 124.025*x^3 + O(x^4)

Tout cela entraîne qu’il n’est pas possible de tester l’égalité mathématique de deux séries. C’est une différence conceptuelle importante entre celles-ci et les autres classes d’objets vues dans ce chapitre. Sage considère donc deux éléments de A[['x']] comme égaux dès qu’ils coïncident jusqu’à la plus faible de leurs précisions :

sage: R.<x> = QQ[[]]

sage: 1 + x + O(x^2) == 1 + x + x^2 + O(x^3)

True

Attention : cela implique par exemple que le test O(x^2) == 0 renvoie vrai, puisque la série nulle a une précision infinie.

Les opérations arithmétiques de base sur les séries fonctionnent comme sur les polynômes. On dispose aussi de quelques fonctions usuelles, par exemple f.exp() lorsque f(0) = 0, ainsi que des opérations de dérivation et d’intégration. Ainsi, un développement asymptotique quand x → 0 de

1 x2 exp Z x 0 r 1 1 + t dt 

est donné par

sage: (1/(1+x)).sqrt().integral().exp() / x^2 + O(x^4) x^-2 + x^-1 + 1/4 + 1/24*x - 1/192*x^2 + 11/1920*x^3 + O(x^4)

Ici, même si seuls quatre termes apparaissent dans le résultat, chaque opération est effectuée à la précision par défaut 20, qui suffit largement pour obtenir un reste final en O(x4). Pour obtenir plus de vingt termes, il faudrait augmenter la

précision des calculs intermédiaires.

Cet exemple montre aussi que si f, g ∈ K[[x]] et g(0) = 0, le quotient f/g renvoie un objet série de Laurent formelle. Contrairement aux séries de Laurent de l’analyse complexe, de la formeP∞

n=−∞anxn, les séries de Laurent formelles sont des sommes du typeP∞

n=−Nanxn, avec un nombre fini de termes d’exposant négatif. Cette restriction est nécessaire pour donner un sens au produit de deux séries formelles : sans celle-ci, chaque coefficient du produit s’exprime comme une somme de série infinie.

7.5.2 Développement de solutions d’équations

Face à une équation différentielle dont les solutions exactes sont trop compli- quées à calculer ou à exploiter une fois calculées, ou tout simplement qui n’admet pas de solution en forme close, un recours fréquent consiste à chercher des solutions sous forme de séries. On commence habituellement par déterminer les solutions de l’équation dans l’espace des séries formelles, et si nécessaire, on conclut ensuite par un argument de convergence que les solutions formelles construites ont un sens analytique. Sage peut être d’une aide précieuse pour la première étape.

Considérons par exemple l’équation différentielle

y(x) =p1 + x2y(x) + exp(x), y(0) = 1.

Cette équation admet une unique solution en série formelle, dont on peut calculer les premiers termes par

sage: (1+x^2).sqrt().solve_linear_de(prec=6, b=x.exp()) 1 + 2*x + 3/2*x^2 + 5/6*x^3 + 1/2*x^4 + 7/30*x^5 + O(x^6)

De plus, le théorème de Cauchy d’existence de solutions d’équations différentielles linéaires à coefficients analytiques assure que cette série converge pour |x| < 1 : sa somme fournit donc une solution analytique sur le disque unité complexe.

Cette approche n’est pas limitée aux équations différentielles. L’équation fonctionnelle exf (x) = f(x) est plus compliquée, ne serait-ce que parce qu’elle n’est pas linéaire. Mais c’est une équation de point fixe, nous pouvons essayer de raffiner une solution (formelle) par itération :

sage: S.<x> = PowerSeriesRing(QQ, default_prec=5)

sage: f = S(1)

sage: for i in range(5): ....: f = (x*f).exp() ....: print f 1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + O(x^5) 1 + x + 3/2*x^2 + 5/3*x^3 + 41/24*x^4 + O(x^5) 1 + x + 3/2*x^2 + 8/3*x^3 + 101/24*x^4 + O(x^5) 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + O(x^5) 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + O(x^5)

Que se passe-t-il ici ? Les solutions de exf (x)= f(x) dans Q[[x]] sont les points fixes de la transformation Φ : f 7→ exf. Si une suite d’itérés de la forme Φn(a) converge, sa limite est nécessairement solution de l’équation. Inversement, posons

f (x) =P∞n=0fnxn, et développons en série les deux membres : il vient

∞ X n=0 fnxn = ∞ X k=0 1 k!  x ∞ X j=0 fjxj k = ∞ X n=0 Xk=0 1 k! X j1,...,jk∈N j1+···+jk=n−k fj1fj2. . . fjk  xn. (7.2)

Peu importent les détails de la formule ; l’essentiel est que fn se calcule en fonction des coefficients précédents f0, . . . , fn−1, comme on le voit en identifiant les coefficients des deux membres. Chaque itération de Φ fournit donc un nouveau terme correct.

Exercice 29. Calculer le développement limité à l’ordre 15 de tan x au voisinage

de zéro à partir de l’équation différentielle tan′= 1 + tan2.

7.5.3 Séries paresseuses

Le phénomène de point fixe motive l’introduction d’une autre sorte de sé- ries formelles appelées séries paresseuses (en anglais lazy). Ce ne sont pas des séries tronquées, mais bien des séries infinies ; l’adjectif paresseux signifie que les coefficients ne sont calculés que quand ils sont explicitement demandés. En contrepartie, on ne peut représenter que des séries dont on sait calculer les coeffi- cients : essentiellement, des combinaisons de séries de base et certaines solutions d’équations pour lesquelles existent des relations comme (7.2). Par exemple, la série paresseuse lazy_exp définie par

sage: L.<x> = LazyPowerSeriesRing(QQ)

sage: lazy_exp = x.exponential(); lazy_exp O(1)

est un objet qui contient dans sa représentation interne toutes les informations nécessaires pour calculer le développement en série de exp x à n’importe quel ordre. Elle s’affiche initialement comme O(1) car aucun coefficient n’a encore été calculé. Tenter d’accéder au coefficient de x5déclenche le calcul, et les coefficients

calculés sont alors mémorisés :

sage: lazy_exp[5] 1/120

sage: lazy_exp

1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + O(x^6)

Reprenons l’exemple de l’équation exf (x)= f(x) pour voir comment il se traite avec des séries paresseuses. Nous pouvons d’abord essayer de reproduire le calcul fait plus haut dans l’anneau QQ[['x']] :

sage: f = L(1) # la série paresseuse constante 1

sage: for i in range(5):

....: f = (x*f).exponential()

....: f.compute_coefficients(5) # force le calcul des

....: print f # premiers coefficients

1 + x + 1/2*x^2 + 1/6*x^3 + 1/24*x^4 + 1/120*x^5 + O(x^6) 1 + x + 3/2*x^2 + 5/3*x^3 + 41/24*x^4 + 49/30*x^5 + O(x^6) 1 + x + 3/2*x^2 + 8/3*x^3 + 101/24*x^4 + 63/10*x^5 + O(x^6) 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + 49/5*x^5 + O(x^6) 1 + x + 3/2*x^2 + 8/3*x^3 + 125/24*x^4 + 54/5*x^5 + O(x^6)

Les développements obtenus sont bien sûr les mêmes que précédemment7. Mais la

valeur de f à chaque itération est maintenant une série infinie, dont on peut calculer des coefficients à la demande. Toutes ces séries intermédiaires sont conservées en mémoire. Le calcul de chacune d’entre elles est automatiquement poussé à la précision requise de manière à fournir, par exemple, le coefficient de x7 dans le

dernier itéré lorsque l’on tente d’y accéder :

sage: f[7] 28673/630

Avec le code de la §7.5.2, l’accès à f[7] aurait provoqué une erreur, l’indice 7 étant supérieur à l’ordre de troncature de la série f.

Cependant, la valeur renvoyée par f[7] n’est que le coefficient de x7 dans

l’itéré Φ5(1), et non dans la solution. La force des séries paresseuses est la

possibilité de passer directement à la limite, en codant f elle-même comme une série paresseuse :

sage: from sage.combinat.species.series importLazyPowerSeries

sage: f = LazyPowerSeries(L, name='f')

sage: f.define((x*f).exponential())

sage: f.coefficients(8)

[1, 1, 3/2, 8/3, 125/24, 54/5, 16807/720, 16384/315]

Ce qui « faisait marcher » le calcul itératif est la relation (7.2). En coulisses, Sage déduit de la définition récursive f.define((x*f).exponential()) une formule du même genre, qui permet de calculer les coefficients par récurrence.

Dans le document Calcul mathématique avec Sage (Page 166-171)

Documents relatifs