• Aucun résultat trouvé

Fractions rationnelles

Dans le document Calcul mathématique avec Sage (Page 149-154)

Corps finis et théorie élémentaire des 6

7.5 Fractions rationnelles

7.5.1 Fractions rationnelles

La division de deux polynômes (sur un anneau intègre) produit une fraction rationnelle. Son parent est le corps des fractions de l’anneau de polynômes, qui peut s’obtenir parFrac(R) :

sage: x = polygen(RR); r = (1 + x)/(1 - x^2); r.parent() Fraction Field of Univariate Polynomial Ring in x over Real Field with 53 bits of precision

sage: r

(x + 1.00000000000000)/(-x^2 + 1.00000000000000)

On observe que la simplification n’est pas automatique. C’est parce que RR est un anneauinexact, c’est-à-dire dont les éléments s’interprètent comme des approximations d’objets mathématiques. La méthode reduce met la fraction sous forme réduite. Elle ne renvoie pas de nouvel objet, mais modifie la fraction rationnelle existante :

sage: r.reduce(); r

1.00000000000000/(-x + 1.00000000000000)

Sur un anneau exact, en revanche, les fractions rationnelles sont automati-quement réduites.

Les opérations sur les fractions rationnelles sont analogues à celles sur les polynômes. Celles qui ont un sens dans les deux cas (substitution, dérivée, factorisation...) s’utilisent de la même façon. Le tableau7.6énumère quelques autres méthodes utiles. La décomposition en éléments simples et surtout la reconstruction rationnelle méritent quelques explications.

BR

OUILLON

Fractions rationnelles

corpsK(x) Frac(K['x']) numérateur r.numerator() dénominateur r.denominator() simplification (modifier) r.reduce()

décomposition en éléments simples r.partial_fraction_decomposition() reconstruction rationnelle p.rational_reconstruct(m)

Séries tronquées

anneauA[[t]] PowerSeriesRing(A, 'x', default_prec=10) anneauA((t)) R.<x> = LaurentSeriesRing(A, 'x') coefficient [xk]f(x) f[k]

troncature x + O(x^n) précision f.prec()

dérivée, primitive (nulle en 0) f.derivative(), f.integral() opérations usuelles

f, expf, ... f.sqrt(), f.exp(), ...

inverse fonctionnel (gf=x) g = f.reversion()

solution dey0+ay=b a.solve_linear_de(precision, b)

Tableau 7.6– Objets construits à partir des polynômes.

7.5.2 Décomposition en éléments simples

Sagecalcule la décomposition en éléments simples d’une fraction ration-nellea/bde Frac(K['x']) à partir de la factorisation de bdans K['x']. Il s’agit donc de la décomposition en éléments simples sur K. Le résultat est formé d’une partie polynomiale pet d’une liste de fractions rationnelles dont les dénominateurs sont des puissances de facteurs irréductibles deb :

sage: R.<x> = QQ[]; r = x^10/((x^2-1)^2*(x^2+3))

sage: poly, parts = r.partial_fraction_decomposition() sage: print poly

x^4 - x^2 + 6

sage: for part in parts: print part.factor() (17/32) * (x - 1)^-2 * (x - 15/17)

(-17/32) * (x + 1)^-2 * (x + 15/17) (-243/16) * (x^2 + 3)^-1

On a ainsi obtenu la décomposition en éléments simples sur les rationnels

r = x10

(x2−1)2(x2+ 3) =x4x2+ 6 +

17 32x1532

(x−1)2 +−1732x1532

(x+ 1)2 + −24316 x2+ 3. Il n’est pas difficile de voir que c’est aussi la décomposition der sur les réels.

Sur les complexes en revanche, le dénominateur du dernier terme n’est pas irréductible, et donc la fraction rationnelle peut encore se décomposer.

On peut calculer la décomposition en éléments simples sur les réels ou les complexes numériquement :

sage: C = ComplexField(15)

BR

OUILLON

sage: Frac(C['x'])(r).partial_fraction_decomposition()

