• Aucun résultat trouvé

Représentation informatique des polynômes

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

Un même objet mathématique — le polynôme p, à coefficients dans A — peut se coder sur ordinateur de façons très différentes. Si le résultat mathématique d’une opération sur p est bien sûr indépendant de la représentation, il en va autrement du comportement des objets Sage correspondants. Le choix de la représentation influe sur les opérations possibles, la forme exacte de leurs résultats, et particulièrement l’efficacité des calculs.

Représentation dense et représentation creuse. Il existe deux façons prin- cipales de représenter les polynômes. En représentation dense, les coefficients de

p =Pni=0pixi sont stockés dans un tableau [p0, . . . , pn] indexé par les exposants. Une représentation creuse ne stocke que les coefficients non nuls : le polynôme est codé par un ensemble de paires exposant-coefficient (i, pi), regroupées dans une liste, ou mieux, dans un dictionnaire indexé par les exposants (voir §3.3.9). Pour des polynômes qui sont effectivement denses, c’est-à-dire dont la plupart des coefficients sont non nuls, la représentation dense occupe moins de mémoire et

7. On constate cependant que Sage emploie parfois des conventions incohérentes : la mé- thode qui s’appelait exp pour les séries tronquées s’appelle ici exponential, et compute_ coefficients(5) calcule les coefficients jusqu’à l’ordre 5 inclus tandis que default_prec=5 donnait des séries tronquées après le coefficient de x4.

permet des calculs plus rapides. Elle économise le stockage des exposants et des structures de données internes du dictionnaire : ne reste que le strict nécessaire, les coefficients. De plus, l’accès à un élément ou l’itération sur les éléments sont plus rapides dans un tableau que dans un dictionnaire. Inversement, la représentation creuse permet de calculer efficacement sur des polynômes qui ne tiendraient même pas en mémoire en représentation dense :

sage: R = PolynomialRing(ZZ, 'x', sparse=True)

sage: p = R.cyclotomic_polynomial(2^50); p, p.derivative() (x^562949953421312 + 1, 562949953421312*x^562949953421311)

Comme l’illustre l’exemple précédent, la représentation est une caractéristique de l’anneau de polynômes, que l’on choisit à sa construction. Le polynôme « dense »

x∈ Q[x] et le polynôme « creux » x ∈ Q[x] n’ont donc pas le même8parent. La

représentation par défaut des polynômes à une indéterminée est dense. L’option sparse=True de PolynomialRing sert à construire un anneau de polynômes creux.

Certains détails de représentation varient de plus suivant la nature des co- efficients des polynômes. Il en va de même du code utilisé pour effectuer les opérations fondamentales. Sage offre en effet, outre une implémentation générique des polynômes qui fonctionne sur tout anneau commutatif, plusieurs variantes optimisées pour un type particulier de coefficients. Celles-ci apportent quelques fonctionnalités supplémentaires, et surtout sont considérablement plus efficaces que la version générique. Elles s’appuient pour cela sur des bibliothèques externes spécialisées, par exemple flint ou ntl dans le cas de Z[x].

Pour mener à bien de très gros calculs, il est crucial de travailler autant que possible dans des anneaux de polynômes disposant d’implémentations efficaces. La page d’aide affichée par p? pour un polynôme p indique quelle implémentation il utilise. Le choix de l’implémentation découle le plus souvent de ceux de l’anneau de base et de la représentation. L’option implementation de PolynomialRing permet de préciser une implémentation quand plusieurs choix sont possibles. Expressions symboliques. Les expressions symboliques décrites dans les chapitres1et 2(c’est-à-dire les éléments de SR) fournissent une troisième repré- sentation des polynômes. Elles constituent un choix naturel quand un calcul mêle polynômes et expressions plus complexes, comme c’est souvent le cas en analyse. Mais la souplesse de représentation qu’elles offrent est parfois utile même dans un contexte plus algébrique. Par exemple, le polynôme (x + 1)1010