(x^4 - x^2 + 6.000, [(0.5312*x - 0.4688)/(x^2 - 2.000*x + 1.000), 4.384*I/(x - 1.732*I), (-4.384*I)/(x + 1.732*I),

(-0.5312*x - 0.4688)/(x^2 + 2.000*x + 1.000)])

La décomposition exacte surCs’obtient de la même façon, en remplaçantC par QQbar. En faisant le calcul sur AA, on aurait la décomposition sur les réels même quand toutes les racines réelles du dénominateurs ne sont pas rationnelles.

7.5.3 Reconstruction rationnelle

Un analogue de la reconstruction rationnelle présentée en §6.1.3existe pour les polynômes à coefficients dansA=Z/nZ. En Sage, la commande

s.rational_reconstruct(m, dp, dq)

calcule lorsque c’est possible des polynômes p, qA[x] tels que qsp mod m, degp6dp, degq6dq.

Restreignons-nous pour simplifier au cas oùnest premier. Une telle relation avecq et mpremiers entre eux entraînep/q=sdansA[x]/hmi, d’où le nom de reconstruction rationnelle.

Le problème de reconstruction rationnelle se traduit par un système linéaire sur les coefficients dep et q, et un simple argument de dimension montre qu’il admet une solution non triviale dès quedp+dq>degm−1. Il n’y a pas toujours de solution avecq etm premiers entre eux (par exemple, les solutions depqx mod x2 avec degp60, degq 61 sont les multiples constants de (p, q) = (0, x)), maisrational_reconstructcherche en priorité les solutionsq premières avec m.

Approximants de Padé. Le cas m = xn est appelé approximation de Padé. Un approximant de Padé de type (k, n −k) d’une série formelle fK[[x]] est une fraction rationnellep/qK(x) telle que degp 6k−1, degq 6nk,q(0) = 1, etp/q=f+O(xn). On a alorsp/qf mod xn.

Commençons par un exemple purement formel. Les commandes suivantes calculent un approximant de Padé de la sérief = Pi=0(i+ 1)2xi à coeffi-cients dansZ/101Z:

sage: A = Integers(101); R.<x> = A[]

sage: f6 = sum( (i+1)^2 * x^i for i in (0..5) ); f6 36*x^5 + 25*x^4 + 16*x^3 + 9*x^2 + 4*x + 1

sage: num, den = f6.rational_reconstruct(x^6, 1, 3); num/den (100*x + 100)/(x^3 + 98*x^2 + 3*x + 100)

En développant à nouveau en série la fraction rationnelle trouvée, on observe que non seulement les développements coïncident jusqu’à l’ordre 6, mais le terme suivant aussi « est juste » !

BR

OUILLON

-6 -4 -2 2 4 6

-3 -2 -1 1 2 3

type (4, 2)

· · · · type (8, 4)

·− ·− ·−

type (12, 6)

− − − −

Figure 7.1– La fonction tangente et quelques approximants de Padé sur [−2π,2π].

sage: S = PowerSeriesRing(A, 'x', 7); S(num)/S(den)

1 + 4*x + 9*x^2 + 16*x^3 + 25*x^4 + 36*x^5 + 49*x^6 + O(x^7) En effet,f est elle-même une fraction rationnelle : on af = (1 +x)/(1x)3. Le développement tronquéf6, accompagné de bornes sur les degrés du numé-rateur et du dénominateur, suffit à la représenter sans ambiguïté. De ce point de vue, le calcul d’approximants de Padé est l’inverse du développement en série des fractions rationnelles : il permet de repasser de cette représentation alternative à la représentation habituelle comme quotient de deux polynômes.

Un exemple analytique. Historiquement, les approximants de Padé ne sont pas nés de ce genre de considérations formelles, mais de la théorie de l’ap-proximation des fonctions analytiques. En effet, les approximants de Padé du développement en série d’une fonction analytique approchent souvent mieux la fonction que les troncatures de la série. Quand le degré du dénominateur est assez grand, ils peuvent même fournir de bonnes approximations même en-dehors du disque de convergence de la série. On dit parfois qu’ils « avalent les pôles ». La figure 7.1, qui montre la convergence des approximants de type (2k, k) de la fonction tangente au voisinage de 0, illustre ce phénomène.

Bien que rational_reconstructsoit limité aux polynômes sur Z/nZ, il est possible de s’en servir pour calculer des approximants de Padé à coefficients rationnels, et aboutir à cette figure. Le plus simple est de commencer par effectuer la reconstruction rationnelle modulo un nombre premier assez grand :

sage: x = var('x'); s = tan(x).taylor(x, 0, 20)

sage: p = previous_prime(2^30); ZpZx = Integers(p)['x']

sage: Qx = QQ['x']

sage: num, den = ZpZx(s).rational_reconstruct(ZpZx(x)^10,4,5) sage: num/den

(1073741779*x^3 + 105*x)/(x^4 + 1073741744*x^2 + 105)

BR

OUILLON

puis de relever la solution trouvée. La fonction suivante relève un élémenta de Z/pZen un entier de valeur absolue au plus p/2.

sage: def lift_sym(a):

... m = a.parent().defining_ideal().gen() ... n = a.lift()

... if n <= m // 2: return n ... else: return n - m

On obtient :

sage: Qx(map(lift_sym, num))/Qx(map(lift_sym, den)) (-10*x^3 + 105*x)/(x^4 - 45*x^2 + 105)

Lorsque les coefficients cherchés sont trop grands pour cette technique, on peut faire le calcul modulo plusieurs premiers, et appliquer le « théorème chinois » afin de retrouver une solution à coefficients entiers, comme expliqué en §6.1.4. Une autre possibilité est de calculer une relation de récurrence à coefficients constants satisfaite par les coefficients de la série. Ce calcul est presque équivalent à celui d’un approximant de Padé (voir exercice 26), mais la fonctionberlekamp_massey deSagepermet de le faire sur un corps quelconque.

Systématisons un peu le calcul précédent, en écrivant une fonction qui cal-cule directement l’approximant à coefficients rationnels, sous des hypothèses suffisamment favorables :

sage: def mypade(pol, n, k):

... x = ZpZx.gen();

... n,d = ZpZx(pol).rational_reconstruct(x^n, k-1, n-k) ... return Qx(map(lift_sym, n))/Qx(map(lift_sym, d)) Il n’y a plus alors qu’à appeler plot sur les résultats de cette fonction (convertis en éléments deSR, carplotne permet pas de tracer directement le graphe d’une fraction rationnelle) pour obtenir le graphique de la figure7.1 :

sage: add(

... plot(expr, -2*pi, 2*pi, ymin=-3, ymax=3, ... linestyle=sty, detect_poles=True,

... aspect_ratio=1)

... for (expr, sty) in [

... (tan(x), '-'),

... (SR(mypade(s, 4, 2)), ':' ), ... (SR(mypade(s, 8, 4)), '-.'), ... (SR(mypade(s, 12, 6)), '--') ])

Les exercices suivants présentent deux autres applications classiques de la reconstruction rationnelle.

Exercice 26. 1. Montrer que si (un)n∈N satisfait une récurrence linéaire à coefficients constants, la série formellePn∈

Nunzn est une fraction rationnelle. Comment s’interprètent le numérateur et le dénominateur ?

BR

OUILLON

2. Deviner les termes suivants de la suite

1,1,2,3,8,11,34,39,148,127,662,339,3056,371,14602,−4257, . . . , en utilisantrational_reconstruct. Retrouver le résultat à l’aide de la fonctionberlekamp_massey.

Exercice 27 (Interpolation de Cauchy). Trouver une fraction rationnelle r=p/q∈F17(x) telle quer(0) =−1,r(1) = 0, r(2) = 7 , r(3) = 5, avec p de degré minimal.

Dans le document Calcul mathématique avec Sage (Page 149-154)