, une fois développé, est dense, mais il n’est pas nécessaire (ni souhaitable !) de le développer pour le dériver ou l’évaluer numériquement.

Attention cependant : contrairement aux polynômes algébriques, les polynômes symboliques (de SR) ne sont pas rattachés à un anneau de coefficients particulier et ne sont pas manipulés sous forme canonique. Un même polynôme a un grand nombre d’écritures différentes, entre lesquelles c’est à l’utilisateur d’expliciter

8. Pourtant, QQ['x'] == PolynomialRing(QQ, 'x', sparse=True) renvoie vrai : les deux parents sont égaux, car ils représentent le même objet mathématique. Naturellement, le test correspondant avec is renvoie faux.

Un peu de théorie

Pour tirer le meilleur parti des opérations rapides sur les polynômes, il est bon d’avoir une idée de leur complexité algorithmique. En voici un bref aperçu à l’intention du lecteur connaissant un peu d’algorithmique. Nous nous limitons au cas des polynômes denses.

Additions, soustractions et autres manipulations directes des coefficients se font facilement en temps linéaire en les degrés des polynômes en jeu. Leur rapidité en pratique dépend donc essentiellement de la possibilité d’accéder rapidement aux coefficients, et donc de la structure de données.

L’opération cruciale est la multiplication. En effet, non seulement c’est une opération arithmétique de base, mais aussi d’autres opérations utilisent des algorithmes dont la complexité dépend essentiellement de celle de la multiplication. Par exemple, on peut calculer la division euclidienne de deux polynômes de degré au plus n pour le coût de O(1) multiplications, ou encore leur pgcd pour celui de O(log n) multiplications.

Bonne nouvelle : on sait multiplier les polynômes en temps presque linéaire. Précisément, la meilleure complexité connue sur un anneau quelconque est de O(n log n log log n) opérations dans l’anneau de base. Elle repose sur des généralisations du célèbre algorithme de Schönhage-Strassen, qui atteint la même complexité pour la multiplication d’entiers. En comparaison, la méthode que l’on utilise à la main pour multiplier les polynômes demande un nombre d’opérations de l’ordre de n2.

Les algorithmes de multiplication rapide sont compétitifs en pratique pour les polynômes de degré suffisamment grand, de même que les méthodes qui en dérivent pour la division. Les bibliothèques sur lesquelles s’appuie Sage pour certains types de coefficients font appel à ce genre d’algorithmes avancés : c’est ainsi que Sage est capable de travailler efficacement avec des polynômes de degré astronomique sur certains anneaux de coefficients.

les conversions nécessaires. Dans le même ordre d’idées, le domaine SR regroupe toutes les expressions symboliques, sans distinction entre les polynômes et les autres, mais on peut tester explicitement si une expression symbolique f est polynomiale en une variable x par f.is_polynomial(x).

algebra.

William Stein

8

Algèbre linéaire

Ce chapitre traite de l’algèbre linéaire exacte et symbolique, c’est-à-dire sur des anneaux propres au calcul formel, tels que Z, des corps finis, des anneaux de polynômes... L’algèbre linéaire numérique est traitée quant à elle au chapitre13. Nous présentons les constructions sur les matrices et leurs espaces ainsi que les opérations de base (§8.1), puis les différents calculs possibles sur ces matrices, re- groupés en deux thèmes : ceux liés à l’élimination de Gauss et aux transformations par équivalence à gauche (§8.2.1 et §8.2.2), et ceux liés aux valeurs et espaces propres et aux transformations de similitude (§8.2.3). On peut trouver dans les ouvrages de Gantmacher [Gan90], de von zur Gathen et Gerhard [vzGG03], de Lombardi et Journaïdi [LA04] un traitement approfondi des notions abordées dans ce chapitre.

8.1 Constructions et manipulations

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

Documents relatifs