Retour à la page principale de Giac/Xcas.

# Algorithmes de calcul formel

### B. Parisse
Institut Fourier
UMR 5582 du CNRS
Université de Grenoble I

> Résumé: Ce document décrit une partie des algorithmes de calcul formel utilisés pour le logiciel de calcul formel Giac/Xcas, cf.
> `http://www-fourier.ujf-grenoble.fr/~parisse/giac_fr.html`

## Table des matières

## 1 Calculer sur ordinateur

### 1.1 Problèmes spécifiques au calcul formel

#### 1.1.1 Calcul exact et approché, types, évaluation.

Dans les langages de programmation traditionnel (C, Pascal,...), il existe déjà des types permettant une représentation exacte des données (type entier) ou une représentation approchée (type flottant). Mais ces types de donnée de base occupent une taille fixe en mémoire, le type entier est donc limité à un intervalle d’entiers (par exemple [0,232−1] pour un entier non signé sur une machine utilisant un processeur 32 bits) alors que le type flottant peut représenter des nombres réels, mais est limité à une précision en nombre de digits de la mantisse et de l’exposant (par exemple 12 chiffres significatifs et un exposant compris entre -499 et 499).

En calcul formel, on souhaite pouvoir calculer rigoureusement d’une part, et avec des paramètres dont la valeur n’est pas connue d’autre part ; il faut donc s’affranchir de ces limites :

- pour les entiers relatifs, on utilise des entiers de précision arbitraire dont la taille en mémoire est dynamique (déterminée pendant l’exécution et non à la compilation),
- pour les nombres complexes, on utilise un couple de nombres réels,
- pour les rationnels, on utilise un couple d’entiers relatifs,
- pour les irrationnels algébriques (par exemple √2), on utilise un polynôme irréductible dont ils sont racines,
- pour les paramètres (x,y,z,t...), on utilise un type structuré contenant un champ de type chaine de caractères pour représenter le nom du paramètre et un champ pour attribuer une valeur à (ou une hypothèse sur) ce paramètre,
- pour les nombres transcendants (par exemple π), on est obligé d’introduire un paramètre auquel on attribue une valeur numérique, qui ne sera utilisée qu’au moment où on veut une approximation numérique d’une expression contenant ce nombre transcendant, on parle de constante,
- lorsqu’on a besoin d’une approximation numérique d’un nombre, on peut utiliser des conversions de ces types en un type flottant. On peut aussi pour lutter contre les erreurs d’arrondi utiliser des nombres flottants étendus dont la précision est dynamique ou même des intervalles de flottants étendus,
- il faut aussi un nouveau type, appelé expression ou symbolique, permettant d’appliquer une fonction qu’on ne peut évaluer directement sur les objets précédents, par exemple sin(x). Il doit s’agir d’une opération de clôture, au sens où appliquer une fonction à un objet symbolique ne nécessite pas la création d’un nouveau type (en général on renvoie un objet symbolique).

Enfin, il faut pouvoir évaluer un objet (en particulier symbolique) : par exemple évaluer sin(x) lorsqu’on assigne une valeur à x. Dans cet exemple, on voit qu’il faut d’abord remplacer x par sa valeur avant de lui appliquer la fonction sinus. C’est le mécanisme général de l’évaluation, mais il y a quelques exceptions où on souhaite empêcher l’évaluation d’un ou plusieurs arguments d’une fonction avant l’évaluation de la fonction. Par exemple si on veut calculer la valeur numérique d’une intégrale par des méthodes de quadrature, on ne souhaitera pas rechercher une primitive de la fonction à intégrer. Dans le jargon, on parle alors de “quoter” un argument (l’origine du terme vient probablement de la notation `'` du langage Lisp). Certaines fonctions doivent toujours quoter leurs arguments (par exemple la fonction qui permet de purger le contenu d’un paramètre), on parle parfois d’autoquotation.

#### 1.1.2 Forme normale et reconnaissance du 0.

Une fois défini ces types de base représentant les nombres d’un système de calcul formel, il faut pouvoir comparer ces nombres, en particulier décider si deux représentations distinctes correspondent au même nombre ou, ce qui revient au même, par soustraction décider quand un nombre est nul. Par exemple 4/2 et 2 représentent le même nombre. Lorsqu’on dispose d’un algorithme permettant de représenter un nombre d’une manière unique, on parle de forme normale. C’est par exemple le cas pour les nombres rationnels, la forme normale usuelle est la fraction irréductible de dénominateur positif. C’est aussi le cas pour les fractions rationnelles de polynômes à coefficients entiers représentées par une fraction irréductible, avec au dénominateur un coefficient de plus haut degré positif. Malheureusement, il n’est pas toujours possible de trouver une forme normale pour diverses raisons théoriques ou pratiques :

- on ne connaît pas toujours le statut de certaines constantes (par exemple la constante d’Euler),
- il n’existe pas d’algorithmes permettant de déterminer s’il existe des relations algébriques entre constantes,
- il n’existe pas forcément une seule forme plus simple, par exemple :

  (

  √

  2

  +1)x+1

  x+

  √

  2

  +1

  =

  x+

  √

  2

  −1

  (

  √

  2

  −1)x+1

  Ce cas se présente fréquemment avec les extensions algébriques.
- en pratique il peut être trop coûteux d’utiliser une forme normale, par exemple le polynôme x1000−1/x−1 possède 1000 monômes

En résumé, au mieux on a une forme normale, au pire on risque de ne pas reconnaître un zéro, entre les deux on peut ne pas avoir de forme normale mais être capable de reconnaître à coup sûr une expression nulle (par contre, si le système de calcul formel détermine qu’une expression est nulle, alors elle l’est).

Il n’existe pas d’algorithme solution pour le problème de la reconnaissance du zéro pour une classe d’expressions "assez générale". Heureusement, dans la plupart des cas pratiques on sait résoudre ce problème, en se ramenant le plus souvent au cas des polynômes et fractions rationnelles. Par exemple, pour simplifier une expression trigonométrique, on remplace les fonctions trigonométriques sin(x), cos(x), tan(x) par leur expression en fonction de t=tan(x/2), on est ainsi ramené à une fraction rationnelle en t que l’on écrit sous forme normale.

Les polynômes ont un rôle central dans tout système de calcul formel puisque sauf dans les cas les plus simples (fractions d’entiers par exemple), la simplification d’expressions fait appel à un moment ou à un autre à des calculs de PGCD de polynômes. Le PGCD de polynômes est un algorithme très sollicité auquel nous consacrerons une section. En effet, l’application brutale de l’algorithme d’Euclide pose des problèmes d’efficacité ce qui a obligé à inventer des méthodes plus efficaces. Anticipons rapidement sur un exemple qui montre l’un des problèmes majeurs des algorithmes de calcul formel, l’explosion en taille (ici des coefficients des restes successifs). Voici donc les restes successifs lorsqu’on applique l’algorithme d’Euclide pour calculer le PGCD de P(x)=(x+1)7−(x−1)6 avec sa dérivée (les deux polynômes sont premiers entre eux) :

7 (x+1)6−6 (x−1)5 |  |

162
49

x5+

−390
49

x4+

1060
49

x3+

−780
49

x2+

474
49

x+

−78
49

157780
729

x4+

−507640
2187

x3+

290864
729

x2+

−101528
729

x+

28028
729

1
49

(

1400328
2645

x3+

−732888
2645

x2+

1133352
3703

x+

−732888
18515

)

1
2187

(

2161816376832
4669921

x2+

−555436846944
4669921

x+

301917024864
4669921

)

1
907235

(

469345063045455
129411872

x+

−47641670106615
129411872

)

5497465490623352995840
209648836272383412129

Le lecteur voulant tester d’autres exemples pourra utiliser le programme `Xcas` (cf. l’appendice) suivant :

    pgcd(a):={
      local b,r,res;
      b:=diff(a,x);
      res:=NULL;
      for (;b!=0;){
        res:=res,b;
        r:=rem(a,b);
        a:=b;
        b:=r;
      }
      return(res);
    }

#### 1.1.3 Valeur générique des variables et hypothèses

Lorsqu’on utilise un symbole sans lui affecter de valeurs en mathématiques on s’attend à une discussion en fonction du paramètre représenté par ce symbole. Ce qui nécessiterait de créer un arborescence de calculs (on retrouve ici les problèmes d’explosion évoqués dans la section précédente). La plupart des systèmes de calcul formel contournent la difficulté en supposant que le paramètre possède une valeur générique (par exemple la solution de (t2−1)x=t−1 sera x=1/(t+1)) ou choisissent une branche pour les fonctions possédant un point de branchement (par exemple pour résoudre x2=t en fonction de t). Certains systèmes demandent de manière interactive à l’utilisateur si la variable est par exemple positive ou différente de 1 mais cela s’oppose à un traitement automatique. On peut aussi anticiper ce type de décision en faisant des hypothèses sur une paramètre, la plupart des systèmes de calcul formel actuel proposent cette possibilité.

### 1.2 Structures de données

On a vu plus haut qu’on souhaitait manipuler des entiers de taille non fixe, des réels de précision fixe ou non, des fractions, des nombres complexes, des extensions algébriques, des paramètres, des expressions symboliques. La plupart des systèmes proposent un type générique qui recouvre ces divers types de scalaire. On peut par exemple utiliser un type structuré comportant un champ type et la donnée ou un pointeur sur la donnée (avec dans ce cas un pointeur sur un compteur de références de la donnée pour pouvoir la détruire dès qu’elle n’est plus référencée1). En programmation orientée objet, on utiliserait plutôt un type abstrait dont dérivent ces différents scalaires et le polymorphisme.

Il faut aussi un type pour les vecteurs, les matrices et les listes. Il faut prendre garde à la méthode utilisée par le système lorsqu’on modifie un élément d’un vecteur, matrice ou liste : soit on effectue une copie de tout l’objet en modifiant l’élément, soit on modifie l’élément de l’objet original. La première méthode (par valeur) est plus aisée à comprendre pour un débutant mais la seconde méthode (par référence) est bien plus efficace.

On peut se poser la question de savoir s’il faut inclure ces types dans le type générique ; en général la réponse est affirmative, une des raisons étant que les interpréteurs qui permettront de lire des données dans un fichier texte sont en général basé sur le couple de logiciels `lex(flex)/yacc(bison)` qui ne peut compiler qu’à destination d’un seul type. Ceci permet également d’unifier en un seul type symbolique les fonctions ayant un ou plusieurs arguments en voyant plusieurs arguments comme un vecteur d’arguments. Les fonctions sont le plus souvent elle-même incluses dans le type générique permettant ainsi à l’utilisateur de saisir des commandes ou programmes fonctionnels (on peut utiliser une fonction comme argument d’une commande).

Pour des raisons d’efficacité, les systèmes de calcul formel utilisent souvent des représentations particulières pour les polynômes dont on a dit qu’ils jouaient un rôle central. Pour les polynômes à une variable, on peut utiliser la liste des coefficients du polynôme, on parle alors de représentation dense. On peut aussi décider de ne stocker que les coefficients non nuls, on parle alors de représentation creuse (on stocke alors un couple formé par le coefficient et le degré du monôme correspondant). Pour les polynômes à plusieurs variables, on peut les considérer comme des polynômes à une variable à coefficients polynomiaux, on parle alors de représentation récursive. On peut aussi décider de ne pas briser la symétrie entre les variables (pas de variable principale), on parle alors de représentation distribuée, le plus souvent les représentation distribuées sont creuses car les représentations denses nécessitent très vite beaucoup de coefficients. Les méthodes de représentation creuses sont parfois aussi utilisées pour les matrices ayant beaucoup de coefficients nuls.

Voyons maintenant plus précisément sur quelques exemples de logiciels de calcul formel répandus quelles structures de données sont utilisées. Plusieurs éléments entrent en compte dans les choix faits :

- le(s) profil(s) d’utilisation (enseignement, ingéniérie, calcul intensif, recherche)
- les ressources disponibles (mémoire, puissance du processeur...)
- la facilité d’implémentation (choix du langage, outils disponibles en particulier débuggueurs, ...)
- l’histoire du système (un système conçu avec les outils disponibles aujourd’hui est forcément différent d’un système conçu il y a 20 ans)

Nous allons d’abord parler des calculatrices formelles HP et TI (le lecteur pourra facilement les tester grâce aux émulateurs gratuits pour PC). Ce sont des systèmes plutôt destinés à l’enseignement, soumis à de fortes contraintes en termes de taille mémoire, et destinés à traiter des petits problèmes. Puis nous présenterons des systèmes pour ordinateur où les ressources (par exemple mémoire) sont moins limitées ce qui permet d’utiliser des langages de programmation de plus haut niveau.

#### 1.2.1 Calculatrices formelles HP

Les langages utilisés pour programmer ces calculateurs sont l’assembleur et le RPL (Reverse Polish Lisp) adapté à l’écriture de code en mémoire morte très compact.

Le type générique est implémenté avec un champ type appelé prologue (qui est en fait un pointeur sur la fonction chargée d’évaluer ce type d’objet) suivi de la donnée elle-même (et non d’un pointeur sur la donnée, on économise ainsi la place mémoire du compteur de référence).

Le type entier en précision arbitraire est codé par le nombre de digits (sur 5 quartets2) suivi du signe sur un quartet et de la représentation BCD (en base 10) de la valeur absolue de l’entier. Le choix de la représentation BCD a été fait pour optimiser les temps de conversion en chaîne de caractères pour l’affichage. La mémoire vive disponible est de 256K, c’est elle qui limite la taille des entiers et non le champ longueur de l’entier. Il n’y a pas de type spécifique pour les rationnels (on utilise un objet symbolique normal).

Les fonctions internes des HP49/50/40 utilisent le type programme pour représenter les entiers de Gauß (complexes dont la partie réelle et imaginaire est entière). Les nombres algébriques ne sont pas implémentés, sauf les racines carrées (représentée de manière interne par le type programme). Il y a un type spécifique prévu pour les flottants en précision arbitraire, mais l’implémentation des opérations sur ces types n’a pas été intégrée en ROM à ce jour.

Les types listes, programmes et objet symbolique sont composés du prologue (champ type) suivi par la succession d’objets situés en mémoire vive ou de pointeurs sur des objets situés en mémoire en lecture seule (ROM) et se terminent par un pointeur sur une adresse fixe (appelée `SEMI`). Ces types sont eux-mêmes des objets et peuvent donc être utilisés de manière récursive. La longueur des types listes, programmes, symboliques n’est stockée nulle part, c’est le délimiteur final qui permet de la connaître, ce qui est parfois source d’inefficacité. On utilise de manière interne les listes pour représenter les polynômes denses (avec représentation récursive pour les polynômes à plusieurs variables).

Les calculatrices HP4xG utilisent une pile3, c’est-à-dire une liste de taille non fixée d’objets. On place les objets sur la pile, l’exécution d’une fonction prend ces arguments sur la pile et renvoie un ou plusieurs résultats sur la pile (ce qui est une souplesse du RPN comparé aux langages où on ne peut renvoyer qu’une valeur de retour). Il faut donc donner les arguments avant d’appeler la fonction correspondante. Par exemple pour calculer a+b on tapera `a b +`. C’est la syntaxe dite polonaise inversée (RPN). Un avantage de cette syntaxe est que le codage d’un objet symbolique par cette syntaxe est évidente, il suffit de stocker la liste précédente `{a b +}`. Les objets symboliques sont donc représenté par une suite d’objets écrit en syntaxe polonaise inversée. L’évaluation d’un objet symbolique se fait dans l’ordre polonaise inversé : les arguments sont évalués puis les fonctions leur sont appliqués. Pour des raisons d’efficacité, on représente souvent les objets composites (listes, symboliques) par leurs composants placés sur la pile (appelé meta-objets).

Une rigidité de la syntaxe polonaise est que les fonctions ont toujours un nombre fixe d’arguments4, par exemple l’addition a toujours 2 arguments, ainsi a+b+c est obtenu par (a+b)+c ou par a+(b+c) c’est-à-dire respectivement `a b + c +` ou `a b c + +` ce qui brise parfois artificiellement la symétrie de certaines opérations. En polonaise inversée, le système doit de plus jongler avec l’autoquote puisque les arguments sont évalués avant l’opérateur qui éventuellement demanderait à ne pas évaluer ses arguments. À noter l’existence d’une commande `QUOTE` permettant à l’utilisateur de quoter une sous-expression.

Les hypothèses sur des variables réelles sont regroupées dans une liste stockée dans la variable globale `REALASSUME`, on peut supposer qu’une variable est dans un intervalle. Il n’y a pas à ce jour de possibilité de supposer qu’une variable est entière (ni à fortiori qu’une variable à une valeur modulo un entier fixé), bien qu’il ait été décidé de réserver la variable globale `INTEGERASSUME` à cet effet. Il n’y a pas de possibilité de faire des hypothèses ayant une portée locale.

#### 1.2.2 Calculatrices formelles TI

Le langage utilisé pour programmer ces calculatrices est le langage C (on peut aussi écrire du code en assembleur pour ces calculatrices). On retrouve ici les différents types de données regroupé en un type générique qui est un tableau d’octets (aussi appelé quantum). Le champ type est appelé tag dans la documentation TI. Contrairement à ce qui précède, ce champ type est placé en mémoire à la fin de l’objet, ce qui est possible car la longueur d’un objet est toujours indiquée au début de l’objet. Ceci est fait afin de faciliter l’évaluation (cf. infra).

Les entiers en précision arbitraire sont codés par un tag parmi deux (pour différencier le signe), un octet pour la longueur, puis la valeur absolue de l’entier (en base 256). Ils sont donc limités par le champ longueur à 255 octets, le plus grand entier représentable est 5 (256255−1). Il existe un tag spécifique pour les rationnels, pour les constantes réelles et entières qui apparaissent par exemple en résolvant une équation. Il existe des tags utilisés de manière interne, par exemple pour les nombres complexes. Il n’y a pas de tag prévu pour les flottants en précision arbitraire. ni pour les nombres algébriques (racines carrées par exemple).

Les listes sont codées par la succession de leurs éléments. En principe elles ne peuvent pas contenir des listes (sauf pour représenter une matrice). Quelques fonctions utilisent les listes pour représenter des polynômes denses à une variable, mais probablement pas pour représenter de manière récursive des polynômes à plusieurs variables (puisque le type liste n’est en principe pas récursif).

Comme les HP, les TI utilisent une pile (non visible par l’utilisateur) appelée expression stack afin de traduire un expression mathématique sous forme d’un texte en un objet symbolique codé exactement comme ci-dessus en syntaxe polonaise. Toutefois, la présence du champ longueur permet d’évaluer un objet symbolique sans perdre en efficacité en partant de l’opérateur final et en redescendant ensuite sur ces arguments, c’est la stratégie adoptée. C’est pour cela que le tag d’identification se trouve à la fin de l’objet. L’utilisation de cette méthode facilite grandement l’autoquotation (on peut toutefois regretter que le système n’ait pas prévu d’instruction permettant à l’utilisateur d’empêcher l’évaluation d’une sous-expression).

On ne peut pas faire d’hypothèse globale sur un paramètre par contre on peut faire des hypothèses de type appartenance à un intervalle ayant une portée locale.

#### 1.2.3 Maple, Mathematica, ...

Ces systèmes ont un noyau fermé, au sens où l’utilisateur n’a pas accès du tout, ou en tout cas pas facilement, aux structures de données de base. Je ne dispose donc pas d’information sur les structures de données utilisées par le noyau.

L’interaction système-utilisateur se fait quasiment toujours en utilisant le langage de programmation propre au système, langage interprété par le noyau du système (ce qui ralentit l’exécution). Ces langages utilisateurs sont essentiellement non typés : on travaille avec des variables du type générique sans pouvoir accéder aux types sous-jacents. On ne bénéficie en général pas des vérifications faites lors de la compilation avec un langage typé, de plus ces systèmes ne sont pas toujours fourni avec de bon outils de mise au point. Enfin ces langages ne sont pas standardisés d’un système à l’autre et il est en général impossible d’utiliser ces systèmes comme des librairies depuis un langage de programmation traditionnel. Leur intérêt principal réside donc dans une utilisation interactive en profitant de la librairie de fonctions accessibles.

#### 1.2.4 Giac/xcas

Il s’agit du système de calcul formel que j’implémente actuellement sous forme d’une bibliothèque C++ (ce qui permettra aux programmes tiers d’utiliser beaucoup plus facilement du calcul formel qu’avec les systèmes précédents). L’objectif est d’avoir un système facile à programmer directement en C++, proche du langage utilisateur, lui-même compatible avec Maple ou MuPAD, tout cela sans trop perdre en performances comparativement aux librairies spécialisées écrites en C/C++. Ce qui explique un choix de type générique (`gen`) non orienté objet, avec un champ type et soit une donnée immédiate (pour les nombres flottants par exemple), soit un pointeur vers un objet du type correspondant au champ type pour les données de taille non fixe (on pourrait donc se contenter du langage C, mais le langage C++ permet de redéfinir les opérateurs sur des types utilisateurs ce qui améliore considérablement la lisibilité du code source). Les données dynamiques ne sont pas dupliquées, Giac utilise un pointeur sur un compteur de référence pour détruire ces données lorsqu’elles ne sont plus référencées.

Les entiers en précision arbitraire sont hérités de la bibliothque GMP (écrite en C) du projet GNU. Les flottants en précision arbitraire utiliseront aussi GMP (plus précisément MPFR). Il y a un type fraction, structure C composé d’un champ numérateur et d’un champ dénominateur, et un type nombre complexe.

Les listes, vecteurs, matrices utilisent le type paramétré `vector<>` de la librairie standard C++ (Standard Template Library). Les objets symboliques sont des structures composés d’un champ sommet qui est une fonction prenant un argument de type `gen` et renvoyant un résultat de type `gen`, et d’un champ feuille qui est de type `gen`. Lorsqu’une fonction possède plusieurs arguments, ils sont rassemblés en une liste formant le champ feuille de l’objet symbolique. Les programmes sont aussi des objets symboliques, dont le champ sommet est la fonction évaluation d’un programme. Les listes sont aussi utilisées pour représenter vecteurs, matrices et polynômes en une variable en représentation dense, on peut y accéder par valeur (`:=`) ou par référence (`=<`). Ces polynômes servent eux-mêmes á représenter des éléments d’une extension algébrique de ℚ (vus comme un couple de polynômes P,Q, où Q est un polynome minimal irréductible à coefficients entiers, autrement dit P,Q vaut P(α) où Q(α)=0), ou des éléments d’un corps fini (comme ci-dessus, mais ici Q est à coefficients dans ℤ/pℤ avec p premier, cf. la commande `GF`). Giac posséde aussi un type pour les polynômes en représentation creuse distribuée en plusieurs indéterminées (cf. les commandes `symb2poly` et `poly2symb`).

L’évaluation d’un objet symbolique se fait en regardant d’abord si la fonction au sommet doit évaluer ou non ses arguments (autoquote), on évalue les arguments si nécessaire puis on applique la fonction.

Une hypthèse sur un paramètre est une valeur spéciale affectée au paramètre, valeur ignorée par la routine d’évaluation.

### 1.3 Algorithmes et complexité.

On va présenter dans la suite quelques algorithmes que l’on peut considérer comme classiques dans le domaine du calcul formel. Avant d’implémenter ce type d’algorithmes, on a besoin des algorithmes de base en arithmétique. Le lecteur trouvera en appendice une brève présentation de certains de ces algorithmes, mes références en la matière sont le livre de Henri Cohen, et les livres de Donald Knuth (cf. appendice).

La plupart des problèmes posés en calcul formel nécessitent des calculs dont la taille croit de manière exponentielle voire doublement exponentielle en fonction de la taille des données et ce même si le résultat est lui aussi de taille petite. Un exemple est la réduction des systèmes de plusieurs équations polynomiales (bases de Groebner). Dans certains cas, l’application de théories mathématiques parfois sophistiquées permet de réduire la complexité (par exemple, M. Van Hoeij a découvert récemment qu’un algorithme très utilisé en théorie des nombres, l’algorithme LLL, permettait d’améliorer la complexité d’une des étapes de la factorisation des polynomes à coefficients entiers sur les entiers). Heureusement, dans de nombreux cas, on peut réduire la complexité (donc le temps de calcul) par des adaptations au problème d’une même idée à condition de faire des hypothèses sur les données (autrement dit en abandonnant la volonté d’implémenter un algorithme très générique, ou tout au moins en spécialisant des algorithmes génériques).

Par exemple lorsqu’on travaille avec des entiers (ou des polynômes à coefficients entiers, ou des matrices à coefficients entiers...) on utilise souvent des algorithmes modulaires et p-adiques. Comme le calcul exact nécessite presque toujours de calculer avec des entiers, ces méthodes ont un rôle central en calcul formel, nous les présentons donc maintenant brièvement. Dans les prochaines sections, nous utiliserons ce type de méthode, par exemple pour le calcul de PGCD ou la factorisation de polynômes à coefficients entiers.

Les méthodes modulaires consistent à réduire un problème dans ℤ à son équivalent dans Z/nℤ pour une ou plusieurs valeurs de n, nombre premier. Le calcul dans ℤ/nℤ a l’avantage de se faire avec des entiers dont la taille est bornée. Ensuite à l’aide d’estimations à priori sur la taille des solutions éventuelles du problème initial, on reconstruit la solution au problème initial avec le théorème des restes chinois.

Par exemple, on peut calculer un déterminant d’une matrice à coefficients entiers en cherchant ce déterminant dans ℤ/nℤ pour plusieurs nombres premiers n, dont le produit est deux fois plus grand qu’une estimation à priori de la taille du déterminant (donnée par exemple par l’inégalité d’Hadamard, cf. Cohen, p. 50).

Les méthodes p-adiques commencent de manière identique par un calcul dans ℤ/nℤ, on augmente ensuite la précision de la solution en la «liftant»de ℤ/nk ℤ vers ℤ/nk+1ℤ ou vers ℤ/n2kℤ (lift linéaire ou lift quadratique), on s’arrête lorsque k est assez grand (à l’aide d’estimations à priori) et on reconstruit alors la solution initiale. L’étape de «lift»est en général un lemme de Hensel dont on verra quelques exemples dans les prochains articles. L’algorithme commun au lemme de Hensel et au théorème des restes chinois est l’identité de Bézout, que l’on retrouve d’ailleurs un peu partout (par exemple pour le calcul de primitives).

Illustrons cette méthode sur un exemple simple, la recherche de racines rationnelles d’un polynôme P(X)=ad Xd + ⋯ + a0 à coefficients entiers ou polynomiaux, avec ad et a0 non nuls. L’algorithme générique (assez connu) consiste à chercher les diviseurs de a0 et de ad et à tester toutes les fractions de ces diviseurs, on montre en effet aisément que si X=p/q fraction irréductible est racine de P alors q divise ad et p divise a0. Cet algorithme est très inefficace si ad ou a0 est un grand entier (car on ne sait pas forcément le factoriser) ou s’il a beaucoup de facteurs premiers (la liste des diviseurs à tester est alors très grande).

Lorsque les coefficients de P sont entiers, la recherche précédente revient à trouver un facteur à coefficients entiers qX−p de P, on peut donc réduire le problème modulo un entier premier n qui ne divise pas ad : si un tel facteur existe dans ℤ alors ce facteur (réduit modulo n) est un facteur de P dans ℤ/nℤ donc P admet une racine dans ℤ/nℤ (puisque q est inversible modulo n car on a choisi n premier ne divisant pas ad). On évalue maintenant P en les n éléments de ℤ/nℤ. S’il n’y a pas de 0, alors P n’a pas de racine rationnelle. S’il y a des racines, on va les lifter de ℤ/nkℤ dans ℤ/n2kℤ.

On suppose donc que pour k≥ 1, il existe un entier pk tel que

P(pk)=0 (mod nk )

Il s’agit de trouver un entier x tel que pk+1=pk+nk x vérifie

P(pk+1)=0 (mod n2k )

On applique la formule de Taylor à l’ordre 1 pour P en pk, le reste est nul modulo n2k, donc :

P(pk)+ nk x P′(pk)=0 (mod n2k )

soit finalement :

x=−

P(pk)
nk

( P′(pk) (mod nk )) −1

On reconnaît au passage la méthode de Newton, pour qu’elle fonctionne il suffit que P′(pk) ≠ 0 (mod n ) ce qui permet de l’inverser modulo nk (et c’est ici qu’intervient l’identité de Bézout). En pratique quand on factorise un polynôme, on commence par retirer les multiplicités, on peut donc supposer que P est sans facteur multiple dans ℤ. Ceci n’entraîne pas forcément qu’il le reste dans ℤ/nℤ ce qui crée une contrainte supplémentaire sur le choix de n, à savoir que P et P′ restent premier entre eux dans ℤ/nℤ (il existe forcément de tels n, par exemple n premier plus grand que le plus grand entier intervenant dans le calcul du PGCD de P et P′ dans ℤ).

Reste donc à revenir dans ℤ à partir d’une racine pk dans ℤ/(nk ℤ) (où on peut choisir k). On va maintenant utiliser la représentation modulaire symétrique : on prend comme représentant modulaire d’un entier z dans ℤ/nkℤ l’unique entier congru à z modulo n qui est strictement compris entre −nk/2 et nk/2 (si n est pair, la deuxième inégalité est choisie large).

Si qX−p est un facteur de P, alors adX−ad/q p est encore un facteur de P (le quotient de P par adX−ad/q p est à coefficients rationnels mais le facteur est à coefficients entiers). Si on a choisi k tel que nk>2|ad a0|, l’écriture en représentation modulaire symétrique de adX−ad/q p est inchangée, en effet on a des estimations à priori sur les entiers p et q : |q|≤ |ad| et |p| ≤ |a0| puisque q divise ad et p divise a0. Comme adX−ad/q p est égal à ad(X−pk) dans ℤ/(nk ℤ), il nous suffit d’écrire en représentation modulaire symétrique ad(X−pk)=ad X−p′. Pour conclure, on sait que ad X−p′ est un multiple entier de qX−p. On divise donc le facteur ad X−p′ par le pgcd de ad et p′ et on teste la divisibilité de P par ce facteur réduit.

Exemple
Considérons le polynôme 2 X3−X2−X−3 qui est sans facteur carré. On ne peut pas choisir n=2 car on réduirait le degré, pour n=3, on a P′=X−1 qui est facteur de P, pour n=5, P′=6X2−2X−1, on vérifie que P et P′ sont premiers entre eux (par exemple avec `GCDMOD` sur une HP49 où on aura fixé la variable `MODULO` à 5).

On teste ensuite les entiers de -2 à 2 sur P. Seul -1 est racine modulo 5 (P(−1)=−5), on va maintenant lifter p1=−1.

L’estimation à priori est 2|ad||a0|=12 donc k=2 (52=25>12), une itération suffira. On a P′(−1)=7, l’inverse de P′(−1) (mod 5 ) est -2 donc:

x= −

P(−1)
5

(−2) = −(−1) (−2)=−2

et p2=−1+5×(−2)=−11 est racine de P dans ℤ/25ℤ. On calcule ensuite ad(X−pk)=2(X+11)=2X+22=2X−3 en représentation symétrique, le PGCD de 2 et -3 est 1 donc on teste le facteur 2X−3, ici il divise P donc P admet un unique facteur entier de degré 1 qui est 2X−3.

### 1.4 Quelques algorithmes d’arithmétique de base.

- Les algorithmes de multiplication et division dit rapides des entiers et polynômes (Karatsuba, FFT, ...). Cf. par exemple Knuth. ou pour les entiers la documentation de GMP, ou infra pour Karatsuba.
- Au lieu de la division euclidienne, on utilise très souvent la pseudo-division pour les polynômes : étant donné deux polynômes A et B de degrés a et b à coefficients dans un anneau contenu dans un corps (par exemple ℤ), on multiplie A par une puissance du coefficient dominant Bb de B, plus précisément par Bba−b+1, ce qui permet d’effectuer la division par B sans que les coefficients sortent de l’anneau.

  Bba−b+1 A= B Q + R

  On utilise cette méthode lorsqu’on peut multiplier les polynômes par des constantes sans changer le problème (par exemple pour l’algorithme d’Euclide).
- L’algorithme d’Euclide est un algorithme «générique»de calcul de PGCD. Il n’est en général pas utilisé tel quel. Pour les entiers on utilise une variation adaptée à la représentation binaire des entiers (cf. Cohen ou le manuel de GMP version 4 pour plus de détails). Nous décrirons des algorithmes de PGCD plus efficaces pour les polynômes dans le prochain article.
- l’identité de Bézout, aussi appelée PGCD étendu. Étant donné deux entiers ou deux polynômes a et b on calcule u, v et d tels que au+bv=d. On écrit la matrice :

  ⎛
  ⎜
  ⎝

  a | 1 | 0
  b | 0 | 1

  ⎞
  ⎟
  ⎠

  où on remarque que pour chaque ligne le coefficient de la 1ère colonne est égal à a multiplié par le coefficient de la 2ème colonne additionné à b multiplié par le coefficient de la 3ème colonne. Ce qui reste vrai si on effectue des combinaisons linéaires de lignes (type réduction de Gauß). Comme on travaille dans les entiers ou les polynômes, on remplace la réduction de Gauß des matrices à coefficients réels par une combinaison linéaire utilisant le quotient euclidien (entier ou polynomial selon le cas) q de a par b. On obtient alors le reste r en 1ère colonne :

  L3=L1−qL2

  ⎛
  ⎜
  ⎜
  ⎝

  a | 1 | 0
  b | 0 | 1
  r | 1 | −q

  ⎞
  ⎟
  ⎟
  ⎠

  et on recommence jusqu’à obtenir 0 en 1ère colonne. L’avant-dernière ligne obtenue est l’identité de Bézout (la dernière ligne donne le PPCM de a et b). Si l’on veut l’inverse de a modulo b on remarque qu’il n’est pas utile de calculer les coefficients appartenant à la 3ème colonne. Enfin, les lignes intermédiaires peuvent servir à reconstruire une fraction d’entier représentée par un entier de ℤ/nℤ lorsque le numérateur et le dénominateur sont de valeur absolue inférieure à √n/2.
- Le théorème des restes chinois. Si on connaît x=a (mod m ) et x= b (mod n ) avec m et n premiers entre eux, on détermine c tel que x=c (mod m× n ). On a donc c=a+mu=b+nv et on applique Bézout pour trouver u ou v, on en déduit c. En pratique, on cherche un des coefficients de Bézout, par exemple on cherche U tel que mU+nV=1, on a alors :

  c=a+m (b−a)U

  Si n est petit devant m (par exemple 32 bits), U est aussi petit, on commence par réduire b−a modulo n, puis on multiplie par U, on réduit á nouveau modulo n et on multiple enfin par m.
- Les tests de pseudo-primalité. Il est essentiel d’avoir une méthode rapide permettant de générer des nombres premiers pour appliquer des méthodes modulaires et p-adiques. On utilise par exemple le test de Miller-Rabin, qui prolonge le petit théorème de Fermat (si p est premier, alors ap=a (mod p )).

#### 1.4.1 Exemple : l’algorithme de Karatsuba

Soient P, Q deux polynômes de degrés strictement inférieur à 2n. On suppose que le cout d’une opération arithmétique dans le corps des coefficients vaut 1 et on néglige les autres opérations (on suppose par exemple que le corps des coefficients est un corps fini). On écrit

P=A+xn B, Q=C+xn D

avec A,B,C,D de degrés strictement inférieur à n, on a alors :

P Q = AC + xn(AD+BC)+x2n BD

Il y a 4 produits de polynômes de degrés <n, mais au prix d’additions intermédiaires, on peut se ramener à 3 produits, en effet

(A+B)(C+D)−AC−BD = AD+BC

donc pour calculer le cofacteur de xn il suffit de soustraire à (A+B)(C+D) les produits AC et BD que l’on calcule par ailleurs. Soit M(n) le temps nécessaire pour calculer le produit de 2 polynômes par cette méthode, on a alors

M(2n) = 3M(n)+ 8n

où 8n représente le nombre d’additions ou de soustractions pour former A+B, C+D, soustraire AC et BD, et tenir compte des "retenues" (les termes de degré ≥ n de AC se combinent avec ceux de degré <2n de AD+BC et les termes de degré < 3n de x2nBD avec ceux de degré ≥ 2n de AD+BC). On en déduit

un=M(2n), un+1=3un+8 × 2n

cette récurrence se résoud facilement par la commande
`rsolve(u(n+1)=3*u(n)+8*2^n,u(n),u(0)=1)`
qui donne M(2n)=un=−8· 2n+9· 3n.

Asymptotiquement, M(2n) ≈ 9· 3n ce qui est bien meilleur que la multiplication naive en 2 · 4n, mais pour de petites valeurs de n, la multiplication naive est plus rapide, on utilise Karatsuba (récursivement) uniquement pour des valeurs de n suffisamment grandes (théoriquement lorsque 8n, le surcout dû aux additions est plus petit que la multiplication économisée, soit 8n<2n2 soit n>4, en pratique plutôt pour n de l’ordre de quelques dizaines selon les implémentations, car nous n’avons tenu compte que des opérations arithmétiques).

#### 1.4.2 Bezout sur les entiers et les fractions continues

Il existe une variante de l’identité de Bézout présentée ci-dessus pour les entiers. Soient a≥ b>0 deux entiers, on pose

(Ln) a un − b vn = (−1)n rn

où r0=a, r1=b et rn+2 est le reste de la division euclidienne de rn par rn+1 (qn+2 le quotient), u0=1, u1=0, v0=0,v1=1. Comme précedemment, chaque ligne s’obtient par combinaison linéaire des deux précédentes, mais cette fois avec une addition

Ln+2=Ln+qn+2 Ln+1

ce qui se traduit par :

un+2=un+qn+2 un+1, vn+2=vn+qn+2 vn+1

Les suites un et vn sont alors strictement croissantes (à partir du rang 1 pour un). Au rang k du dernier reste non nul on a :

a uk − b vk = (−1)k rk, rk=d=gcd(a,b)

et au rang suivant :

auk+1 −b vk+1=0

On montre par récurrence que

vn rn+1 + vn+1 rn=a

et une relation analogue pour un, on en déduit alors que vk+1=a/d et uk+1=b/d (ce sont les cofacteurs du PPCM de a et b), en particulier les coefficients de Bézout vérifient uk<b et vk<a.

On va aussi voir que un+2/vn+2 est la n-ième réduite du développement en fractions continues de a/b (donc les coefficients de Bézout se lisent sur l’avant-dernière réduite). On introduit la notation

[a0,a1,..,an] =a0+

1

a1+

1

a2+

...
ak

pour a0 ≥ 0, a1>0, ..., an>0. On a alors :

a
b

=[q2,q3,..,qk]

En effet :

a
b

=

r0
r1

=q2 +

r2
r1

= q2 +

1

r1
r2

= ...

D’autre part, on montre par récurrence sur n≥ 1 que si x>0

[q2,..., qn,x]=

vnx+vn−1
unx+un−1

en effet au rang n=1

[x]=x=

v1 x + v0
u1 x+u0

et pour l’induction :

[q2,..., qn,x]

=

[q2,..., qn−1,qn+

1
x

]

=

vn−1(qn+1/x)+vn−2
un−1(qn+1/x)+un−2

=

x(vn−1qn+vn−2)+vn−1
x(un−1qn+un−2)+un−1

=

vnx+vn−1
unx+un−1

Donc au rang n−1 et pour x=qn, on obtient

[q2,..., qn]=

vn+1
un+1

#### 1.4.3 La puissance rapide itérative

Pour calculer ak (mod n ), on décompose k en base 2

k=

J
∑
j=0

kj 2j, ak =

J
∏
j=0

akj 2j =

∏
j/kj ≠ 0

a2j

On initialise une variable `B` à 1, `B` vaudra ak (mod n ) en fin de calcul, on initialise une variable `k` à k. On calcule dans une boucle les carrés successifs de a (mod n ) que l’on stocke dans une variable `A` (`A` vaudra donc successivement a (mod n ), a2 (mod n ), a4 (mod n ), ...) et simultanément on teste si kj vaut 1 en prenant le reste de la division par 2 de `k` (dans ce cas on multuplie `B` par `A` modulo n), on divise ensuite `k` par 2 au sens du quotient euclidien.

    rapide(a,k,n):={
      local A,B;
      A:=a; B:=1;
      tantque k!=0 faire
        si irem(k,2)==1 alors B:=irem(A*B,n); fsi;
        k:=iquo(k,2);
        A:=irem(A*A,n);
      ftantque;
      return B;
    }

### 1.5 Pour en savoir plus.

Sur des aspects plus théoriques :

- Knuth: TAOCP (The Art of Computer Programming), volumes 1 et suivants
- Henri Cohen: A Course in Computational Algebraic Number Theory
- Davenport, Siret, Tournier: Calcul formel: Systèmes et algorithmes de manipulations algébriques

Sur des aspects plus pratiques, quelques références en ligne, la plupart sont accessibles gratuitement :

- le code source de Giac disponible à l’URL :
  `http://www-fourier.ujf-grenoble.fr/~parisse/giac.html`
- le code source de GiNaC, cf. : `http://www.ginac.de`
- le site `http://www.hpcalc.org` pour les calculatrices HP, on y trouve tout, de la documentation, des émulateurs de calculatrices HP, des outils de développement pour Windows et Unix/Linux, ... Pour ce qui concerne cet article, je conseille de lire
  `http://www.hpcalc.org/hp48/docs/programming/rplman.zip`
- le site `http://www.ticalc.org`, on y trouve le portage tigcc du compilateur C de GNU, des émulateurs, etc. Des informations de cet article ont leur source dans le guide du développeur TI89/92
  `http://education.ti.com/`
- la librairie du système `MuPAD` (archivée dans le fichier `lib.tar` des distributions Unix, pour une installation par défaut, ce fichier se trouve dans le rérpertoire `/usr/local/MuPAD/share/lib`), cf. `www.sciface.com` pour obtenir une licence d’utilisation.
- en Maple, il est possible de décompiler une instruction `Maple` avec la commande
  `eval(instruction);`
  après avoir tapé
  `interface(verboseproc=2);`
- le source du plus ancien système de calcul formel `maxima` (devenu logiciel libre) pour les personnes familières du langage Lisp
  `http://sourceforge.net/projects/maxima`
  de même pour le système Axiom
- le source de librairies plus spécialisées (GMP, GP-PARI, Singular, NTL, Zen, ALP, GAP, CoCoA, ...), rechercher ces moms sur google.

## 2 Exercices sur types, calcul exact et approché, algorithmes de bases

Pour télécharger et installer Xcas sur votre ordinateur, suivre les instructions données sur
`http://www-fourier.ujf-grenoble.fr/~parisse/giac_fr.html`
Pour lancer `xcas` sous Unix, ouvrir un fenêtre terminal et taper la commande
`xcas &`
Lors de la première exécution, vous devrez choisir entre différents types de syntaxe (compatible C, maple ou TI89). Vous pouvez changer ce choix à tout moment en utilisant le menu Configuration->mode (syntaxe).

L’aide en ligne est accessible en tapant `?nom_de_commande`. Dans Xcas, vous pouvez aussi taper le début d’un nom de commande puis la touche de tabulation (à gauche du A sur un clavier francais), sélectionner la commande dans la boite de dialogues puis cliquer sur Details pour avoir une aide plus complète dans votre navigateur. Pour plus de détails sur l’interface de Xcas, consultez le manuel (Aide->Interface). Si vous n’avez jamais utilisé de logiciel de calcul formel, vous pouvez commencer par lire le tutoriel (menu Aide->Debuter en calcul formel->tutoriel) et faire certains des exercices proposés (des corrigés sous forme de sessions Xcas sont dans Aide->Debuter en calcul formel->solutions)

Il peut être interessant de tester ces exercices en parallèle avec Xcas et des calculatrices formelles....

1. Utiliser la commande `type` ou `whattype` ou équivalent pour déterminer la représentation utilisée par le logiciel pour représenter une fraction, un nombre complexe, un flottant en précision machine, un flottant avec 100 décimales, la variable x, l’expression sin(x)+2, la fonction `x->sin(x)`, une liste, une séquence, un vecteur, une matrice. Essayez d’accéder aux parties de l’objet pour les objets composites (en utilisant `op` par exemple).
2. Comparer le type de l’objet `t` si on effectue la commande `t[2]:=0;` après avoir purgé `t` ou après avoir affecté `t:=[1,2,3]` ?
3. Comparer l’effet de l’affectation dans une liste et dans un vecteur ou une matrice sur votre logiciel (en Xcas, on peut utiliser `=<` au lieu de `:=` pour stocker par référence).
4. Voici un programme écrit en syntaxe compatible maple (menu Cfg->Mode->maple dans Xcas) qui calcule la base utilisée pour représenter les flottants.

       Base:=proc()
       local A,B;
       A:=1.0; B:=1.0;
       while evalf(evalf(A+1.0)-A)-1.0=0.0 do A:=2*A; od;
       while evalf(evalf(A+B)-A)-B<>0 do B:=B+1; od;
       B;
       end;

   Testez-le et expliquez.
5. Déterminer le plus grand réel positif x de la forme 2−n (n entier) tel que (1.0+x)−1.0 renvoie 0 sur PC avec la précision par défaut puis avec `Digits:=30`.
6. Calculer la valeur de a:=exp(π √163) avec 30 chiffres significatifs, puis sa partie fractionnaire. Proposez une commande permettant de décider si a est un entier.
7. Déterminer la valeur et le signe de la fraction rationnelle

   F(x,y)=

   1335
   4

   y6 + x2 (11x2 y2−y6 −121y4−2) +

   11
   2

   y8 +

   x
   2y

   en x=77617 et y=33096 en faisant deux calculs, l’un en mode approché et l’autre en mode exact. Que pensez-vous de ces résultats? Combien de chiffres significatifs faut-il pour obtenir un résultat raisonnable en mode approché?
8. À quelle vitesse votre logiciel multiplie-t-il des grands entiers (en fonction du nombre de chiffres)? On pourra tester le temps de calcul du produit de a(a+1) où a=10 000!, a=15000!, etc.
9. Comparer le temps de calcul de an (mod m ) par la fonction `powmod` et la méthode prendre le reste modulo m après avoir calculé an.
   Programmez la méthode rapide et la méthode lente.
   Que se passe-t-il si on essaie d’appliquer l’algorithme de la puissance rapide pour calculer (x+y+z+1)32 ? Calculer le nombre de termes dans le développement de (x+y+z+1)n et expliquez.
10. Déterminer un entier c tel que c=1 (mod 3 ), c=3 (mod 5 ), c=5 (mod 7 ) et c=2 (mod 1 )1.
11. Programmation de la méthode de Horner
    Il s’agit d’évaluer efficacement un polynôme

    P(X) = an Xn + ... + a0

    en un point. On pose b0=P(α ) et on écrit :

    P(X)−b0=(X−α )Q(X)

    où :

    Q(X) = bn Xn−1 + ... +b2 X + b1

    On calcule alors par ordre décroissant bn, bn−1, ..., b0.
    1. Donner bn en fonction de an puis pour i≤ n−1, bi en fonction de ai et bi+1. Indiquez le détail des calculs pour P(X)=X3−2X+5 et une valeur de α non nulle.
    2. Écrire un fonction `horn` effectuant ce calcul: on donnera en arguments le polynôme sous forme de la liste de ces coefficients (dans l’exemple `[1,0,-2,5]`) et la valeur de α et le programme renverra P(α ). (On pourra aussi renvoyer les coefficients de Q).
    3. En utilisant cette fonction, écrire une fonction qui calcule le développement de Taylor complet d’un polynôme en un point.
12. Algorithmes de base : écrire des programmes implémentant
    1. le pgcd de 2 entiers
    2. l’algorithme de Bézout
    3. l’inverse modulaire en ne calculant que ce qui est nécessaire dans l’algorithme de Bézout
    4. les restes chinois

## 3 Le PGCD

Comme on l’a remarqué dans le premier article, l’algorithme d’Euclide est inefficace pour calculer le pgcd de deux polynômes à coefficients entiers. On va présenter ici les algorithmes utilisés habituellement par les systèmes de calcul formel: sous-résultant (PRS), modulaire (GCDMOD), p-adique (EEZGD) et heuristique (GCDHEU). Le premier est une adaptation de l’algorithme d’Euclide et s’adapte à des coefficients assez génériques. Les trois autres ont en commun d’évaluer une ou plusieurs variables du polynôme (dans ce dernier cas il est nécessaire de bien distinguer le cas de polynômes à plusieurs variables) et de reconstruire le pgcd par des techniques distinctes, la plupart du temps ces algorithmes fonctionnent seulement si les coefficients sont entiers.

Soit donc P et Q deux polynômes à coefficients dans un corps. Le pgcd de P et Q n’est défini qu’à une constante près. Mais lorsque les coefficients de P et Q sont dans un anneau euclidien comme par exemple ℤ ou ℤ[ i ], on appelle pgcd de P et Q un polynôme D tel que P / D et Q / D soient encore à coefficients dans l’anneau, et que D soit optimal, c’est-à-dire que si un multiple µ D de D vérifie P / µ D et Q / µ D sont à coefficients dans l’anneau, alors µ est inversible. La première étape d’un algorithme de calcul de pgcd consiste donc à diviser par le pgcd des coefficients entiers de chaque polynôme.

Exemple: P = 4 X2 − 4 et Q = 6 X2 + 12 X + 6. Le polynôme X + 1 est un pgcd de P et Q puisqu’il est de degré maximal divisant P et Q mais le pgcd de P et Q est 2 ( X + 1 ). Remarquons qu’avec notre définition − 2 ( X + 1 ) convient aussi. Par convention on appelera pgcd le polynôme ayant un coefficient dominant positif.

Définition: On appelle contenu c ( P ) d’un polynôme P le pgcd des coefficients de P. On définit alors la partie primitive de P: pp( P ) = P / c ( P ). Si c(P)=1, on dit que P est primitif. On montre que :

D = pgcd ( P, Q ) = pgcd ( c ( P ), c ( Q )) pgcd ( pp ( P ), pp ( Q ))

### 3.1 Le sous-résultant.

La première idée qui vient à l’esprit pour améliorer l’efficacité de l’algorithme d’Euclide consiste à éviter les fractions qui sont créées par les divisions euclidiennes. On utilise à cet effet la pseudo-division: au lieu de prendre le reste R de la division euclidienne du polynôme P par Q, on prend le reste de la division de P qδ + 1 par Q, où q désigne le coefficient dominant de Q et δ la différence entre le degré de P et de Q.

Exercice: En utilisant votre système de calcul formel préféré, calculez les restes intermédiaires générés dans l’algorithme d’Euclide lorsqu’on utilise la pseudo-division par exemple pour les polynômes P ( x ) = ( x + 1 )7 − ( x − 1 )6 et sa dérivée.

Une solution avec giac/xcas:

    // -*- mode:C++ -*- a,b 2 polynomes -> pgcd de a et b
    pgcd(a,b):={
     local P,p,Q,q,R,g,h,d;
     // convertit a et b en polynomes listes et extrait la partie primitive
     P:=symb2poly1(a);
     p:=lgcd(P); // pgcd des elements de la liste
     P:=P/p;
     Q:=symb2poly1(b);
     q:=lgcd(Q);
     Q:=Q/q;
     if (size(P)<size(Q)){ // echange P et Q
      R:=P; P:=Q; Q:=R;
     }
     // calcul du contenu du pgcd
     p:=gcd(p,q);
     g:=1;
     h:=1;
     while (size(Q)!=1){
      q:=Q[0]; // coefficient dominant
      d:=size(P)-size(Q);
      R:=rem(q^(d+1)*P,Q);
      if (size(R)==0) return(p*poly12symb(Q/lgcd(Q),x));
      P:=Q;
      Q:=R;
      // ligne suivante a decommenter pour prs
      // Q:=R/(g*h^d);
      print(Q);
      // ligne suivante a decommenter pour prs
      // g:=q; h:=q^d/h^(d-1);
     }
     return(p);
    }

On s’aperçoit que les coefficients croissent de manière exponentielle. La deuxième idée qui vient naturellement est alors à chaque étape de rendre le reste primitif, donc de diviser R par le pgcd de ces coefficients. Cela donne un algorithme plus efficace, mais encore assez peu efficace car à chaque étape on doit calculer le pgcd de tous les coefficients, on peut imaginer le temps que cela prendra en dimension 1 et à fortiori en dimension supérieure. L’idéal serait de connaitre à l’avance une quantité suffisamment grande qui divise tous les coefficients du reste.

C’est ici qu’intervient l’algorithme du sous-résultant: après chaque pseudo-division euclidienne, on exhibe un coefficient "magique" qui divise les coefficients du reste. Ce coefficient n’est pas le pgcd mais il est suffisamment grand pour qu’on évite la croissance exponentielle des coefficients.

Algorithme du sous-résultant

Arguments: 2 polynômes P et Q primitifs. Valeur de retour: le pgcd de P et Q.

Pour calculer le coefficient "magique" on utilise 2 variables auxiliaires g et h initialisées a 1.

Boucle à effectuer tant que Q est non nul:

- on note δ =degre(P)-degre(Q) et q le coefficient dominant de Q
- on effectue la division euclidienne (sans fraction) de qδ + 1 P par Q, soit R le reste
- Si R est constant, on sort de l’algorithme en renvoyant 1 comme pgcd
- on recopie Q dans P puis R / ( g hδ ) dans Q
- on recopie q dans g et h1 − δ qδ dans h.

Si on sort normalement de la boucle, Q est nul, on renvoie donc la partie primitive de P qui est le pgcd cherché.

Pour tester l’algorithme avec `xcas`, il suffit de décommenter les deux lignes `Q:=R/(g*h^d);` et `g:=q; h:=q^d/h (d-1);` ci-dessus.

La preuve de l’algorithme est un peu longue et par ailleurs bien expliquée dans le 2ème tome de Knuth (The Art of Computer Programming, Semi-numerical Algorithms), on y renvoie donc le lecteur intéressé. L’idée générale (et l’origine du nom de l’algorithme) est de considérer la matrice de Sylvester des polynômes de départ P et Q (celle dont le déterminant est appelé résultant de P et Q) et de traduire les pseudo-divisions qui permettent de calculer les restes successifs du sous-résultant en opération de ligne sur ces matrices. On démontre alors que les coefficients de R divisés par g hδ peuvent être interprétés comme des déterminants de sous-matrices de la matrice de Sylvester après réduction et c’est cela qui permet de conclure qu’ils sont entiers.

Par exemple, supposons que P=R0, Q=R1, R2... diminuent de 1 en degré à chaque division (c’est le cas générique dans le déroulement de l’algorithme d’Euclide). Dans ce cas, δ=1, il s’agit par exemple de montrer que le reste R3 de Q=R1 par R2 est divisible par le carré du coefficient dominant de Q=R1. Voyons comment on obtient les coefficients de R3 à partir de la matrice de Sylvester de P et Q. Prenons la sous-matrice constituée des 2 premières lignes de P et des 3 premières lignes de Q et réduisons-la sous forme échelonnée sans introduire de dénominateur.

⎛
⎜
⎜
⎜
⎜
⎜
⎝

pn | pn−1 | pn−2 | pn−3 | ...
0 | pn | pn−1 | pn−2 | ...
qn−1 | qn−2 | qn−3 | qn−4 | ...
0 | qn−1 | qn−2 | qn−3 | ...
0 | 0 | qn−1 | qn−2 | ...

⎞
⎟
⎟
⎟
⎟
⎟
⎠

On effectue L1 ← qn−1 L1 − pn L3 et L2 ← qn−1 L2 − pn L4, ce qui correspond à l’élimination du terme en x du quotient de P par Q

⎛
⎜
⎜
⎜
⎜
⎜
⎝

0 | qn−1 pn−1 − pn qn−2 | ... | ... | ...
0 | 0 | qn−1 pn−1 − pn qn−2 | ... | ...
qn−1 | qn−2 | qn−3 | qn−4 | ...
0 | qn−1 | qn−2 | qn−3 | ...
0 | 0 | qn−1 | qn−2 | ...

⎞
⎟
⎟
⎟
⎟
⎟
⎠

on effectue ensuite

L1 | ← | qn−1 L1 − (qn−1 pn−1 − pn qn−2) L4
L2 | ← | qn−1 L2 − (qn−1 pn−1 − pn qn−2) L5

ce qui correspond à l’élimination du terme constant du quotient de P par Q, on obtient

⎛
⎜
⎜
⎜
⎜
⎜
⎝

0 | 0 | r2,n−2 | ... | ...
0 | 0 | 0 | r2,n−2 | ...
qn−1 | qn−2 | qn−3 | qn−4 | ...
0 | qn−1 | qn−2 | qn−3 | ...
0 | 0 | qn−1 | qn−2 | ...

⎞
⎟
⎟
⎟
⎟
⎟
⎠

si on enlève les lignes 3 et 4, et les colonnes 1 et 2, on obtient (après échanges de lignes) une sous-matrice de la matrice de Sylvester de Q et R2

⎛
⎜
⎜
⎝

qn−1 | qn−2 | ...
r2,n−2 | ... | ...
0 | r2,n−2 | ...

⎞
⎟
⎟
⎠

On recommence les opérations de réduction de cette sous-matrice correspondant à la division euclidienne de Q par R2, on obtient

⎛
⎜
⎜
⎝

0 | 0 | r3,n−3
r2,n−2 | ... | ...
0 | r2,n−2 | ...

⎞
⎟
⎟
⎠

puis après suppression des colonnes 1 et 2 et des lignes 2 et 3 la ligne des coefficients de R3.

Supposons qu’on se limite dès le début de la réduction à ne garder que les colonnes 1 à 4 et une 5-ième colonne parmi les suivantes, on obtient à la fin de la réduction une matrice 1,1 qui contient un des coefficients de R3 (selon le choix de la 5-ième colonne). Donc ce coefficient est égal au déterminant de la matrice 1,1 qui est égal, au signe près, au déterminant de la matrice 3,3 dont il est issu par notre réduction (en effet, dans la 2ième partie de la réduction, on a multiplié deux fois L1 par r2,n−2, mais on doit ensuite diviser le déterminant par r2,n−22 pour éliminer les colonnes 1 et 2). Quant au déterminant de la matrice 3,3, il se déduit du déterminant de la matrice 5,5 par multiplication par qn−14 (2 lignes ont été multipliées 2 fois par qn−1) et division par qn−12 (élimination des colonnes 1 et 2). Au final, tout coefficient de R3 est égal au produit d’un déterminant 5,5 extrait de la matrice de Sylvester de P et Q par qn−12, qui est justement le coefficient “magique” par lequel on divise le reste de R1=Q par R2 lors de l’algorithme du sous-résultant.

### 3.2 Le pgcd en une variable

.

#### 3.2.1 Le pgcd heuristique.

On suppose ici que les coefficients sont entiers ou entiers de Gauss. On peut donc se ramener au cas où les polynômes sont primitifs.

L’idée consiste à évaluer P et Q en un entier z et à extraire des informations du pgcd g des entiers P ( z ) et Q ( z ). Il faut donc un moyen de remonter de l’entier g à un polynôme G tel que G ( z ) = g. La méthode consiste à écrire en base z l’entier g, avec une particularité dans les divisions euclidiennes successives on utilise le reste symétrique (compris entre − z / 2 et z / 2). Cette écriture donne les coefficients d’un polynôme G unique. On extrait ensuite la partie primitive de ce polynôme G. Lorsque z est assez grand par rapport aux coefficients des polynômes P et Q, si pp ( G ) divise P et Q, on va montrer que le pgcd de P et de Q est D = pp ( G ).

On remarque tout d’abord que d : = D ( z ) divise g. En effet D divise P et Q donc pour tout entier (ou entier de Gauss) z, D ( z ) divise P ( z ) et Q ( z ). Il existe donc une constante a telle que

g = a d

On a aussi pp ( G ) divise D. Il existe donc un polynôme C tel que :

D = pp ( G ) C

Nous devons prouver que C est un polynôme constant. On suppose dans la suite que ce n’est pas le cas. Evaluons l’égalité précédente au point z, on obtient

d =

g
c ( G )

C ( z )

Finalement

1 =

a
c ( G )

C ( z )

La procédure de construction de G nous donne une majoration de ces coefficients par | z | / 2, donc de c ( G ) par | z | / 2, donc C ( z ) divise un entier de module plus petit que | z | / 2, donc

| C ( z ) | ⩽

| z |
2

On considère maintenant les racines complexes z1, … ., zn du polynôme C (il en existe au moins une puisqu’on a supposé C non constant). On a:

C ( X ) = cn ( X − z1 ) … . ( X − zn )

Donc, comme cn est un entier (ou entier de Gauss) non nul, sa norme est supérieure ou égale à 1 et :

| C ( z ) | ⩾

n
∏
j = 1

( | z | − | zj | )

Il nous reste à majorer les racines de C pour minorer | C ( z ) |. Comme C divise D il divise P et Q donc les racines de C sont des racines communes à P et Q. On va appliquer le:

Lemme 1 Soit x une racine complexe d’un polynôme P = an Xn + … . + a0.

Alors

| x | < | P |/| an | + 1, | P | = max0 ⩽ i ⩽ n ( | ai | )

Application du lemme à C(X) : on a 1/|cn|≤ 1 donc si on a choisi z tel que | z | ⩾ 2 min( | P |, | Q | ) + 2, alors pour tout j, | zj | < | z | / 2 donc

| C ( z ) | >

⎛
⎜
⎜
⎝

| z |
2

⎞
⎟
⎟
⎠

n

qui contredit notre majoration de | C ( z ) |.

Théorème 1 Soit P et Q deux polynômes à coefficients entiers. On choisit un entier z tel que | z | ⩾ 2 min( | P |, | Q | ) + 2, si la partie primitive du polynôme G reconstruit à partir du pgcd de P ( z ) et Q(z) par écriture en base z (avec comme reste euclidien le reste symétrique) divise P et Q alors c’est le pgcd de P et Q.

Pour finir la démonstration du théorème, il nous faut encore montrer le lemme. On a

− an xn = an − 1 xn − 1 + … . + a0

Donc

| an | | x |n ⩽ | P | ( 1 + … . + | x |n − 1 ) = | P |

| x |n − 1
| x | − 1

Ici on peut supposer que | x | ⩾ 1, sinon le lemme est démontré, donc | x | − 1 est positif et

| an | ( | x | − 1 ) ⩽ | P |

| x |n − 1
| x |n

⇒ | x | − 1 <

| P |
| an |

Remarques

- Le théorème publié par Char, Geddes et Gonnet porte sur des coefficients entiers et c’est comme cela qu’il est utilisé par les systèmes de calcul formel (en commençant historiquement par Maple). Peu de systèmes l’utilisent pour les polynômes à coefficients entiers de Gauss. On peut d’ailleurs généraliser le théorème à d’autres types de coefficients, à condition d’avoir un anneau euclidien plongé dans ℂ avec une minoration sur la valeur absolue des élements non nuls de l’anneau.
- Nous n’avons jusqu’à présent aucune certitude qu’il existe des entiers z tels que la partie primitive de G divise P et Q. Nous allons montrer en utilisant l’identité de Bézout que pour z assez grand c’est toujours le cas. Plus précisément, on sait qu’il existe deux polynômes U et V tels que

  P U + Q V = D

  Attention toutefois, U et V sont à coefficients rationnels, pour avoir des coefficients entiers, on doit multiplier par une constante entière α, donc en évaluant en z on obtient l’existence d’une égalité à coefficients entiers

  P ( z ) u + Q ( z ) v = α D ( z )

  Donc le pgcd g de P ( z ) et Q ( z ) divise α D ( z ) = α d. Comme g est un multiple de d, on en déduit que g = β d, où β est un diviseur de α. Si on a choisi z tel que

  | z | > 2 | D | | α |

  alors | z | > 2 | D | | β | donc l’écriture symétrique en base z de g est G = β D. Donc la partie primitive de G est D, le pgcd de P et Q.

Exemple 1 Si P0 = 6 ( X2 − 1 ) et Q0 = 4 ( X3 − 1 ).

Le contenu de P0 est 6, celui de Q0 est 4.
On a donc pgcd des contenus = 2, P = X2 − 1, Q = X3 − 1. La valeur initiale de z est donc 2 ∗ 1 + 2 = 4. On trouve P ( 4 ) = 15, Q ( 4 ) = 63. Le pgcd entier de 15 et 63 est 3 que nous écrivons symétriquement en base 4 sous la forme 3 = 1 ∗ 4 − 1, donc G = X − 1, sa partie primitive est X − 1. On teste si X − 1 divise P et Q, c’est le cas, donc c’est le pgcd de P et Q et le pgcd de P0 et Q0 est 2 ( X − 1 ).

Algorithme gcdheu
En arguments deux polynômes P0 et Q0 à coefficients entiers ou entiers de Gauss. Retourne le pgcd de P0 et Q0 ou faux en cas d’échec.

1. Calculer le contenu de P0 et Q0. Vérifier que les coefficients sont entiers de Gauss sinon retourner faux.
2. Extraire la partie primitive P de P0 et Q de Q0, calculer le pgcd c des contenus de P0 et Q0
3. Déterminer z = 2 min( | P |, | Q | ) + 2.
4. Début de boucle: initialisation du nombre d’essais à 1, test d’arrêt sur un nombre maximal d’essais, avec changement de z entre deux itérations (par exemple z ← 2 z).
5. Calculer le pgcd g de P ( z ) et Q ( z ) puis son écriture symétrique en base z dont on extrait la partie primitive G.
6. Si G ne divise pasP passer à l’itération suivante. De même pour Q.
7. Retourner c G
8. Fin de la boucle
9. Retourner faux.

On remarque au passage qu’on a calculé le quotient de P par G et le quotient de Q par G lorsque la procédure réussit. On peut donc passer à la procédure gcdheu deux paramètres supplémentaires par référence, les deux polynômes que l’on affectera en cas de succès, ce qui optimise la simplification d’une fraction de 2 polynômes.

#### 3.2.2 Le pgcd modulaire

On part du fait que si D est le pgcd de P et Q dans ℤ (ou ℤ [ i ] ) alors après réduction modulo un nombre premier n qui ne divise pas les coefficients dominants de P et Q, D divise le pgcd G de P et Q dans ℤ / n ℤ (par convention, le pgcd dans ℤ / n ℤ est normalisé pour que son coefficient dominant vaille 1). Comme on calcule G dans ℤ / n ℤ, les coefficients des restes intermédiaires de l’algorithme d’Euclide sont bornés, on évite ainsi la croissance exponentielle des coefficients. Il faudra ensuite reconstruire D à partir de G.

On remarque d’abord que si on trouve G = 1, alors P et Q sont premiers entre eux. En général, on peut seulement dire que le degré de G est supérieur ou égal au degré de D. En fait, le degré de G est égal au degré de D lorsque les restes de l’algorithme d’Euclide (calculé en effectuant des pseudo-divisions, cf. l’exercice 1) ont leur coefficient dominant non divisible par n. Donc plus n est grand, plus la probabilité est grande de trouver G du bon degré.

Dans la suite, nous allons déterminer une borne b à priori majorant les coefficients de D. On utilisera ensuite la même méthode que dans l’algorithme modulaire de recherche de racines évidentes: on multiplie G dans ℤ / n ℤ par le pgcd dans ℤ des coefficients dominants p et q de P et Q. Soit D = pgcd ( p, q ) G le résultat écrit en représentation symétrique. Si n ⩾ b pgcd ( p, q ) et si G est du bon degré, on montre de la même manière que D = D. Comme on ne connait pas le degré de D, on est obligé de tester si D divise P et Q. Si c’est le cas, alors D divise D donc D = D puisque degre ( D ) = degre ( G ) ⩾ degre ( D ). Sinon, n est un nombre premier malchanceux pour ce calcul de pgcd (degre ( G ) ⩾ degre ( D )), il faut essayer un autre premier.

Remarque: On serait tenté de dire que les coefficients de D sont bornés par le plus grand coefficient de P. C’est malheureusement faux, par exemple ( X + 1 )2 dont le plus grand coefficient est 2 divise ( X + 1 )2 ( X − 1 ) dont le plus grand coefficient (en valeur absolue) est 1.

Soit P = ∑pi Xi un polynôme à coefficients entiers. On utilise la norme euclidienne

| P |2 = ∑| pi |2 (1)

On établit d’abord une majoration du produit des racines de norme supérieure à 1 de P à l’aide de | P |. Ensuite si D est un diviseur de P, le coefficient dominant d de D divise le coefficient dominant p de P et les racines de D sont aussi des racines de P. On pourra donc déterminer une majoration des polynômes symétriques des racines de D et donc des coefficients de D.

Lemme 2 Soit A = ∑j = 0a aj Xj un polynôme et α ∈ ℂ. Alors

| ( X − α ) A | = | ( α X − 1 ) A |

Pour prouver le lemme 2, on développe les produits de polynômes. On pose a−1 = aa + 1 = 0 et on note ℜ la partie réelle.

| ( X − α ) A |2 = ∑j = 0a + 1 | aj − 1 − α aj |2 =

a + 1
∑
j = 0

| aj − 1 |2 + | α |2 | aj |2 − 2 ℜ ( aj − 1

α aj

)

| ( α X − 1 ) A |2 =

a + 1
∑
j = 0

|

α

aj − 1 − aj |2 =

a + 1
∑
j = 0

| α |2 | aj − 1 |2 + | aj |2 − 2 ℜ (

α

aj − 1

aj

)

Les deux donnent bien le même résultat.

Soit P ( X ) = p ∏( X − αj ) la factorisation de P sur ℂ. On introduit le polynôme

P = p

∏
j / | αj | ⩾ 1

( X − αj )

∏
j / | αj | < 1

(

αj

X − 1 )

qui d’après le lemme a la même norme que P. La norme de P majore donc le coefficient constant de P d’où:

∏j / | αj | ⩾ 1 | αj | ⩽ | P |/| p | (2)

On remarque que (2) reste vraie si on considère les racines δj de norme plus grande que 1 d’un diviseur D de P puisque le produit porte alors sur un sous-ensemble. On écrit maintenant l’expression des coefficients dj de D à l’aide des racines δj de D:

| dm − j | = | d |

⎪
⎪
⎪
⎪

∑
choix de j racines parmi les m racines de D

∏
δk ∈ racines choisies

δk

⎪
⎪
⎪
⎪

Pour majorer | dm − j |, on commence par majorer | δk | par βk = max( 1, | δk | ). On est donc ramené à majorer

σj, m ( β ) =

∑
choix de j parmi m valeurs βk

∏
βk ∈ choix

βk

avec pour hypothèse une majoration de M = ∏k = 1m βk donnée par la relation (2). Pour cela, on cherche le maximum de σj, m ( β ) sous les contraintes M fixé et βk ⩾ 1.

On va montrer que le maximum ne peut être atteint que si l’un des βk = M (et tous les autres βk = 1 ). Sinon, quitte à réordonner supposons que les βk sont classés par ordre croissant. On a donc βm − 1 ≠ 1, on pose βk = βk pour k ⩽ m − 2, βm − 1 = 1 et βm = βm − 1 βm. Comparons σj, m ( β ) et σj, nm ( β ). Si le choix de j parmi m comporte k = m − 1 et k = m, le produit est inchangé. Sinon on a la somme de deux produits, l’un contenant k = m − 1 et l’autre k = m. On compare donc B ( βm − 1 + βm ) et B ( 1 + βm − 1 βm ) avec B = ∏βk ∈ reste du choix βk. Comme

1 + βm − 1 βm ⩾ βm − 1 + βm

puisque la différence est le produit (1−βm)(1−βm−1) de deux nombres positifs, on arrive à la contradiction souhaitée.

Ensuite on décompose les choix de σm, j en ceux contenant M et des 1 et ceux ne contenant que des 1, d’où la majoration

σj, m ( β ) ⩽

⎛
⎜
⎝

m − 1
j − 1

⎞
⎟
⎠

M +

⎛
⎜
⎝

m − 1
j

⎞
⎟
⎠

et finalement

| dm − j | ⩽ | d |

⎛
⎜
⎜
⎝

⎛
⎜
⎝

m − 1
j − 1

⎞
⎟
⎠

| P |
| p |

+

⎛
⎜
⎝

m − 1
j

⎞
⎟
⎠

⎞
⎟
⎟
⎠

(3)

On peut en déduire une majoration indépendante de j sur les coefficients de D, en majorant | d | par | p | (puisque d divise p) et les coefficients binomiaux par 2m − 1 (obtenue en développant ( 1 + 1 )m − 1). D’où le

Théorème 2 (Landau-Mignotte) Soit P un polynôme à coefficients entiers (ou entiers de Gauss) et D un diviseur de P de degré m. Si | P | désigne la norme euclidienne du vecteur des coefficients de P et p le coefficient dominant de P alors les coefficients dj de D satisfont l’inégalité

| dj | ⩽ 2m − 1 ( | P | + | p | ) (4)

Avec cette estimation, on en déduit que si n est un premier plus grand que

min( 2degre ( P ) − 1 ( | P | + | p | ), 2degre ( Q ) − 1 ( | Q | + | q | ) ), (5)

alors le pgcd trouvé dans ℤ / n ℤ va se reconstruire en un pgcd dans ℤ si son degré est le bon.

Malheureusement la borne précédente est souvent très grande par rapport aux coefficients du pgcd et calculer dans ℤ / n ℤ s’avèrera encore inefficace (surtout si le pgcd est 1). Cela reste vrai même si on optimise un peu la majoration (5) en repartant de (3).

L’idée est donc de travailler modulo plusieurs nombres premiers plus petits et reconstruire le pgcd des 2 polynômes à coefficients entiers à partir des pgcd des polynômes dans ℤ / n ℤ et du théorème des restes chinois. En pratique on prend des nombres premiers inférieurs à la racine carrée du plus grand entier hardware de la machine (donc plus petits que 216 sur une machine 32 bits) ce qui permet d’utiliser l’arithmétique hardware du processeur sans risque de débordement.

Algorithme du PGCD modulaire en 1 variable:

En argument: 2 polynômes primitifs P et Q à coefficients entiers. Le résultat renvoyé sera le polynôme pgcd.

Variable auxiliaire: un entier N initialisé à 1 qui représente le produit des nombres premiers utilisés jusqu’ici et un polynôme H initialisé à 0 qui représente le pgcd dans ℤ / N ℤ.

Boucle infinie :

1. Chercher un nouveau nombre premier n qui ne divise pas les coefficients dominants p et q de P et Q
2. Calculer le pgcd G de P et Q dans ℤ / n ℤ. Si G=1, renvoyer 1.
3. Si H = 0 ou si le degré de G est plus petit que le degré de H, recopier G dans H et n dans N, passer à la 6ème étape
4. Si le degré de G est plus grand que celui de H passer à l’itération suivante
5. Si le degré de G est égal au degré de H, en utilisant le théorème des restes chinois, calculer un polynôme H tel que H = H modulo N et H = G modulo n. Recopier H dans H et n N dans N.
6. Ecrire pgcd ( p, q ) H en représentation symétrique. Soit H le résultat rendu primitif. Tester si H divise P et Q. Si c’est le cas, renvoyer H, sinon passer à l’itération suivante.

Finalement on n’a pas utilisé b, la borne de Landau-Mignotte. On peut penser que l’étape 6 ne devrait être effectuée que lorsque N est plus grand que pgcd ( p, q ) b. En pratique, on effectue le test de l’étape 6 plus tôt parce que les coefficients du pgcd sont rarement aussi grand que b. Mais pour éviter de faire le test trop tôt, on introduit une variable auxiliaire H′ qui contient la valeur de H de l’itération précédente et on ne fait le test que si H′ = H (ou bien sûr si on a dépassé la borne).

Remarque:

L’algorithme ci-dessus fonctionne également pour des polynômes à plusieurs variables.

Exemple 1:

Calcul du pgcd de ( X + 1 )3 ( X − 1 )4 et ( X4 − 1 ). Prenons pour commencer n = 2. On trouve comme pgcd X4 + 1 (en effet − 1 = 1 donc on cherchait le pgcd de ( X + 1 )7 et de X4 + 1 = ( X + 1 )4). On teste si X4 + 1 divise P et Q, ce n’est pas le cas donc on passe au nombre premier suivant. Pour n = 3, on trouve X2 − 1. Donc n = 2 n’était pas un bon nombre premier pour ce calcul de pgcd puisqu’on a trouvé un pgcd de degré plus petit. On teste si X2 − 1 divise P et Q, c’est le cas ici donc on peut arrêter, le pgcd cherché est X2−1.

Exemple 2 :

Calcul du pgcd de ( X + 1 )3 ( X − 1 )4 et ( X4 − 1 )3. Pour n = 2, on trouve un polynôme de degré 7. Pour n = 3, on trouve X6 − 1 donc n = 2 était une mauvaise réduction. Comme X6 − 1 ne divise pas P et Q, on passe à n = 5. On trouve X6 + 2 X4 − 2 X2 − 1. On applique le théorème des restes chinois qui va nous donner un polynôme dans ℤ / 15 ℤ. On cherche donc un entier congru à 2 modulo 5 et à 0 modulo 3, -3 est la solution (écrite en représentation symétrique), donc le polynôme modulo 15 est X6 − 3 X4 + 3 X2 − 1 = ( X2 − 1 )3. Ce polynôme divise P et Q, c’est donc le pgcd de P et de Q.

### 3.3 Le pgcd à plusieurs variables.

#### 3.3.1 Le pgcd heuristique.

On suppose comme dans le cas à une variable que les polynômes sont primitifs, donc qu’on a simplifié les polynômes par le pgcd entier de leurs coefficients entiers.

Le principe est identique à celui du PGCD à 1 variable, on évalue les deux polynômes P et Q de k variables X1, … ., Xk en un Xk = z et on calcule le pgcd g des 2 polynômes P ( z ) et Q ( z ) de k − 1 variables. On remonte ensuite à un polynôme G par écriture symétrique en base z de g et on teste si pp ( G ) divise P et Q. Il s’agit à nouveau de montrer que si z est assez grand, alors pp ( G ) est le pgcd cherché. On sait que d = D ( z ) divise g. Il existe donc un polynôme a de k − 1 variables tel que g = a d. On sait aussi que pp ( G ) divise D, donc il existe un polynôme C de k variables tel que D = C ∗ pp ( G ) . On évalue en z et on obtient d = C ( z ) g / c ( G ), où c ( G ) est un entier, donc

c ( G ) = a ∗ C ( z )

Comme c ( G ) est un entier, a et C ( z ) sont des polynômes constants. Comme précédemment, on a aussi | C ( z ) | ⩽ | z | / 2 puisque | c ( G ) | ⩽ | z | / 2.

- Premier cas: si C ne dépend que de la variable Xk. On continue le raisonnement comme dans le cas unidimensionnel.
- Deuxième cas: si C dépend d’une autre variable, par exemple X1. On regarde le coefficient de plus haut degre de C par rapport a X1. Ce coefficient divise le coefficient de plus haut degre de P et de Q par rapport a X1. Comme C ( z ) est constant, on en deduit que le coefficient de plus haut degre de P et Q par rapport a X1 est divisible par Xk − z donc le coefficient de plus bas degre en Xk de ces coefficients de plus haut degre est divisible par z, ce qui contredit la majoration de ce coefficient.

En pratique, cet algorithme nécessite le calcul récursif de pgcd sans garantie de réussite. On l’évite donc s’il y a beaucoup de variables (la limite est par exemple de 5 pour MuPAD).

#### 3.3.2 Le pgcd modulaire multivariables.

Ici, on travaille modulo Xn − α, où X1, … ., Xn désignent les variables des polynômes. On considère donc deux polynômes P et Q comme polynômes de la variables Xn avec des coefficients dans ℤ [ X1, … ., Xn − 1 ]. On évalue en Xn = α, on obtient deux polynômes en n − 1 variables dont on calcule le pgcd (récursivement).

Il s’agit de reconstruire le pgcd par interpolation. Tout d’abord, on a une borne évidente sur le degré du pgcd par rapport à la variable Xn, c’est le minimum δ des degrés par rapport à Xn des polynômes P et Q. A première vue, il suffit donc d’évaluer les polynômes en δ + 1 points α.

Il faut toutefois prendre garde aux mauvaises évaluations et à la normalisation des pgcd avant d’interpoler. En effet, si D ( X1, … ., Xn ) désigne le pgcd de P et Q et G ( X1, … ., Xn − 1 ) le pgcd de P ( X1, … ., Xn − 1, α ) et de Q ( X1, … ., Xn − 1, α ), on peut seulement dire D ( X1, … ., Xn − 1, α ) divise G. Plusieurs cas sont donc possibles lorsqu’on évalue en un nouveau point α:

- l’un des degrés de G est plus petit que le degré du polynôme D′ reconstruit par interpolation jusque là. Dans ce cas, toutes les évaluations qui ont conduit à reconstruire D′ étaient mauvaises. Il faut recommencer l’interpolation à zéro ou à partir de G (si tous les degrés de G sont inférieurs ou égaux aux degrés du D′ reconstruit).
- l’un des degrés de G est plus grand que le degré du D′ reconstruit jusque là. Il faut alors ignorer α.
- Tous les degrés de G sont égaux aux degrés du D′ reconstruit jusque là. Dans ce cas, G est un multiple entier du polynôme D′ reconstruit jusque là et évalué en Xn = α. Si on suppose qu’on a pu s’arranger pour que ce multiple soit 1, on ajoute le point α aux points d’évaluation précédents αj en posant:

  D′ = D′ + ( G − D′ )

  ∏
  αj

  ( Xn − αj )

  ∏
  αj

  ( α − αj )

On voit que les mauvaises évaluations se détectent simplement par les degrés. Pour la normalisation, on utilise une petite astuce: au lieu de reconstruire le pgcd D, on va reconstruire un multiple du pgcd D (ce multiple appartiendra à ℤ [ Xn ] ). On voit maintenant P et Q comme des polynômes en n − 1 variables X1, … ., Xn − 1 à coefficients dans ℤ [ Xn ]. Alors lcoeff(D), le coefficient dominant de D (relativement à l’ordre lexicographique sur les variables X1,...,Xn−1), est un polynôme en Xn qui divise le coefficient dominant de P et de Q donc divise le coefficient dominant du pgcd des coefficients dominants de P et de Q. On va donc reconstruire le polynôme :

D′ = D

Δ ( Xn )
lcoeff ( D ) ( Xn )

, Δ ( Xn ) = pgcd ( lcoeff ( P ) ( Xn ), lcoeff ( Q ) ( Xn ))

c’est-à-dire D multiplié par un polynôme qui ne dépend que de Xn.

Revenons à G en un point α de bonne évaluation. C’est un multiple entier de D ( X1, … ., Xn − 1, α ):

G = β D ( X1, … ., Xn − 1, α )

Donc, comme polynômes de X1,...,Xn−1 à coefficients dans ℤ[Xn] ou dans ℤ, lcoeff ( G ) = β lcoeff ( D )| Xn = α. Comme lcoeff ( D ) divise Δ ( Xn ), il en est de même en Xn = α donc lcoeff(G) divise β Δ(α). On en déduit que Δ ( α) G qui est divisible par Δ (α) β est divisible par lcoeff ( G ). On va donc considérer le polynôme Δ (α) G / lcoeff ( G ) : ses coefficients sont entiers et son coefficient dominant est

Δ ( α) = lcoeff(D′( X1, … ., Xn − 1, α ))

donc

Δ (α) G / lcoeff ( G )= D′( X1, … ., Xn − 1, α )

Algorithme du pgcd modulaire à plusieurs variables (interpolation dense):

Arguments: 2 polynômes primitifs P et Q de n variables X1, … ., Xn à coefficients entiers. Renvoie le pgcd de P et Q.

1. Si n = 1, renvoyer le pgcd de P et Q en une variable.
2. Test rapide de pgcd trivial par rapport à Xn. On cherche des n − 1-uplets α tels que P ( α, Xn ) et Q ( α, Xn ) soient de même degré que P et Q par rapport à la variable Xn. On calcule le pgcd G de ces 2 polynômes en une variable. Si le pgcd est constant, alors on retourne le pgcd des coefficients de P et Q.
3. On divise P et Q par leur contenu respectifs vu comme polynômes en X1, … ., Xn − 1 à coefficients dans ℤ [ Xn ], on note C ( Xn ) le pgcd des contenus. On calcule aussi le pgcd Δ ( Xn ) des coefficients dominants de P et de Q.
4. On initialise D′ le pgcd reconstruit à 0, I ( Xn ) le polynôme d’interpolation à 1, δ=(δ1,...,δn−1) la liste des degrés partiels du pgcd par rapport à X1, … ., Xn − 1 au minimum des degrés partiels de P et Q par rapport à X1, … ., Xn − 1, e le nombre d’évaluation à 0 et E l’ensemble des points d’interpolation à la liste vide.
5. Boucle infinie:
   - Faire α=entier aléatoire n’appartenant pas à E jusqu’à ce que

     degre(P ( X1, … ., Xn − 1, α ))=degreXn ( P ( X1, … ., Xn ) |  |
     degre ( Q ( X1, … ., Xn − 1, α )) = degreXn ( Q ( X1, … ., Xn )) |  |

   - Calculer le pgcd G ( X1, … ., Xn − 1 ) en n − 1 variables de P ( X1, … ., Xn − 1, α ) et Q ( X1, … ., Xn − 1, α ).
   - Si degre ( G )i < δi pour un indice au moins. Si degre ( G ) ⩽ δ, on pose δ = degre ( G ), D′ = G Δ ( α )/lcoeff ( G ), I = Xn − α, e = 1 et E = [ α ], sinon on pose δ = min( δ, degre ( G )), D′ = 0, I = 1, e = 0, E = [ ]. On passe à l’itération suivante.
   - Si degre ( G ) > δ, on passe à l’itération suivante.
   - Si degre ( G ) = δ, on interpole:
     - G := G Δ ( α )/lcoeff ( G )
     - D′ := D′ + I ( Xn )/∏αj ∈ E ( α − αj ) ( G − D′ ( X1, … ., Xn − 1, α ))
     - I := I ∗ ( Xn − α )
     - e := e + 1 et ajouter α à E
     - Si e est strictement plus grand que le minimum des degrés partiels de P et Q par rapport à Xn, on pose D la partie primitive de D′ (vu comme polynôme à coefficients dans ℤ [ Xn ]), on teste si P et Q sont divisibles par D, si c’est le cas, on renvoie D = C ( Xn ) D

On observe que dans cet algorithme, on fait le test de divisibilite de D par P et Q. En effet, même après avoir évalué en suffisamment de points, rien n’indique que tous ces points sont des points de bonne évaluation. En pratique cela reste extrêmement improbable. En pratique, on teste la divisibilité plus tôt, dès que D′ n’est pas modifié par l’ajout d’un nouveau point à la liste des αj.

Il existe une variation de cet algorithme, appelé SPMOD (sparse modular), qui suppose que seuls les coefficients non nuls du pgcd en n − 1 variables sont encore non nuls en n variables (ce qui a de fortes chances d’être le cas). L’étape d’interpolation est alors remplacée par la résolution d’un sous-système d’un système de Vandermonde. Cette variation est intéressante si le nombre de coefficients non nuls en n − 1 variables est petit devant le degré. Si elle échoue, on revient à l’interpolation dense.

Notons enfin qu’on peut appliquer cette méthode lorsque les coefficients de P et Q sont dans ℤ / n ℤ mais il faut alors vérifier qu’on dispose de suffisamment de points d’interpolation. Ce qui en combinant avec l’algorithme modulaire à une variable donne un algorithme doublement modulaire pour calculer le pgcd de 2 polynômes à coefficients entiers. C’est cette méthode qu’utilise par exemple MuPAD (en essayant d’abord SPMOD puis l’interpolation dense).

Exemple:

Dans cet exemple, on donne F et G sous forme factorisée, le but étant de faire comprendre l’algorithme. En utilisation normale, on n’exécuterait cet algorithme que si F et G étaient développés.

P = (( x + 1 ) y + x2 + 1 ) ( y2 + x y + 1 ), Q = (( x + 1 ) y + x2 + 1 ) ( y2 − x y − 1 ).

Prenons x comme variable X1 et y comme variable X2. Les coefficients dominants de P et Q sont respectivement y et − y donc Δ = y.

En y = 0, P ( x, 0 ) = x2 + 1 n’est pas du bon degré.

En y = 1, P ( x, 1 ) = ( x + x2 + 2 ) ( x + 2 ) et Q ( x, 1 ) = ( x + x2 + 2 ) ( − x ) sont du bon degré. Leur pgcd est G = x2 + x + 2, Δ ( 1 ) = 1, donc D′ = x2 + x + 1. On teste la divisibilité de P par D′, le teste échoue.

En y = 2, P ( x, 2 ) = ( x2 + 2 x + 3 ) ( 2 x + 5 ) et Q ( x, 2 ) = ( x2 + 2 x + 3 ) ( − 2 x + 3 ) donc G = x2 + 2 x + 3, Δ ( 2 ) = 2. On interpole:

D′ = x2 + x + 2 +

y − 1
2 − 1

( 2 ( x2 + 2 x + 3 ) − ( x2 + x + 2 )) = y ( x2 + 3 x + 4 ) − ( 2 x + 2 )

On teste la divisibilité de P par D′, le test échoue.

En y = 3, P ( x, 3 ) = ( x2 + 3 x + 4 ) ( 3 x + 10 ) et Q ( x, 3 ) = ( x2 + 3 x + 4 ) ( − 3 x + 8 ) donc G = x2 + 3 x + 4, Δ ( 3 ) = 3. On interpole:

D′ | = | y ( x2 + 3 x + 4 ) − ( 2 x + 2 ) +

( y − 2 ) ( y − 1 )
( 3 − 2 ) ( 3 − 1 )

⎛
⎝

3 ( x2 + 3 x + 4 ) − ( 3 ( x2 + 3 x + 4 ) − ( 2 x + 2 ))

⎞
⎠

donc

D′ = y ( x2 + 3 x + 4 ) − ( 2 x + 2 ) +

( y − 2 ) ( y − 1 )
2

( − 2 x − 2 ) = x2 y + x y2 + y2 + y

On divise D′ par son contenu et on trouve x2 + x y + y + 1 qui est bien le pgcd de P et Q.

#### 3.3.3 EZGCD.

Il s’agit d’une méthode p-adique. On évalue toutes les variables sauf une, on calcule le pgcd en une variable et on remonte au pgcd variable par variable (EEZGCD) ou toutes les variables simultanément (EZGCD) par un lemme de Hensel. Il semble qu’il est plus efficace de remonter les variables séparément.

Soit donc F et G deux polynômes primitifs dépendant des variables X1, …, Xn de pgcd D, on fixe une des variables qu’on appelera X1 dans la suite. Soient lcoeff ( F ) et lcoeff ( G ) les coefficients dominants de F et G par rapport à X1. On évalue F et G en un n − 1 uplet b tel que le degré de F et G par rapport à X1 soit conservé après evaluation en b. On suppose que Db ( X1 ) = pgcd ( F ( b ), G ( b )) a le même degré que D ( b ). On a donc l’égalité:

( F ∗ lcoeff ( F )) ( b ) =

⎛
⎜
⎜
⎝

Db

lcoeff ( F ( b ))
lcoeff ( Db )

⎞
⎟
⎟
⎠

∗

⎛
⎜
⎜
⎜
⎜
⎜
⎝

F ( b )
Db

lcoeff ( F ) ( b )

lcoeff (

F ( b )
Db

)

⎞
⎟
⎟
⎟
⎟
⎟
⎠

et de même en remplaçant F par G.

Pour pouvoir lifter cette égalité (c’est-à-dire généraliser à plusieurs variables), il faut que Db et F ( b )/Db soient premiers entre eux. Sinon, on peut essayer de lifter l’égalité analogue avec G. En général, on montre qu’il existe un entier j tel que Db et F ( b ) + j G ( b )/Db soient premiers entre eux. En effet, sinon au moins un des facteurs irréductibles de Db va diviser F ( b ) + j G ( b )/Db pour deux valeurs distinctes de j et va donc diviser à la fois F ( b )/Db et G ( b )/Db en contradiction avec la définition de Db = pgcd ( F ( b ), G ( b )). On lifte alors l’égalité obtenue en remplaçant F par ( F + k G ) ci-dessus. Dans la suite, on suppose qu’on peut prendre j = 0 pour alléger les notations.

On va aussi supposer que b = 0. Sinon, on fait un changement d’origine sur les polynômes F et G pour que b = 0 convienne, on calcule le pgcd et on lui applique la translation d’origine opposée.

On adopte ensuite la notation suivante: si k est un entier, on dit qu’un polynôme P est un O ( k ) si la valuation de P vu comme polynôme en X2, … ., Xn à coefficients dans ℤ [ X1 ] est supérieure ou égale à k, ou de manière équivalente si

P ( X1, h X2, … ., h Xn ) = Oh → 0 ( hk )

L’égalité à lifter se réécrit donc:

F lcoeff ( F ) = P0 Q0 + O ( 1 )

où P0 =Db lcoeff ( F ( b ))/lcoeff ( Db ) et Q0 = F ( b )/Db lcoeff ( F ) ( b )/lcoeff ( F ( b )/Db ) sont premiers entre eux et de degré 0 par rapport aux variables X2, … ., Xn. Cherchons P1 = O ( 1 ) et Q1 = O ( 1 ) de degré 1 par rapport aux variables X2, … ., Xn tels que

F lcoeff ( F ) = ( P0 + P1 ) ( Q0 + Q1 ) + O ( 2 )

Il faut donc résoudre

F lcoeff ( F ) − P0 Q0 = P0 Q1 + Q0 P1 + O ( 2 )

On peut alors appliquer l’identité de Bézout qui permet de déterminer des polynômes P1 et Q1 satisfaisant l’égalité ci-dessus (avec comme reste O ( 2 ) nul) puisque P0 et Q0 sont premiers entre eux. De plus, on choisit P1 et Q1 tels que degreX1 P1 ⩽ degreX1 ( F ) − degre ( Q0 ) = degre ( P0 ) et degreX1 ( Q1 ) ⩽ degre ( Q0 ) et lcoeffX1 ( P0 + P1 ) + O ( 2 ) = lcoeffX1 ( Q0 + Q1 ) + O ( 2 ) = lcoeffX1 ( F ). On tronque ensuite P1 et Q1 en ne conservant que les termes de degré 1 par rapport à X2, … ., Xn.

On trouve de la même manière par récurrence Pk et Qk homogènes de degré k par rapport à X2, … ., Xk, de degré par rapport à X1 respectivement inférieur aux degrés de Q0 et de P0 et tels que

F lcoeff ( F ) = ( P0 + … . + Pk ) ( Q0 + … . + Qk ) + O ( k + 1 ) (6)

et lcoeff ( F ) = lcoeffX1 ( P0 + … . + Pk ) + O ( k + 1 ) = lcoeffX1 ( Q0 + … . + Qk ) + O ( k + 1 ).

Si on est bien en un point de bonne évaluation et si k est plus grand que le degré total (par rapport aux variables X2, … ., Xn) du polynôme F lcoeff ( F ) on va vérifier que P0 + … . + Pk = D lcoeff ( F )/lcoeff ( D ). En effet, si on a deux suites de polynômes P et P′ et Q et Q′ satisfaisant (6) avec les même termes de degré zéro P0 et Q0, alors en prenant la différence, on obtient:

( P0 + P1 … + Pk ) ( Q0 + Q1 … + Qk ) = ( P0 + P1′ … + Pk′ ) ( Q0 + Q1′ … + Qk′ ) + O ( k + 1 )

On égale alors les termes homogènes de degré j, pour j = 1, on obtient P0 ( Q1 − Q1′ ) = Q0 ( P1 − P1′ ), donc Q0 divise Q1 − Q1′ qui est de degré strictement inférieur au degré de Q0 par rapport à X1 (car on a l’inégalité large et les termes de plus haut degré sont égaux), donc Q1 = Q1′ et P1 = P1′. On montre de la même manière que Qj = Qj′ et Pj = Pj′. L’écriture est donc unique, c’est donc l’écriture en polynôme homogène de degré croissant de D lcoeff ( F )/lcoeff ( D ) que l’on reconstruit.

Cet algorithme permet donc de reconstruire D, il suffit de tester à chaque étape si P0 + … . + Pk divise F lcoeff ( F ). On appelle cette méthode de remontée lemme de Hensel linéaire. Il existe une variante dite lemme de Hensel quadratique qui consiste à passer de O ( k ) à O ( 2 k ). Elle nécessite toutefois un calcul supplémentaire, celui de l’identité de Bézout à O ( 2 k ) près pour les polynômes P0 + … . + Pk − 1 et Q0 + … . + Qk − 1. Ce calcul se fait également par lifting.

Algorithme EZGCD (Hensel linéaire)

Arguments: 2 polynômes F et G à coefficients entiers et primitifs. Renvoie le pgcd de F et G ou false.

1. Evaluer F et G en ( X2, … ., Xn ) = ( 0, … ., 0 ), vérifier que les coefficients dominants de F et de G ne s’annulent pas. Calculer le pgcd Db de F ( 0 ) et de G ( 0 ). Prendre un autre point d’évaluation au hasard qui n’annule pas les coefficients dominants de F et de G et vérifier que le pgcd a le même degré que Db. Sinon, renvoyer false (on peut aussi faire une translation d’origine de F et de G en un autre point mais cela diminue l’efficacité de l’algorithme).
2. On note lcF et lcG les coefficients dominants de F et de G par rapport à X1.
3. Si degre ( F ) ⩽ degre ( G ) et degre ( Db ) = degre ( G ) et F divise G renvoyer F
4. Si degre ( G ) < degre ( F ) et degre ( Db ) = degre ( F ) et G divise F renvoyer G
5. Si degre ( F ) = degre ( Db ) ou si degre ( G ) = degre ( Db ) renvoyer false
6. Boucle infinie sur j entier initialisé à 0, incrémenté de 1 à chaque itération: si pgcd ( Db, F ( 0 ) + j G ( 0 )/Db ) = C constant, alors arrêter la boucle
7. Lifter l’égalité ( F + j G ) ( lcF + j lcG ) ( 0 ) = ( Db ( lcF + j lcG ) ( 0 )/lcoeff ( Db ) ) ∗ … . par remontée de Hensel linéaire ou quadratique. Si le résultat est false, renvoyer false. Sinon renvoyer le premier polynôme du résultat divisé par son contenu vu comme polynôme en X1 à coefficients dans ℤ [ X2, … ., Xn ].

Remontée de Hensel linéaire:

Arguments: F un polynôme, lcF=lcoeff(F) son coefficient dominant, P0 un facteur de F ( 0 ) ayant comme coefficient dominant lcF ( 0 ) et dont le cofacteur Q0 est premier avec P0.

Renvoie deux polynômes P et Q tels que F lcF = P Q et P ( 0 ) = P0 et lcoeff ( P ) = lcoeff ( Q ) = lcF.

1. Soit G = F lcF, , Q0 = G ( 0 ) / P0, P = P0, Q = Q0.
2. Déterminer les deux polynômes U et V de l’identité de Bézout (tels que P0 U + Q0 V = d où d est un entier).
3. Boucle infinie avec un compteur k initialisé à 1, incrémenté de 1 à chaque itération
   - Si k > degreX2, … ., Xn ( G ), renvoyer false.
   - Si P divise G, renvoyer P et G / P.
   - Soit H = G − P Q = O ( k ). Soit u = U H/d et v = V H/d, on a P0 u + Q0 v = H
   - Remplacer v par le reste de la division euclidienne de v par P0 et u par le reste de la division euclidienne de u par Q0. La somme des deux quotients est égale au quotient euclidien de H par P0 Q0, c’est-à-dire au coefficient dominant de H divisé par le produit des coefficients dominants de P0 et Q0 (qui sont égaux) donc on a l’égalité:

     P0 u + Q0 v = H −

     lcoeff ( H )
     lcoeff ( P0 )2

     P0 Q0

   - Soit α = ( lcoeff ( F ) − lcoeff ( P )) / lcoeff ( P0 ) et β = ( lcoeff ( F ) − lcoeff ( Q )) / lcoeff ( P0 ). On ajoute α P0 à v, ainsi lcoeff ( P + v ) = lcoeff ( F ) + O ( k + 1 ) et β Q0 à u, ainsi lcoeff ( Q + u ) = lcoeff ( F ) + O ( k + 1 )

     Remarque: on montre alors que α + β = lcoeff ( H )/lcoeff ( P0 Q0 ) + O ( k + 1 ) donc P0 u + Q0 v = H + O ( k + 1 ) en utilisant les propriétés :

     lcoeff ( F ) = lcoeff ( P ) + O ( k ) = lcoeff ( Q ) + O ( k ) = lcoeff ( P0 ) + O ( 1 )

   - Réduire u et v en éliminant les termes de degré strictement supérieur à k par rapport à X2, … ., Xn. S’il reste un coefficient non entier, renvoyer false
   - Remplacer P par P + v et Q par Q + u, passer à l’itération suivante.

Exemple:

F = (( x + 1 ) y + x2 + 1 ) ( y2 + x y + 1 ), G = (( x + 1 ) y + x2 + 1 ) ( y2 − x y − 1 )

On a F ( 0, y ) = ( y + 1 ) ( y2 + 1 ) et G ( 0, y ) = ( y + 1 ) ( y2 − 1 ), le pgcd est donc Db = ( y + 1 ). On remarque que Db est premier avec le cofacteur de F mais pas avec le cofacteur de G. Si on évalue en un autre point, par exemple x = 1, on trouve un pgcd D1 de même degré, donc 0 est vraissemblablement un bon point d’évaluation (ici on en est sûr puisque le pgcd de F et G se calcule à vue...). On a lcoeff ( F ) = x + 1, on va donc lifter G = (( x + 1 ) y + x2 + 1 ) ( y2 + x y + 1 ) ( x + 1 ) = P Q où P0 = ( y + 1 ) et Q0 = ( y2 + 1 ).

On calcule les polynômes de l’identité de Bézout U = ( 1 − y ) et V = 1 avec d = 2, puis à l’ordre k = 1:

H = G − P0 Q0 = ( 2 y3 + 2 y2 + 3 y + 1 ) x + O ( 2 )

donc u = reste ( U H / d, Q0 ) = x y et v = reste ( V H / d, P0 ) = − x.

Donc Q1 = x y + α Q0 avec α = ( x + 1 − 1 ) / lcoeff ( P0 ) = x et Q0 + Q1 = ( y2 + 1 ) ( x + 1 ) + x y. De même, P1 = − x + β P0, avec β = ( x + 1 − 1 ) / lcoeff ( P0 ) = x donc P0 + P1 = ( y + 1 ) ( x + 1 ) − x. On remarque que P0 + P1 et Q0 + Q1 sont bien à O ( 2 ) près les facteurs de F lcoeff ( F ):

P = ( x + 1 ) y + x2 + 1 = P0 + P1 + O ( 2 ), Q = ( x + 1 ) ( y2 + x y + 1 ) = Q0 + Q1 + O ( 2 )

Une deuxième itération est nécessaire. On calcule

H = G − ( P0 + P1 ) ( Q0 + Q1 ) = ( 2 y2 + y + 1 ) x2 + O ( 3 )

puis reste ( U H / d, Q0 ) = y x2 et reste ( V H / d, P0 ) = x2. Ici les coefficients α et β sont nuls car lcoeff ( F ) n’a pas de partie homogène de degré 2. On trouve alors P = P0 + P1 + P2 et Q = Q0 + Q1 + Q2. Pour calculer le pgcd, il suffit de calculer la partie primitive de P vu comme polynôme en y, ici c’est encore P car le contenu de P est 1 (remarque: pour Q le contenu est x + 1).
On trouve donc P comme pgcd.

### 3.4 Quel algorithme choisir?

Il est toujours judicieux de faire une évaluation en quelques n − 1 uplets pour traquer les pgcd triviaux. (E)EZGCD sera efficace si (0,...,0) est un point de bonne évaluation et si le nombre de remontées nécessaires pour le lemme de Hensel est petit donc pour les pgcd de petit degré, GCDMOD est aussi efficace si le degré du pgcd est petit. Le sous-résultant est efficace pour les pgcd de grand degré car il y a alors peu de divisions euclidiennes à effectuer et les coefficients n’ont pas trop le temps de croitre. SPMOD est intéressant pour les polynômes creux de pgcd non trivial creux. GCDHEU est intéressant pour les problèmes relativement petits.

Avec des machines multiprocesseurs, on a probablement intérêt à lancer en parallèle plusieurs algorithmes et à s’arrêter dès que l’un deux recontre le succès.

### 3.5 Pour en savoir plus.

Parmi les références citées dans le premier article, ce sont les livres de Knuth, H. Cohen, et Davenport-Siret-Tournier qui traitent des algorithmes de pgcd. On peut bien sûr consulter le source de son système de calcul formel lorsqu’il est disponible :

- pour MuPAD sur un système Unix, depuis le répertoire d’installation de MuPAD (en général `/usr/local/MuPAD`) après avoir désarchivé le fichier `lib.tar` du répertoire `share/lib` par la commande
  `cd share/lib && tar xvf lib.tar`
  on trouve les algorithmes de calcul de PGCD dans le répertoire
  `share/lib/lib/POLYLIB/GCD`
- Pour l’algorithme EZGCD, je me suis inspiré de l’implémentation de Singular (logiciel libre disponible à `www.singular.uni-kl.de`)

Sur le web on trouve quelques articles en lignes sur le sujet en cherchant les mots clefs GCDHEU, EZGCD, SPMOD sur un moteur de recherche, il y a par exemple une description un peu différente du pgcd heuristique sur:
`www.inf.ethz.ch/personal/gonnet/CAII/HeuristicAlgorithms/node1.html`
et un article de comparaison de ces algorithmes par Fateman et Liao (dont la référence bibliographique est Evaluation of the heuristic polynomial GCD. in: ISSAC pages 240–247, 1995). Quelques autres références :

- K.O.Geddes et al "Alg. for Computer Algebra", Kluwer 1992.
- pour GCDHEU Char, Geddes, Gonnet, Gcdheu: Heuristic polynomial gcd algorithm based on integer gcd computation, in: Journal of Symbolic Computation, 7:31–48, 1989.
- pour SPMOD "Probabilistic Algorithms for Sparse Polynomials", in: Symbolic & Algebraic Comp. (Ed E.W.Ng), Springer 1979, pp216,

## 4 Le résultant

Il s’agit d’un point de vue d’algèbre linéaire sur le PGCD. Considérons deux polynômes A et B de degrés p et q et de pgcd D et l’identité de Bézout correspondante :

A U + B V =D (7)

avec degré(U)<q et degré(V)<p. Imaginons qu’on cherche U et V en oubliant qu’il s’agit d’une identité de Bézout, en considérant simplement qu’il s’agit d’un problème d’algèbre linéaire de p+q équations (obtenues en développant et en identifiant chaque puissance de X de 0 à p+q−1) à p+q inconnues (les p coefficients de V et les q coefficients de U) On sait que A et B sont premiers entre eux si et seulement si ce problème d’algèbre linéaire a une solution pour D=1. Donc si le déterminant du système est non nul, alors A et B sont premiers entre eux. Réciproquement si A et B sont premiers entre eux, le système a une solution unique non seulement avec comme second membre 1 mais avec n’importe quel polynôme de degré inférieur p+q, donc le déterminant du système est non nul.

Définition:
On appelle résultant de A et B le déterminant de ce système (7). Il s’annule si et seulement si A et B ne sont pas premiers entre eux (ont au moins une racine commune). On appelle matrice de Sylvester la transposée de la matrice du système (les inconnues étant par ordre décroissant les coefficients de U et V)

M(A,B)=

⎛
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎝

aa | aa−1 | … | … | a0 | 0 | … | 0
0 | aa | … | … | a1 | a0 | … | 0
⋮ |  |  |  |  |  |  | ⋮
0 | 0 | … |  |  |  |  | a0
bb | bb−1 | … | b0 | 0 | 0 | … | 0
⋮ |  |  |  |  |  |  | ⋮
0 | 0 | … |  |  |  |  | b0

⎞
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎠

(cette matrice contient b=degré(B) lignes de coefficients du polynôme A et a=degré(A) lignes de coefficients du polynôme B)

Lien avec l’algorithme du sous-résultant (calcul de PGCD)
On peut calculer le déterminant avec la suite des restes de divisions euclidiennes de la manière suivante, on part de la pseudo-division de A par B :

bba−b+1 A=BQ+R

on effectue alors sur chaque ligne contenant les coefficients de A la manipulation de ligne correspondante, c’est-à-dire multiplier la ligne par bba−b+1 et soustraire (q0 fois la ligne de B terminant dans la même colonne+q1 fois la ligne de B terminant une colonne avant+...). Toutes les lignes contenant les coefficients de A ont été remplacées par des lignes contenant les coefficients de R. Ces lignes contiennent k zéros initiaux avec k ≥ 1, ce qui permet de réduire le déterminant à celui de la matrice de Sylvester de R et B (à un coefficient multiplicatif près qui vaut bbk par rapport au précédent donc bbk−b(a−b+1) par rapport au déterminant de départ). On échange ensuite R et B ce qui change éventuellement le signe et on continue en faisant les divisions euclidiennes de l’algorithme du sous-résultant (cf. Knuth où on utilise la matrice de Sylvester pour prouver que l’algorithme du sous-résultant est correct). Rappelons que le sous-résultant définit les suites Ak (A0=A, A1=B), dk le degré de Ak, δk=dk−dk+1, gk (g0=1, si k≠ 0, gk coefficient dominant de Ak) hk (h0=1, hk+1=hk1−δk gk+1δk) et

gkδk−1+1 Ak−1 = Ak Qk+1 + gk−1 hk−1δk−1 Ak+1

Théorème 3 Le résultant est égal au signe près au coefficient hk où k correspond au reste Ak constant (en supposant que le résultant soit non nul).

Preuve
La transcription de l’égalité précédente sur les résultants donne par la méthode ci-dessus :

gk(δk−1+1)dkRes(Ak−1,Ak) | = | gkdk−1−dk+1 Res(gk−1 hk−1δk−1 Ak+1,Ak)
| = | gkdk−1−dk+1 (gk−1 hk−1δk−1)dk Res(Ak+1,Ak)

On en déduit que :

Res(Ak−1,Ak)
gk−1dk hk−1dk−1−1

= gkdk−1−dk+1−(δk−1+1)dk hk−1δk−1dk+1−dk−1 Res(Ak+1,Ak)

On observe que :

hk−1δk−1dk+1−dk−1 =hk−1(δk−1−1)(dk−1) =

⎛
⎝

hk−1δk−1−1

⎞
⎠

dk−1 =

⎛
⎜
⎜
⎝

gkδk−1
hk

⎞
⎟
⎟
⎠

dk−1

donc :

Res(Ak−1,Ak)
gk−1dk hk−1dk−1−1

=

gkdk−1−dk+1−(δk−1+1)dk

⎛
⎜
⎜
⎝

gkδk−1
hk

⎞
⎟
⎟
⎠

dk−1

Res(Ak+1,Ak)

=

gkdk−1−dk+1−dk−δk−1

⎛
⎜
⎜
⎝

1
hk

⎞
⎟
⎟
⎠

dk−1

Res(Ak+1,Ak)

=

Res(Ak+1,Ak)
gkdk+1 hkdk−1

Donc en valeur absolue

|

Res(A0,A1)
g0d1 h0d0−1

| = |

Res(Ak−1,Ak)
gk−1dk hk−1dk−1−1

|

En prenant le rang k tel que Ak est constant, on a dk=0 et le résultant est égal à gkdk−1, on obtient donc :

|Res(A0,A1)|=|

gkdk−1
hk−1dk−1−1

|

Comme ici δk−1=dk−1, le terme de droite est |hk|.

Remarque
On peut calculer au fur et à mesure le signe du résultant en tenant compte des degrés de Ak pour inverser l’ordre de Ak−1 et Ak dans le résultant.

Utilisation
La valeur du résultant est très utile pour savoir si 2 polynômes dépendant de paramètres sont premiers entre eux en fonction de la valeur des paramètres. En effet, la fonction `gcd` d’un logiciel de calcul formel calculera le PGCD par rapport à toutes les variables en incluant les paramètres. En cherchant quand le résultant s’annule en fonction des paramètres on obtient un autre type d’information.

Exemple :
Chercher quand le polynône P=x3+px+q possède une racine multiple en fonction de p et q. On calcule le résultant de P et P′ et on trouve 4p3+27q2, donc P a une racine multiple si et seulement si 4p3+27q2=0.

Remarque :
Comme le coefficient dominant de P′ est un multiple du coefficient dominant de P, le résultant de P et P′ est divisible par le coefficient dominant de P, on appelle le quotient discriminant.

## 5 Localisation des racines : les suites de Sturm.

L’algorithme du sous-résultant appliqué à un polynôme sans racine multiple P et à sa dérivée permet, à condition de changer les signes dans la suite des restes, de connaitre le nombre de racines réelles d’un polynôme à coefficients réels dans un intervalle. Ceci est trè utile pour par exemple simplifier des valeurs absolues de polynômes dans un intervalle.

On définit donc la suite de polynômes A0=P, A1=P′, ..., Ak,0 par :

Ai = Ai+1 Qi+2 − Ai+2 (8)

avec Ak, le dernier reste non nul, un polynôme constant puisque P n’a pas de racine multiple. On utilise plutot l’algorithme du sous-résultant que l’algorithme d’Euclide, il faut alors s’assurer que les signes de Ai et Ai+2 sont opposés lorsque Ai+1 s’annule quitte à changer le signe de Ai+2 en fonction du signe du coefficient dominant de Ai+1, de la parité de la différence des degrés et du signe du coefficient gh1−δ.

On définit s(a) comme étant le nombre de changements de signes de la suite Ai(a) en ignorant les 0. On a alors le

Théorème 4 Le nombre de racines réelles de A0=P sur l’intervalle ]a,b] est égal à s(a)−s(b).

Preuve
Par continuité de la suite des polynômes, s ne peut varier que si l’un des polynômes s’annule. On considére la suite des signes en un point : elle ne peut contenir deux 0 successifs (sinon toute la suite vaudrait 0 en ce point en appliquant (8), or Ak est constant non nul). Elle ne peut pas non plus contenir +,0,+ ni -,0,- à cause de la convention de signe sur les restes de (8). Donc une racine b de Ai pour 0<i<k, n’influe pas sur la valeur de s au voisinage de b (il y a toujours un changement de signe entre les positions i−1 et i+1). Comme Ak est constant, seules les racines de A0=P sont susceptibles de faire varier s. Comme A1=P′, le sens de variations de A0 au voisinage d’une racine de A0 est déterminé par le signe de A1, donc les possibilités sont -,+ vers +,+ ou +,- vers -,-, ce qui diminue s d’une unité.

Remarques

- On peut localiser les racines réelles par dichotomie : on sait que toutes les racines sont situées dans l’intervalle [−C,C] avec C=|P|∞/|lcoeff(P)|. On coupe l’intervalle en deux, on calcule le nombre de racines dans chaque partie, et on continue en conservant uniquement les intervalles contenant au moins une racine. Lorsqu’un intervalle contient une seule racine, on passe à la dichotomie classique (changement de signe), ou à la méthode de Newton (avec évaluation exacte du polymôme et arrondi du dénominateur à une puissance de 2). C’est ce qui est utilisé par l’instruction `realroot` de Giac.
- Il existe un autre algorithme de localisation de racines réelles dû à Vincent, Collins et Akritas. Un étudiant d’Akritas travaille sur une implémentation C++ de cet algorithme dans Giac.
- Ces suites se générallisent dans le plan complexe, on peut déterminer le nombre de racines contenues dans un rectangle du plan complexe (cf. par exemple l’article de Mickael Eiserman sur `www-fourier.ujf-grenoble.fr/~eiserm`). Malheureusement, il faut calculer une nouvelle suite de Sturm pour chaque rectangle (alors que dans ℝ on peut réutiliser la même suite de Sturm). Ce qui est donc beaucoup plus couteux, en pratique on ne peut guère aller au-delà du degré 10 avec l’instruction `complexroot` de Giac, analogue de `realroot`.
- Une autre méthode dans le cas complexe, peut-être plus prometteuse, consisterait à utiliser un hybride numérique-exact. Les racines d’un polynôme sont aussi les valeurs propres complexes de sa matrice companion M. On peut alors par une méthode itérative (on pose A0=M, puis on factorise An=QR par la méthode de Hessenberg et on définit An+1=RQ), factoriser cette matrice sous forme de Schur: M=P−1 S P où P est unitaire et S diagonale supérieure aux erreurs d’arrondis près. En approchant P par une matrice exacte P′, on peut essayer de controler la localisation des valeurs propres de M à partir des coefficients diagonaux de S et de la taille des coefficients sous-diagonaux de P′ M P′−1.

## 6 Exercices (PGCD, résultant, ...)

### 6.1 Instructions

Les instructions arithmétiques sont en général dans la librairie standard. Elles sont dans les menus Cmds->Integer et Cmds->Polynomes de `Xcas`. Certaines de ces instructions sont dans la librairie `numtheory` (en maple) ou `numlib` (en MuPAD) (utilisez `?numtheory` ou `?numlib` pour avoir la liste des fonctions de ces librairies), pour éviter de taper `numlib::` ou `numtheory::` à chaque fois, on peut lancer en maple la commande `with(numtheory);` ou en MuPAD `export(numlib);`.

#### 6.1.1 Entiers

- `chrem` (en MuPAD `numlib::ichrem`) : restes chinois (entier)
- `divisors` (en maple `numtheory::divisors`, en MuPAD `numlib::divisors`) : liste des diviseurs d’un entier
- `gcd, lcm` : PGCD et PPCM
- `igcdex`: Bézout pour des entiers
- `iquo` et `irem` quotient et reste de la division euclidienne de deux entiers
- `isprime` test de primalité. En maple et MuPAD, il s’agit d’un test de pseudo-primalité. En Xcas, utiliser `is_pseudoprime` pour effectuer un test plus rapide de pseudo-primalité.
- `mods`: reste euclidien symétrique
- `nextprime` et `prevprime` (en MuPAD `numlib::prevprime`): nombre premier suivant ou précédent
- `powmod(a,b,n)` (Xcas), `a &^ b mod n` (Maple), `powermod(a,b,n)` (Mupad): calcul de ab (mod n ) par l’algorithme de la puissance rapide

#### 6.1.2 Polynômes

On peut représenter les polynômes par leur écriture symbolique (par exemple `x^2+1`), ou par des listes (représentation dense ou creuse, récursive ou distribuée). Xcas, Maple et MuPAD acceptent la représentation symbolique. Xcas propose deux types de représentation, dense à une variable (`poly1[ ]`), ou distribuée (`%%%{ }%%%`) et des instructions de conversion (`poly2symb` et `symb2poly`) entre représentations. MuPAD propose également une représentation non symbolique, cf. la documentation `?poly`. L’intérêt d’une représentation non symbolique est l’efficacité des opérations polynomiales, (et la possibilité de chronométrer des opérations comme le produit de 2 polynômes).

Les instructions qui suivent utilisent la représentation symbolique, certaines acceptent les autres représentations.

- `coeff` coefficient(s) d’un polynôme,
- `coeffs` liste des coefficients d’un polynôme (à développer auparavant, en mupad on utilise `coeff`)
- `content` contenu (pgcd des coefficients)
- `degree` degré
- `divide` division euclidienne,
- `gcd, lcm` PGCD et PPCM
- `gcdex` Bézout,
- `genpoly` (en MuPAD `numlib::genpoly`): crée un polynôme à partir de la représentation z-adique d’un entier (utile pour le PGCD heuristique)
- `icontent`: contenu entier pour un polynôme à plusieurs variables
- `indets`: liste des noms de variables d’une expression
- `lcoeff`: coefficient dominant d’un polynôme
- `ldegree`: valuation
- (MuPAD) `multcoeffs` multiplie les coefficients d’un polynôme
- (MuPAD) `pdivide` pseudo-division
- (MuPAD) `poly(expr,[var],coeff)` crée un polynôme à partir de l’expression symbolique `expr` par rapport une variable ou à une liste de variables `var`, on peut indiquer dans quel anneau vivent les coefficients (par exemple dans ℤ/13ℤ avec comme 3ème argument `IntMod(13)`)
- `primpart`: partie primitive d’un polynôme
- `quo`, `rem` (xcas et Maple) quotient et reste euclidien (en MuPAD utiliser les options Quo et Rem de `divide`)
- `tcoeff`: coefficient de plus bas degré d’un polynôme
- `interp` (MuPAD `interpolate`) : interpolation de Lagrange
- `convert(.,sqrfree)` (MuPAD `polylib::sqrfree`) : décomposition en facteurs n’ayant pas de racine multiples
- `convert(.,parfrac)` (MuPAD `polylib::partfrac`) : décomposition en éléments simples
- `resultant` (MuPAD `polylib::resultant`) : calcule le résultant de 2 polynômes par rapport à une variable.

Notez aussi que le menu `Exemples->poly->pgcd.xws` de Xcas contient des exemples de programmes de calcul de pgcd de type Euclide.

#### 6.1.3 Calculs modulo n

Pour travailler dans ℤ/nℤ[X] :

- avec `Xcas` on utilise la notation % comme en C, par exemple `gcd(P % 3, Q % 3)`. On peut aussi utiliser la notation Maple en mode “syntaxe Maple” (cf. ci-dessous)
- avec Maple, on utilise les formes inertes des instructions (qui renvoient l’instruction non évaluée), dont le nom est le même que le nom de commande habituel mais précédé par une majuscule, puis on indique `mod n`, par exemple `Gcd(P,Q) mod 11`.
- avec MuPAD, on désigne le type des coefficients par exemple par `IntMod(13)` puis on construit des objets ayant des coefficients de ce type (par exemple des polynômes, cf. infra). Par exemple `poly(x^2+1,[x],IntMod(13))`.

### 6.2 Exercices PGCD

1. Calculez le pgcd de x202+x101+1 et sa dérivée modulo 3 et modulo 5. Conclusion?
2. P=51x3−35x2+39x−115 et Q=17x4−23x3+34x2+39x−115. Calculez le pgcd de P et Q modulo 5, 7 et 11. En déduire le pgcd de P et Q par le théorème des restes chinois. Pourquoi ne doit-on pas essayer modulo 17?
3. Écrire un programme qui détermine le degré probable du pgcd de 2 polynômes en une variable en utilisant le pgcd modulaire (on considère le degré probable déterminé lorsqu’on trouve deux nombres premiers réalisant le minimum des degrés trouvés)
4. Détaillez l’algorithme du PGCD heuristique pour les polynômes P=(x+1)7−(x−1)6 et sa dérivée. Comparez avec l’algorithme d’Euclide naïf.
5. Écrire un programme mettant en oeuvre le pgcd heuristique pour des polynômes à une variable.
6. On veut comprendre comment un logiciel de calcul formel calcule

   ∫

   x6+2
   (x3+1)2

   dx

   On se ramène d’abord à une fraction propre (numérateur N de degré inférieur au dénominateur), Soit P=X3+1, calculez le PGCD de P et P′, puis deux polynômes U et V tels que:

   N=UP+VP′

   On décompose alors l’intégrale en deux morceaux :

   ∫

   N
   P2

   =

   ∫

   U
   P

   +

   ∫

   V

   P′
   P2

   Faites une intégration par parties sur le deuxième terme et en déduire la valeur de l’intégrale du départ.
7. Écrire un programme mettant en oeuvre l’algorithme modulaire de calcul du PGCD.
8. Écrire un programme qui détermine le degré probable du PGCD par rapport à toutes les variables de 2 polynôme à plusieurs variables en utilisant l’évaluation en toutes les variables sauf une.
9. Calculer le pgcd par une méthode modulaire de (xy−x+1)(xy+x2+1) et (xy−x−y)(xy−x+1)

### 6.3 Exercices (résultant)

1. Pour quelles valeurs de p le polynôme X5+X3−pX+1 admet-il une racine multiple?
2. Résoudre le système en éliminant successivement les variables grâce au résultant :

   ⎧
   ⎪
   ⎨
   ⎪
   ⎩

   a3+b3+c3 | = | 8
   a2+b2+c2 | = | 6
   a+b+2c | = | 4

3. Donner le détail des calculs avec Bézout de la décomposition en éléments simples de :

   1
   (x2−1)2(x+2)

   puis calculer le coefficient de xn du développement en séries entières de cette fraction en 0.
4. Calculer

   ∫

   1−x2
   1+x4

   dx

   en utilisant le résultant pour calculer les logarithmes.
5. En utilisant uniquement l’instruction de calcul de PGCD déterminer la multiplicité maximale d’un facteur irréductible de x14−x13−14x12+12x11+78x10−54x9−224x8+116x7+361x6−129x5−330x4+72x3+160x2−16x−32

### 6.4 Exercice (Bézout modulaire)

Soit A et B deux polynômes à coefficients entiers et premiers entre eux. Soit c ∈ ℤ* le résultant de A et B, on va calculer les polynômes U et V de l’identité de Bézout

A U + B V = c , deg(U)<deg(B), deg(V)<deg(A) (9)

par une méthode modulaire.

1. Montrer, en utilisant les formules de Cramer, que les coefficients de U et V sont des entiers de valeur absolue inférieure ou égale à la borne de Hadamard h de la matrice de Sylvester de A et B (dont le déterminant est c, le résultant de A et B). Calculer h en fonction de la norme euclidienne de A, B et de leurs degrés.
2. On calcule c ∈ ℤ* puis on résoud (9) dans ℤ/pi Z[X] pour plusieurs nombres premiers pi (choisis si possible inférieurs à √231 pour des raisons d’efficacité), puis on calcule par le théorème des restes chinois (9) dans ℤ/∏pi Z[X]. Donner une minoration de ∏i pi faisant intervenir h qui permette de garantir que l’écriture en représentation symétrique de (9) dans ℤ/∏pi Z[X] est identique à (9) dans ℤ[X].
3. Application : résoudre de cette manière l’équation de Bézout pour

   A=(X+1)4(X−3), B=(X−1)4(X+2)

   (vous pouvez utiliser sans justifications l’instruction de calcul de résultant, des coefficients de Bézout dans ℤ/piZ[X] et de reste chinois de votre logiciel).
4. Écrire une fonction mettant en oeuvre cet algorithme.
5. Que pensez-vous de l’intérêt de cet algorithme par rapport à l’algorithme d’Euclide étendu dans ℤ[X]?

### 6.5 Exercice (Géométrie et résultants).

On cherche une relation algébrique entre les coordonnées de 4 points A,B,C,D qui traduise le fait que ces 4 points sont cocycliques. Cette condition étant invariante par translation, on cherche une relation entre les 6 coordonnées des 3 vecteurs v1=(x1,y1), v2=(x2,y2) et v3=(x3,y3) d’origine A et d’extrémité B, C et D. On peut supposer quitte à translater que le centre du cercle est l’origine, on a donc 5 paramètres : le rayon du cercle R et les 4 angles des points sur le cercle θ0, θ1, θ2 et θ3. La relation cherchée va s’obtenir en éliminant les 5 paramètres des expressions des 6 coordonnées en fonction de ces paramètres.

1. Exprimer les 6 coordonnées en fonction de R et a=tan(θ0/2), b=tan(θ1/2), c=tan(θ2/2) et d=tan(θ3/2). On obtient ainsi 6 équations, par exemple les deux premières sont de la forme

   x1− F(R,a,b)= 0, y1− G(R,a,b)= 0

   où F et G sont deux fractions rationnelles.
2. En réduisant au même dénominateur, calculer 6 polynômes, fonction de x1,y1,x2,y2,x3,y3,R,a,b,c,d, qui doivent s’annuler pour que les points soient cocycliques (Vous pouvez utiliser l’instruction `numer` pour obtenir le numérateur d’une fraction rationnelle).
3. Éliminer b des polynômes contenant x1 et y1 et factoriser le polynôme obtenu, faire de même avec c, x2 et y2 et d, x3 et y3, en déduire (en supposant que les points sont tous distincts) 3 polynômes en x1,y1,x2,y2,x3,y3,R,a qui s’annulent.
4. Éliminer R et a, en déduire la relation cherchée.
5. Vérifier que cette relation est équivalente à la nullité de la partie imaginaire du birapport des affixes α, β, γ, δ des 4 points :

   ℑ

   ⎛
   ⎜
   ⎜
   ⎝

   α−β
   α−γ

   δ−γ
   δ−β

   ⎞
   ⎟
   ⎟
   ⎠

   = 0

### 6.6 Décalage entier entre racines.

Soit P un polynôme à coefficients entiers sans racines multiples. On dira que P a la propriété I si deux des racines de P sont décalées d’un entier. En d’autres termes, si r1,...,rn désignent les racines complexes distinctes de P, P possède la propriété I s’il existe au moins un entier parmi les différences ri−rj pour i ≠ j.

1. Soit

   R(t)=resultantx(P(x),P(x+t))

   Montrer que R est à coefficients entiers. Montrer que la propriété I est équivalente à la propriété “R possède une racine entière non nulle”. On va maintenant construire un algorithme déterminant les racines entières du polynôme R.
2. Après division de R par une puissance de t, on peut supposer que R a un coefficient constant non nul. Après division de R par son contenu, on peut aussi supposer que le contenu de R est 1. En effectuant ensuite une factorisation square-free de R, on peut se ramener au cas où R et R′ sont premiers entre eux. Soit a une racine de R.
   1. Donner une majoration de |a| en fonction du coefficient constant de R.
   2. Soit p un nombre premier ne divisant pas le coefficient dominant de R et tel que R et R′ soient premiers entre eux modulo p. On peut calculer a à partir d’une racine de R modulo p en la “remontant” modulo pk pour k assez grand (algorithme p-adique). Pour quelle valeur de k peut-on reconstruire toutes les racines entières de R ?
   3. Comparer l’algorithme ci-dessus avec les algorithmes suivants : la factorisation de R sur ℤ, la recherche numérique des racines complexes de R, la recherche des racines entières de R parmi les diviseurs entiers du coefficient constant de R et leurs opposés.
3. Une fois les racines entières de R connues, comment peut-on en déduire les facteurs de P dont les racines diffèrent de cet(ces) entier(s)?
4. Soit

   P(x)=x6+9x5+29x4+41x3+37 x2+59x+31

   Montrer que P a la propriété I. Calculer la ou les racines entières de R et donner la factorisation correspondante de P.
5. Écrire un programme qui effectue cet algorithme sur un polynôme quelconque. On pourra utiliser la fonction `rationalroot` de Xcas pour déterminer les racines entières de R.
6. Application : on cherche à calculer

   n
   ∑
   k=1

   −9x2−27x−30
   P(x)

   (10)

   Décomposer cette fraction en éléments simples (donner le détail des calculs en utilisant la factorisation précédente et l’identité de Bezout `abcuv` en Xcas).
7. Calculer la somme précédente (10). On pourra remarquer que pour k entier strictement positif, 1/f(x+k)−1/f(x) s’exprime comme une somme de différences 1/f(x+j+1)−1/f(x+j).
8. Écrire un programme effectuant ce calcul avec une fraction quelconque, lorsque cela est possible.

## 7 Factorisation

On présente ici quelques algorithmes utilisés pour factoriser un polynôme à coefficients entiers. Pour un polynôme en une variable, cele se fait en plusieurs étapes : on commence par se ramener à un polynôme P dont tous les facteurs sont de multiplicité un, ensuite on factorise P dans ℤ/pℤ (par la méthode de Berlekamp ou Cantor-Zassenhauss), puis on remonte à ℤ/pk Z pour k suffisamment grand (en fonction de la borne de Landau sur les facteurs de P), et on recombine enfin les facteurs modulaires pour trouver les facteurs de P. Lorsque P à plusieurs variables, on utilise une méthode analogue à celle permettant de trouver le pgcd de polynômes à plusieurs variables.

Rappel
Le pgcd des coefficients d’un polynôme est appelé contenu de ce polynôme. Un polynôme est dit primitif si son contenu est égal à 1.

### 7.1 Les facteurs multiples

Étant donné un polynôme P à coefficients entiers, on cherche à écrire :

P=Πk=1n Pkk

où les Pk n’ont pas de facteurs multiples et sont premiers entre eux deux à deux. Comme on est en caractéristique 0, cela revient à dire que pgcd(Pk,Pk′)=1 et pgcd(Pk,Pj)=1. Bien entendu on va utiliser la dérivée de P dans l’algorithme de recherche des Pk :

P′=

n
∑
k=1

kPk′ Pkk−1 Πj≠ k Pjj

Soit G le pgcd de P et de P′. On a :

G=Πk=1n Pkk−1,

en effet G divise P et P′ :

W1=

P
G

=Πk=1n Pk, Z1=

P′
G

=

n
∑
k=1

kPk′Πj≠ k Pj

il s’agit de vérifier que W1 et Z1 sont premiers entre eux. Soit F un facteur irréductible du pgcd de W1 et Z1, alors F divise l’un des Pk, appelons Pl ce facteur. Comme F divise Πj≠ k Pj si k≠ l, on en déduit que F divise le dernier terme de la somme de Z1, c’est-à-dire que F divise lPl′Πj≠ l Pj donc F divise Pl′ puisque les Pk sont premiers entre eux. Donc Pl et Pl′ ont un facteur en commun, ce qui est contraire aux hypothèses.

On pose alors :

Y1=Z1−W1′=

∑
k>1

(k−1)Pk′ Πj≠ k Pj

On définit alors par récurrence des suites de polynômes Wn, Yn et Gm par :

- Gm=pgcd(Wm,Ym)
- Wm+1=Wm/Gm et Ym+1=Ym/Gm−Wm+1′

On va montrer que Pm=Gm. Commençons au rang n=1, on voit que P1 divise Y1 (puisqu’il est commun à tous les Πj≠ k Pj car k>1) et divise W1. Et c’est le seul facteur commun, car tout autre facteur irréductible serait un diviseur d’un Pl pour l>1, donc diviserait (l−1)Pl′Πj≠ l,j>1 Pj, donc diviserait Pl′. Le raisonnement en un rang quelconque est identique, les polynômes sont donnés par :

Gm=Pm, Wm=Πk>=m Pk, Ym=

∑
k>m

(k−m)Pk′Πj≥ m, j≠ k Pj

Lorsqu’on programme cet algorithme, le test d’arrêt est Gm=1.

Square-free factorisation (Algorithme de Yun)
Argument: un polynôme primitif P à coefficients entiers (ou dans ℤ[i] ou dans un corps de caractéristique nulle).
Valeur renvoyée: une liste de polynômes Pm telle que P=Πk=1n Pkk.

1. Initialiser la liste résultat à liste vide.
2. Initialiser W à P et Y à P′. Calculer le pgcd G de W et Y et simplifier W et Y par leur pgcd puis poser Y=Y−W′.
3. Boucle tant que Y≠ 0.
4. Calculer le pgcd G de W et Y. Ajouter G à la liste résultat.
5. Simplifier W et Y par G, puis poser Y=Y−W′ et passer à l’itération suivante.

Remarque : lorsqu’on veut factoriser un polynôme à coefficients modulaires, il faut aussi se ramener à un polynôme sans facteurs multiples mais on ne peut pas utiliser cet algorithme tel quel car la caractéristique du corps n’est pas nulle.

Exemple :
Factorisation sans facteurs multiples de P(X)=(X3−1)(X+2)2(X2+3)3. En mode interactif avec un logiciel de calcul formel, effectuons l’étape d’initialisation :

    W:=normal((x^3-1)*(x+2)^2*(x^2+3)^3);
    Y:=diff(W,x);
    G:=gcd(W,Y);
            x^5+2*x^4+6*x^3+12*x^2+9*x+18
    W:=normal(W/G);
            x^6+2*x^5+3*x^4+5*x^3+-2*x^2+-3*x-6
    Y:=normal(Y/G);
    Y:=normal(Y-diff(W,x));
            5*x^5+8*x^4+3*x^3+-5*x^2+-8*x-3

On vérifie bien que W=(x+2)*(x3−1)*(x2+3) est le produit des facteurs Pi. On entame maintenant la boucle :

    G:=gcd(W,Y);
            x^3-1   -> P1
    Y:=normal(Y/G);
    W:=normal(W/G);
    Y:=normal(Y-diff(W,x));
            2*x^2+4*x
    G:=gcd(W,Y);
            x+2     -> P2
    Y:=normal(Y/G);
    W:=normal(W/G);
    Y:=normal(Y-diff(W,x));
            0
    G:=gcd(W,Y);
            x^2+3   ->  P3

puis W=1 et Y=0 et le prochain G vaut 1, on a bien trouvé tous les facteurs Pi.

### 7.2 Factorisation en une variable

On suppose maintenant qu’on veut factoriser un polynôme P sans facteur multiple (et primitif). En général on commence par simplifier P par ses facteurs linéaires (détectés avec l’algorithme présenté dans le premier article de cette série). On commence par chercher un nombre premier p tel que P dans ℤ/pℤ conserve le même degré et reste sans facteur multiple (donc pgcd(P,P′)=1 dans ℤ/pℤ), ce qui est toujours possible (il suffit de prendre p plus grand que le plus grand entier apparaissant dans l’algorithme du sous-résultant pour calculer le pgcd de P et P′ dans ℤ).

Convention
Tous les polynômes ayant leurs coefficients dans un corps fini sont supposés avoir comme coefficient dominant 1 lorsque le choix existe (par exemple les facteurs d’un polynôme modulo p).

#### 7.2.1 Factorisation dans ℤ/pℤ[X]

On suppose qu’on a un polynôme P à coefficients dans ℤ/pℤ sans facteur multiple. Il s’agit de factoriser P dans ℤ/pℤ[X]. Il existe essentiellement deux stratégies, l’une commence par factoriser par groupes de facteurs de même degré puis casse les facteurs et l’autre plus directe à base d’algèbre linéaire modulaire (méthode de Berlekamp). Dans les deux cas, on utilise le fait que si F est un polynôme, alors les polynômes à coefficients dans ℤ/pℤ modulo F forment un anneau A qui est aussi un espace vectoriel sur ℤ/pℤ de dimension le degré de F (si F est irréductible, alors A est un corps). On s’intéresse alors aux propriétés de l’application ϕ: x ∈ A ↦ xp. On observe d’abord que cette application est une application linéaire. Cela découle du petit théorème de Fermat pour ϕ(λ x)=λ ϕ(x) et de la formule de Newton et de la primalité de p pour ϕ(x+y)=ϕ(x)+ϕ(y).

Calcul de ϕ
Pour mettre en oeuvre ces algorithmes, on commence par déterminer la matrice de l’endomorphisme ϕ: x ↦ xp dans ℤ/pℤ[X] (mod P(X) ) muni de sa base canonique { 1, X,...,Xdeg(P)−1 }.

#### 7.2.2 Distinct degree factorization

Cette méthode consiste à détecter les groupes de facteurs ayant un degré donné (distinct degree factorization). Si nécessaire, on utilise ensuite un autre algorithme pour casser ces groupes. On utilise ici les propriétés des itérées de l’application linéaire ϕ sur des espaces vectoriels de corps de base ℤ/pℤ. On va déterminer le produit Pk de tous les facteurs de P de degré k en calculant le pgcd de P et de X(pk)−X dans ℤ/pℤ[X].

Pour k=1, Xp−X est le produit des X−k pour tout k∈ ℤ/pℤ par le petit théorème de Fermat (kp=k (mod p )), donc le pgcd de P et de X(p1)−X dans ℤ/pℤ[X] est le produit des facteurs de P de degré 1.

Pour k>1, le raisonnement se généralise de la manière suivante : on considère un facteur irréductible F(X) de P de degré k et le corps K=(ℤ/pℤ)[Y] (mod F(Y) ). Le corps K est un corps fini, c’est aussi un espace vectoriel sur ℤ/pℤ de dimension k, donc K possède pk éléments et K* est un groupe multiplicatif à pk−1 éléments, donc tout élément de K* vérifie l’équation xpk−1=1 donc tout élément de K vérifie x(pk)=x. En particulier pour x=Y (mod F(Y) ) on trouve que Y(pk)=Y (mod F(Y) ) donc F(X) divise X(pk)−X dans ℤ/pℤ.

Réciproquement, si on se donne un facteur irréductible F qui divise Xpk−X, soit K le corps correspondant à F, alors le noyau de l’application linéaire

x ∈ K ↦ xpk−x ∈ K

est K tout entier, car Y=Ypk (mod F ) entraine (Y2)(pk)=Y2 pk=(Ypk)2=Y2 (mod F ) et de même pour les autres puissances de Y qui, avec Y0=1 également dans le noyau, forment une base de l’espace vectoriel K sur ℤ/pℤ. Donc le nombre d’éléments de K est inférieur ou égal au degré du polynôme Xpk−X (puisque X(pk)−X est divisible par X−x pour tout x∈ K), donc le degré de F est inférieur ou égal à k.

Donc Pk est égal au pgcd de P/Πj<k Pj avec Xpk−X.

Algorithme distinct degree factorization
Argument: un polynôme P à coefficients entiers sans facteur multiple et primitif.
Valeur renvoyée: la liste L des produits des facteurs irréductibles et du degré correspondant de P (ordonné par ordre croissant de degré).
On commence par initialiser L à vide et un polynôme auxiliaire Q à X (il contiendra les valeurs de Xpk−X (mod P )), on fait une boucle indéfinie sur k commençant à 1 et incrémenté de 1 à chaque itération

- Si k est strictement plus grand que le degré de P divisé par 2, on rajoute le couple (P,degre(P)) à L et on renvoie L
- On remplace Q par Qp (mod P ) en utilisant le calcul de ϕ modulo P
- On calcule le pgcd G de Q−X et de P.
- Si G vaut 1, on passe à l’itération suivante
- On rajoute le couple (G,k) à la liste L et on remplace P par le quotient de P par G.

Exemple :
Factorisation en degré distincts de (X3+X+1)(X4−X+1) dans ℤ/5ℤ. On regarde d’abord si P reste sans facteur multiple après réduction modulo 5.

    P:=normal((x^3+x+1)*(x^4-x+1) mod 5);
    gcd(P,diff(P,x));
        1 mod 5  -> ok P est sans facteur multiple
    P1:=gcd(P,(x^5-x)mod 5);
        (1 mod 5)*x -2 mod 5  -> P1
    P:=normal(P/P1);
    P2:=gcd(P,(x^(5^2)-x)mod 5);
        1 mod 5  -> pas de facteur de degre 2
    P3:=gcd(P,(x^(5^3)-x)mod 5);
        (x^6+2*x^5+x^2+x+2) mod 5

Donc P admet 3 facteurs dans ℤ/5ℤ: un de degré 1 (x−2) et deux de degré 3 (dont le produit est x6+2x5+x2+x+2).

Le même calcul dans ℤ/7ℤ donne

    P:=normal((x^3+x+1)*(x^4-x+1) mod 7);
    gcd(P,diff(P,x));
        1 mod 7  -> ok P est sans facteur multiple
    P1:=gcd(P,(x^7-x)mod 7);
        1 mod 7
    P2:=gcd(P,(x^(7^2)-x)mod 7);
        1 mod 7
    P3:=gcd(P,(x^(7^3)-x)mod 7);
        (x^3+x+1) mod 7

donc P possède un facteur de degré 3 modulo 7, donc le facteur restant de degré 4 est forcément irréductible.

On remarque sur cet exemple que 7 est plus intéressant que 5, car la factorisation modulo 7 donne moins de facteurs (à recombiner pour trouver la factorisation dans ℤ) et la factorisation est complète modulo 7 alors que modulo 5 il faut casser le facteur de degré 6 en deux facteurs de degré 3. La plupart des algorithmes de factorisation effectuent la factorisation en degré distinct modulo plusieurs entiers (ce qui peut de plus être parallélisé) et choisissent le meilleur.

#### 7.2.3 La méthode de Cantor-Zassenhaus

Cet algorithme sert à casser des groupes de facteurs de même degré, c’est une méthode probabiliste. On suppose donc qu’on a un produit P d’au moins deux facteurs irréductibles de degré d à casser. Soit D l’un des polynômes irréductibles de degré d à coefficients dans ℤ/pℤ, et soit K=ℤ/pℤ[Y] (mod D(Y) ), on a :

Xpd−X=Πα ∈ K (X−α)

puisque le corps K possède pd éléments tous racines de l’équation Xpd=X.

On considère un polynôme T non constant, et le polynôme Tpd−T. En remplaçant X par T ci-dessus, on en déduit :

Tpd−T=Πα ∈ K (T−α)

Donc pour tout élément β ∈ K=ℤ/pℤ[Y] (mod D(Y) ), on a

(Tpd−T)(β)=Πα ∈ K (T(β)−α)=0

Donc Tpd−T est divisible par Xpd−X (puisque toutes les racines du second sont racines du premier), donc est divisible par tout polynôme irréductible de degré inférieur ou égal à d à coefficients dans Z/pℤ. Comme

Tpd−T=T(T

pd−1
2

−1)(T

pd+1
2

−1) (11)

et que ces trois facteurs sont premiers entre eux, on en déduit que tout polynôme irréductible de degré inférieur ou égal à d à coefficients dans Z/pℤ divise l’un des trois facteurs ci-dessus. Pour casser P, l’idée consiste alors à calculer le pgcd de P et Tpd−1/2−1 pour un polynôme pris au hasard. On sait que P divise le produit des 3 termes de (11), et on espère que les facteurs irréductibles de P ne diviseront pas tous le même terme.

On va montrer que si T est un polynôme de degré ≤ 2d−1 choisi au hasard, la probabilité que deux facteurs irréductibles de P ne divisent pas Tpd−T est proche de 0.5. Soient donc A et B deux facteurs irréductibles de P de degré d. D’après l’identité de Bézout, tout polynôme T de degré ≤ 2d−1 s’écrit de manière unique sous la forme :

T = A U + B V (12)

avec degre(U ≤ d−1) et degre(V ≤ d−1) et réciproquement une combinaison linéaire de cette forme est un polynôme de degré ≤ 2d−1. Choisir T au hasard revient donc à choisir un couple (U,V) de polynômes à coefficients dans ℤ/pℤ au hasard et de manière indépendante. D’autre part, A et B étant de degré d, on sait que dans K=ℤ/pℤ[Y] (mod D(Y) ) ces polynômes admettent d racines. Soit donc α [respectivement β] une racine de A [resp. B] dans K. Alors A divise Tpd−1/2−1 si et seulement si T(α )pd−1/2=1 (et de même pour B et β) car Tpd−1/2−1 a ses coefficients dans ℤ/pℤ (et non dans K). En appliquant (12), A divise Tpd−1/2−1 si et seulement si :

B(α )

pd−1
2

V(α )

pd−1
2

=1

Le premier terme de cette égalité est une constante égale à 1 ou -1, le second a une probabilité proche de 0.5 (égale à pd−1/2pd) de valoir 1 ou -1 car, comme A est irréductible, V(α) décrit K lorsque V décrit les polynômes de degré ≤ d−1. De même, B a une probabilité proche de 0.5 de diviser Tpd−1/2−1, et ces 2 probabilités sont indépendantes puisque U et V le sont, donc la probabilité que soit A soit B divise divise Tpd−1/2−1 est proche de 0.5.

Algorithme de Cantor-Zassenhaus
Argument: Un polynôme P à coefficients dans ℤ/pℤ de degré k dont tous les facteurs irréductibles sont de degré d.
Valeur renvoyée: la liste des facteurs irréductibles de P.

- Si k=d renvoyer une liste contenant P.
- Déterminer un polynôme T aléatoire de degré inférieur ou égal à 2d−1 et de coefficient dominant 1. Calculer le pgcd D de P et de T(pd−1)/2−1. Si le degré de T est égal à 0 ou à k recommencer cette étape.
- Appeler récursivement cet algorithme avec T et P/T et renvoyer la liste réunion des deux listes renvoyées.

Exemple :
Cassons le polynôme de degré 6 obtenu dans l’exemple précédent (modulo 5). Donc P:=(x6+2*x5+x2+x+2) (mod 5 ) et d=3, 2d−1=5, (pd−1)/2=62. On choisit au hasard un polynôme de degré inférieur ou égal à 5, par exemple T=x4−x3+x+1, puis on calcule T62 modulo P ce qui donne (x5+x3+x2+1) (mod 5 ) puis le pgcd de T62−1 et de P qui vaut x3+x+1 (mod 5 ), on a donc cassé P en deux. En prenant T:=x4−x3+x+2, on trouve T62=1 (mod P ), donc ce T n’aurait pas permis de casser P.

#### 7.2.4 La méthode de Berlekamp

Cette méthode permet de factoriser un polynôme sans facteurs multiples, elle peut aussi servir à casser des groupes de facteurs de même degré. Ici on travaille dans l’anneau des polynômes à coefficients dans ℤ/pℤ modulo le polynôme P et on s’intéresse au noyau de ϕ−Id (où ϕ: x ↦ xp). On suppose que P=Πj=1n Fj où les Fj sont irréductibles et premiers entre eux. On va montrer que le noyau de ϕ−Id est composé des polynômes Q tels que Q (mod Fj ) est constant (dans ℤ/pℤ) pour tout j.

Si Q (mod Fj )=sj ∈ ℤ/pℤ, alors Qp (mod Fj )=sjp=sj, donc par le théorème des restes chinois, Q=Qp (mod P ).

Réciproquement, si Qp−Q=0 (mod P ), en utilisant la factorisation :

Xp−X= Πj ∈ ℤ/pℤ (X−j)

on en tire P divise Qp−Q=Πj ∈ ℤ/pℤ (Q(X)−j), donc Fj divise l’un des facteurs et Q(X) (mod Fj ) ∈ ℤ/pℤ. Le noyau de ϕ −Id est donc un espace vectoriel de dimension n, le nombre de facteurs irréductibles de P et possède donc pn éléments (en effet pour tout n uplet de sj, on peut construire un polynôme Q du noyau par le théorème des restes chinois en posant Q(mod Fj )=sj).

L’intérêt du noyau de ϕ−Id est qu’on peut le calculer sans connaitre les Fj. Une fois ce calcul fait, voyons comment on peut remonter aux Fj. On connait déjà la dimension du noyau donc le nombre de facteurs irréductibles. De plus, on remarque que le polynome constant est un élément du noyau qu’on appellera T1, on note alors T2,...,Tn les autres polynômes du noyau. Ensuite, on calcule le pgcd de P avec T2−jT1 pour j∈ ℤ/pℤ. On sait que T2=s2,j (mod Fj ), donc ce pgcd est égal au produit des facteurs Fj tels que s2,j=jT1. L’un au moins des pgcd calculés est non trivial car sinon T2=T1 (mod Fj ) pour tout j donc T2=T1. Si on a de la chance tous les s2,j seront distincts et les pgcd non triviaux de P avec T2−jT1 donneront les Fk. Sinon il faudra continuer avec T3−jT1 etc.

Exemple :
Revenons sur la factorisation de P:=(x6+2x5+x2+x+2) (mod 5 ). Commençons par calculer la matrice de ϕ dans la base { 1,x,x2,...,x5}. On a évidemment ϕ(1)=1 et ϕ(x)=x5, puis ϕ(x2)=x10=x5+x4−2x3+x (mod P ), puis en multipliant par x5 et en divisant par P, ϕ(x3)=−x4+2x3, de la même manière on obtient ϕ(x4)=−x5+2x4+x3−x2−2 et ϕ(x5)=x3+x2−x. La matrice de ϕ est donc :

M=

⎛
⎜
⎜
⎜
⎜
⎜
⎜
⎝

1 | 0 | 0 | 0 | −2 | 0
0 | 0 | 1 | 0 | 0 | −1
0 | 0 | 0 | 0 | −1 | 1
0 | 0 | −2 | 2 | 1 | 1
0 | 0 | 1 | −1 | 2 | 0
0 | 1 | 1 | 0 | −1 | 0

⎞
⎟
⎟
⎟
⎟
⎟
⎟
⎠

On calcule ensuite le noyau de ϕ−Id (comme matrice à coefficients dans ℤ/5ℤ), on obtient une base du noyau en prenant par exemple les vecteurs (−1,0,0,0,0,0) et (0,0,−1,−1,0,−1). Donc le polynôme P possède 2 facteurs dans ℤ/5ℤ[X]. Pour déterminer les facteurs, on calcule le pgcd de P avec le polynôme T2−s où T2=−x5−x3−x2 correspond au 2ème vecteur de la base du noyau. On obtient pour s=0 un pcgd non trivial (x3+x+1), ce qui permet de calculer les 2 facteurs. Si on avait essayé d’autres valeurs de s, pour s=1 on obtient comme pgcd 1, pour s=2 on trouve le 2ème facteur x3+2x2−x+2.

#### 7.2.5 Remontée (Hensel)

Il s’agit de passer d’une factorisation de P dans ℤ/pℤ[X] à une factorisation de P dans ℤ/pk Z[X], la méthode est analogue à celle de l’algorithme EZGCD de calcul de pgcd de polynômes.

On suppose donc que

P=Πj=1n Pj (mod p )

où les Pj sont premiers entre eux deux à deux dans ℤ/pℤ. Il s’agit de trouver des polynômes Pj,k=Pj (mod p ) tels que

P=Πj=1n Pj,k (mod pk )

Commençons par le cas k=2. On pose

Pj,2=Pj+pQj=Pj (mod p )

On a alors :

P | = | Πj=1n Pj,2 (mod p2 ) =Πj=1n (Pj+pQj) (mod p2 )

=

Πj=1n Pj + p

n
∑
j=1

Qj Πk≠ j Pk (mod p2 )

Donc :

n
∑
j=1

Qj Πk≠ j Pk=

P−Πj=1n Pj
p

(mod p )

On est ramené à résoudre une identité de Bézout généralisée. On montrera dans l’appendice le :

Théorème 5 (Identité de Bézout généralisée) Soit P1, ..., Pn (n≥ 2) des polynômes premiers entre eux deux à deux modulo p. Alors pour tout polynôme Q, il existe des polynômes Q1, ..., Qn tels que :

n
∑
j=1

Qj Πk≠ j Pk=Q (mod p )

On a donc réussi à remonter l’égalité P=Π Pj (mod p ) à P=Π Pj,2 (mod p2 ). Le passage de P=Π Pj,l (mod pl ) à P=Π Pj,l+1 (mod pl+1 ) est identique, on a :

Pj,l+1=Pj,l+plQj

où les Qj sont les solutions de l’identité de Bézout généralisée avec :

Q=

P−Πj=1n Pj,l
pl

Lorsqu’on programme cet algorithme (cf. l’appendice), on calcule une fois pour toutes les solutions de l’identité de Bézout pour Q=1, et on multiplie par Q.

Algorithme de remontée de Hensel linéaire
Arguments: Un polynôme P à coefficients entiers, la liste L={ Pj } de ses facteurs dans ℤ/pℤ[X]
Valeur renvoyée: la liste des facteurs de P dans ℤ/pl ℤ[X]
On calcule la borne de Landau-Mignotte6 pour les facteurs de P, on multiplie par le coefficient dominant de P et on calcule l tel que pl est strictement plus grand que deux fois cette quantité. On calcule aussi les polynômes Qj de l’identité de Bézout généralisée pour Q=1
Puis on fait une boucle pour k variant de 2 à l:

- On détermine P−Πj Pj (mod pk ), on divise par pk−1 et on place le résultat dans Q
- On multiplie les polynômes Qj de l’identité de Bézout généralisée (correspondants au polynôme 1) par Q et on détermine le reste de la division euclidienne de Q Qj par Pj, on multiplie par pk−1 et on ajoute le résultat à Pj.

Il existe une version quadratique de cette méthode. On passe alors de P=Π Pj,l (mod pl ) à P=Π Pj,2l (mod p2l ). Pour cela, il faut trouver les polynômes Qj solutions de l’équation :

n
∑
j=1

Qj Πk≠ j Pk,l=Q (mod pl )

Pour l=1, c’est l’identité de Bézout généralisée, mais ce n’est plus le cas pour l>1. En fait, on résout cette égalité en remontant l’identité de Bézout quadratiquement, plus précisément pour trouver les Sj solutions de

n
∑
j=1

Sj Πk≠ j Pk,2l=Q (mod p2l )

on pose Sj=Qj+pl Rj, il s’agit donc de trouver les Rj solutions de

n
∑
j=1

(Qj+pl Rj) Πk≠ j Pk,2l=Q (mod p2l )

soit :

n
∑
j=1

Rj Πk≠ j Pk,l =

Q−

n
∑
j=1

Qj Πk≠ j Pk,l

pl

(mod pl )

on en déduit les Rj.

Algorithme de remontée de Hensel quadratique
Arguments et valeur renvoyée identiques à l’algorithme de remontée de Hensel linéaire ci-dessus.
On commence comme dans le cas linéaire par calculer les coefficients de l’identité de Bézout généralisée pour Q=1 et la valeur de l telle que p2l soit supérieur à deux fois la borne de Landau des facteurs de P fois le coefficient dominant de P.
On fait une boucle sur k variant de 1 à l:

- On calcule P−Πj Pj (mod p2k ), on divise par p2k−1 et on place le résultat dans Q
- On multiplie par Q les polynômes Qj de l’identité de Bézout généralisée (avec comme second membre le polynôme 1), on calcule le reste euclidien du résultat par Pj (modulo p2k−1), on multiplie par p2k−1 et on ajoute à Pj (avec les notations précédentes, on passe ainsi des Pj,2k−1 aux Pj,2k)
- Si k=l on renvoie la liste des Pj
- On calcule 1−∑j Qj Πk≠ j Pk (mod p2k ), on divise par p2k−1 et on place le résultat dans Q
- On multiplie par Q les polynômes Qj de l’identité de Bézout, généralisée et on calcule le reste euclidien du résultat par Pj (modulo p2k−1), on multiplie par p2k−1 et on ajoute à Qj (ce qui ajuste les polynômes Qj qui vérifient maintenant l’identité de Bézout modulo p2k)

Remarque
Pendant l’étape de remontée de Hensel, une optimisation classique consiste à tester la divisibilité dans ℤ du polynôme P par le facteur lifté Pj (7) lorsqu’il n’a pas subi de modification pendant 2 étapes successives (autrement dit lorsque Pj (mod pl )=Pj (mod pl+1 ) (ou (mod p2l ) pour le lift quadratique). Si la division est exacte, on obtient un facteur irréductible de P dans ℤ. On recalcule alors la borne de Landau de P/Pj pour diminuer le nombre d’itérations à effectuer dans cette étape.

Exemple :
Reprenons le polynôme P(X)=(X3+X+1)(X4−X+1) et supposons qu’on ait choisi de le factoriser modulo 5 puis de remonter. On a 3 facteurs a=x−2, b=x3+x+1 et c=x3+2x2−x+2. Si on développe P, on trouve 6 coefficients non nuls de valeur absolue 1, on peut calculer la borne de Landau-Mignotte correspondante sur les coefficients d’un facteur entier : 25 (√(6)+1) soit un peu plus de 110, il suffit donc d’effectuer 3 étapes de remontée linéaire (54=625>111/2). On commence par trouver 3 polynômes A, B, C tels que

A(x3+x+1)(x3+2x2−x+2)+B(x−2)(x3+2x2−x+2)+ |  |
+C(x−2)(x3+x+1) | = | 1 (mod 5 )

On commence par résoudre D(x3+2x2−x+2)+C(x−2)(x3+x+1)=1(mod 5 ), on trouve C=2x2−2 et D=−2x3−2x2+2x+1. Puis on calcule A et B en résolvant E(x3+x+1)+F(x−2)=1 qui donne E=1 et F=−x2−2x qu’on multiplie par D, donc A=D et B=2x5+x4+2x3−2x. Ce qui donne l’identité de Bézout généralisée.

Passons aux calculs de remontée. On a abc=x7−4x5+5x4+−9x3−x2−4 et P=x7+x5+x3−x2+1, donc Q=(P−abc)/5=x5−x4+2x3+1. On pose alors

a1 | = | a+5 (QA (mod a ))(mod 25 ),
b1 | = | b+5 (QB (mod b )) (mod 25 ),
c1 | = | c+5 (QC (mod c )) (mod 25 )

donc :

a1= a+5 × (−2), b1=b+5 × 0, c1=c+5 × (2x2−x)

En principe, on continue encore 2 itérations de la même manière. La 2ème itération donne :

Q=(P−a1 b1 c1)/25= 6x5−3x4+7x3+3x2−2x+1

a2 | = | a1+25 (QA (mod a )) (mod 125 ),
b2 | = | b1+25 (QB (mod b )) (mod 125 ),
c2 | = | c1+25 (QC (mod c )) (mod 125 )

donc :

a2=a1 +25(−1)=x−37, b2=b1=b, c2=c1+25(x2+1) =x3+37x2−6x+27

On peut aussi observer que b1=b, ceci laisse à penser que b est un facteur de P dans ℤ ce qu’on vérifie en effectuant la division euclidienne de P par b=x3+x+1. Comme elle tombe juste, on est ramené à factoriser x4−x+1 et donc à remonter la factorisation de ac. La borne de Landau diminue à 8(√3+1) puisque le degré est 4 et la norme euclidienne du polynôme est √3. Il suffit alors de remonter dans ℤ/125 ℤ au lieu de ℤ/625 ℤ (on gagne ainsi une itération).

#### 7.2.6 Combinaison de facteurs

Lorsqu’on a les facteurs de P dans ℤ/pkℤ[X] avec pk plus grand que le produit du coefficient dominant de P multiplié par la borne de Landau-Mignotte sur les coefficients de P, on commence par tester la divisibilité dans ℤ[X] de P par chaque facteur trouvé multiplié par le coefficient dominant de P. Si la division est exacte, on a un facteur irréductible, mais si elle n’est pas exacte il peut se produire qu’un facteur irréductible de P dans ℤ[X] soit un produit de deux, voir plusieurs, facteurs modulaires. Il faut donc tester la divisibilité de P dans ℤ[X] par toutes les combinaisons possibles de produits de facteurs modulaires (toujours multiplié par le coefficient dominant de P). Cette étape peut être exponentiellement longue si le nombre de facteurs modulaires est grand et si par exemple P est irréductible, bien que les cas soient très rares.

Algorithme de recombinaison
Arguments: un polynôme à coefficients entiers, primitif et sans facteur multiple P de coefficient dominant pn, la liste L des facteurs de P dans ℤ/pl Z[X] pour l assez grand et pl
Valeur de retour: la liste F des facteurs de P dans ℤ.
Initialiser F à vide, initialiser le nombre de facteurs à combine c à 1, entamer une boucle infinie :

- Si c est strictement supérieur au cardinal de L divisé par 2, ajouter le quotient de P par le produit des facteurs de F à F et retourner F
- Initialiser un vecteur v=(v1,...,vc) à c composantes à la valeur (1,...,c)
- Boucle indéfinie intérieure :
  1. Faire le produit des facteurs de F d’indice v, multiplier par pn dans ℤ/pl Z, écrire le facteur en représentation symétrique, le rendre primitif et tester si c’est un facteur de P dans ℤ.
  2. Si on a trouvé un facteur, le rajouter à la liste F et supprimer les indices de v de la liste L, terminer cette boucle intérieure.
  3. Sinon, incrémenter v de la manière suivante:
     On fait une boucle sur un index m initialisé à la taille de v, diminuant de 1 à chaque itération: on ajoute 1 à l’élement de v d’indice m, si l’élément obtenu est inférieur ou égal au cardinal de L+m−n, on arrête cette boucle, sinon on passe à l’itération suivante. Si m=0 à la fin de la boucle, v ne peut pas être incrémenté.
  4. Si v ne peut être incrémenté, on incrémente c et on termine la boucle intérieure.
  5. Sinon on fait une boucle à nouveau sur m en partant de la valeur actuelle incrémentée de 1, et tant que m≤ n on pose vm=vm−1+1. Puis on passe à l’itération suivante de la boucle intérieure.

Il existe différentes méthodes qui améliorent la complexité de cette étape :

- La recherche des degré possibles de facteurs fondée sur la factorisation en degrés distincts pour différents nombres premiers permet d’éviter des tests de division si une combinaison de facteurs est d’un degré exclu par la factorisation pour d’autres nombres premiers.
- Le test de divisibilité du coefficient dominant ou du coefficient constant permet aussi d’éviter des divisions complètes de polynômes.

Mais ces astuces n’évitent pas l’énumération de toutes les combinaisons possibles de facteurs et donc la complexité exponentielle. Lorsque les combinaisons d’un petit nombre de facteurs (par exemple 3) échouent, les systèmes récents utilisent l’algorithme knapsack de Van Hoeij basé sur l’algorithme LLL (recherche de base d’un réseau ayant des vecteurs de petite norme) qui permet d’eliminer complètement cette complexité exponentielle.

Exemple :
Toujours le même exemple, il nous restait deux facteurs dans ℤ/125 ℤ, le facteur x3+x+1 ayant été détecté comme un facteur de P=x7+x5+x3−x2+1 dans ℤ. On teste chacun des facteurs a2=x−37 et c2=x3+37x2−6*x+27 séparément, sans succès. On les multiplie alors modulo 125, ce qui donne x4−x+1 en représentation symétrique qui est bien un facteur de P (donc un facteur irréductible).

### 7.3 Factorisation à plusieurs variables

Comme pour le PGCD en plusieurs variables, on se ramène d’abord en une variable, en général on évalue toutes les variables sauf celle correspondant au degré partiel le plus faible. On factorise ensuite en une variable puis on remonte. A chaque étape de remontée, il peut être à nouveau nécessaire de combiner plusieurs facteurs. Différentes stratégies existent, comme pour le PGCD : factorisarion heuristique (avec reconstruction z-adique), remontée variable par variable ou toutes les variables en même temps comme dans EZGCD. On va présenter ici plus en détails l’algorithme de factorisation heuristique.

Soit P un polynôme en X1,...,Xn à coefficients entiers avec n>1, on choisit une des variables par exemple Xn, qu’on notera X dans la suite. On considère P comme un polynôme en X1,...,Xn−1 à coefficients dans ℤ[X]. On suppose que P est primitif (quitte à extraire son contenu qui est dans ℤ[X]). On calcule ensuite P(z) pour un entier z tel que8 |z| ≥ 2|P|+2. On factorise P(z) dans ℤ[X1,...,Xn−1] :

P(z)(X1,...,Xn−1)=c(z) Πj=1k pj(X1,...,Xn−1) (13)

où c est le contenu du polynôme P(z) (comme polynôme en n−1 variables à coefficients entiers). Il s’agit de reconstruire les facteurs de P à partir des pj et de c. Deux problèmes se posent alors, celui de la recombinaison possible de plusieurs facteurs pj pour obtenir un facteur irréductible de P, et l’existence d’un facteur entier du contenu c à combiner avec un ou plusieurs pj pour obtenir ce facteur irréductible. Plus précisément, si Pk est un facteur irréductible de P, on a :

Pk(z)=d(z) Πcertains j pj, où d(z) divise c(z) (14)

On a le :

Théorème 6 Soit P(X1,...,Xn−1,X) un polynôme à coefficients entiers ayant au moins 2 variables. On suppose que P est primitif vu comme polynôme en les variables X1,...,Xn−1 à coefficients dans Z[X]. Il existe une majoration C du contenu |c(z)| de P évalué en X=z (plus précisément on peut trouver un entier C tel que c(z) divise C).
Il existe un nombre fini de z tels que l’un des facteurs irréductibles Pk de P évalué en X=z soit réductible (c’est-à-dire tels que (14) admette plusieurs facteurs pj distincts)

Preuve
Pour déterminer C, on remarque que les facteurs du contenu de P(z) sont des facteurs communs des coefficients de P évalués en z vu comme polynôme en X1,...,Xn−1 à coefficients dans ℤ[X]. Donc c(z) divise le générateur de l’idéal engendré par ces coefficients (ce générateur est un polynôme de ℤ[X] qui est constant car on a supposé P primitif), on peut aussi dire que deux au moins des coefficients dans ℤ[X] de P sont premiers entre eux, alors c(z) divise le coefficient de l’identité de Bézout de ces 2 coefficients vu comme polynômes en X.

Considérons maintenant un facteur irréductible Pk de P de degré d par rapport à X. Pour X1,...,Xn−1 fixés, on factorise Pk sur ℂ :

Pk(X)=pk Πj=1d (X−zj)

On va maintenant se restreindre à un domaine des X1,...,Xn−1 sur lequel les zj ont une dépendance analytique par rapport à X1,...,Xn−1. Pour cela on veut appliquer le théorème des fonctions implicites pour déterminer zj au voisinage d’une solution donnée. On calcule donc la dérivée P′k de Pk par rapport à X. On sait que P n’a pas de facteurs multiples, donc Pk et Pk′ sont premiers entre eux, donc d’après l’identité de Bézout, il existe un polynôme non nul D dépendant de X1,...,Xn−1 et deux polynômes U et V dépendant de X1,...,Xn−1,X tels que :

U Pk + V Pk′ = D

Si D(X1,...,Xn−1) ne s’annule pas, on va pouvoir appliquer le théorème des fonctions implicites. On se fixe x1,..,xn−1, on calcule dans ℂ les racines zj du polynôme P(x1,..,xn−1,X) pour une solution zj telle que P(x1,..,xn−1,zj)=0, comme D est non nul, on a P′(x1,...,xn−1,zj)≠ 0, donc on peut écrire au voisinage de (x1,..,xn−1)

zj=zj(X1,...,Xn−1), P(X1,...,Xn−1,zj)=0

avec des fonctions zj analytiques. Si D est constant, D ne s’annule pas, sinon quitte à permuter les variables, on peut supposer que le degré de D par rapport à X1 est non nul. On peut alors se restreindre à une zone X1 >> X2 >> .. >> Xn−1 >> 1 où D sera non nul ce qui permet de suivre analytiquement les zj.

Supposons maintenant qu’il existe un nombre infini de z tels Pk(z) soit réductible. Alors il existe un ensemble infini Z de ces valeurs de z pour lesquels l’un des facteurs à coefficients entiers fj de Pk(z) correspond à un même sous-ensemble R des racines zj de Pk et à un même contenu c (puisqu’il y a un nombre fini de combinaisons possibles des racines en facteur et un nombre fini de diviseurs possibles du contenu de Pk). Pour z ∈ Z, on a :

fj(X1,...,Xn,z)=c Πl ∈ R (z−zj), fj ∈ ℤ[X1,...,Xn−1]

Soit L(X) le polynôme obtenu par interpolation de Lagrange en cardinal(R)+1 points z de Z, égal à fj en X=z. Pour des raisons de degré, on a :

L=c Πl ∈ R (X−zj)

donc L est un facteur de P. De plus L est un polynôme en X1,...,Xn−1,X à coefficients rationnels (par construction). Ceci vient en contradiction avec l’hypothèse Pk irréductible, car on a construit un facteur de Pk à coefficients rationnels L de degré strictement inférieur.

Corollaire
Pour z assez grand, la reconstruction z-adique de c(z) pj(z) est un polynôme dont la partie primitive est un facteur irréductible de P.

Preuve du corollaire
On prend z assez grand pour que tous les facteurs irréductibles de P évalués en z aient un seul facteur polynomial (i.e. soient de la forme d(z)pj(z)). Quitte à augmenter z, on peut supposer que |z|> 2 C L où C est la majoration de |c(z)| et L est la borne de Landau sur les facteurs de P. Alors la reconstruction z-adique de c(z)pj(z) est c(z)/d(z)Pj, donc sa partie primitive est un facteur irréductible de P.

Algorithme de factorisation heuristique à plusieurs variables
Argument: un polynôme P primitif en au moins 2 variables.
Valeur renvoyée: les facteurs irréductibles de P
Choisir la variable X par rapport à laquelle P est de plus bas degré puis factoriser le contenu de P vu comme polynôme à coefficients dans ℤ[X]. Initialiser un entier z à 2|P|+2 (où |P| est le plus grand coefficient entier de P en valeur absolue) et une liste L à la factorisation de du contenu de P.
Boucle indéfinie :

- Si P=1 renvoyer la liste L des facteurs de P.
- Tant que pgcd(P(z),P′(z))=0 incrémenter z de 1.
- Factoriser P(z)=c(z)Π pj
- Pour tous les facteurs pj, déterminer le polynôme Pj tel que c(z)pj=Pj(z) par remontée z-adique (avec les coefficients de Pj écrit en représentation symétrique, de valeur absolue plus petite que |z|/2). Tester si la partie primitive de Pj divise P. Si oui, rajouter un facteur irréductible à la liste L, et diviser P par ce facteur.
- Augmenter z, par exemple remplacer z par la partie entière de √2 z.

### 7.4 Preuve de l’identité de Bézout généralisée

Elle se fait par récurrence. Pour n=2, c’est l’identité de Bézout usuelle. Pour passer du rang n−1 au rang n, on isole Pn dans l’identité à résoudre :

⎛
⎜
⎜
⎝

n−1
∑
j=1

Qj (Π1 ≤ k ≤ n−1,k≠ j Pk)

⎞
⎟
⎟
⎠

Pn + Qn Πk≤ n−1 Pk =Q (mod p )

Comme Pn est premier avec Πk≤ n−1 Pk, en appliquant Bézout, on trouve deux polynômes Qn et Rn tels que :

Rn Pn + Qn Πk≤ n−1 Pk =Q (mod p ) (15)

Il reste à résoudre

n−1
∑
j=1

Qj Π1 ≤ k ≤ n−1,k≠ j Pk=Rn (mod p )

ce que l’on peut faire par hypothèse de récurrence.

### 7.5 Algorithme de Bézout généralisé

Arguments: une liste P1,...,Pn de polynômes premiers entre eux 2 à 2 et un polynôme Q à coefficients dans ℤ/pℤ
Valeur renvoyée: la liste de polynômes Q1,...,Qn tels que

n
∑
j=1

Qj Πk≠ j Pk=Q (mod p )

On peut commencer par calculer le produit de tous les Pk puis faire une boucle sur j pour calculer les produits des Pk pour k≠ j en divisant le produit complet par Pj (on fait ainsi n−1 multiplications et n divisions au lieu de n(n−1) multiplications).
Boucle indéfinie sur n décrémenté de 1 par itération :

- Si n=2, on rajoute à la liste résultat les polynômes Q1 et Q2 de l’algorithme de Bézout usuel et on renvoie la liste
- Sinon, on calcule les polynômes Rn et Qn vérifiant (15), on rajoute Qn en début de liste, on remplace Q par Rn.

Remarquons que lorsque nous utiliserons cet algorithme, Q sera la différence entre deux polynômes de même degré (le degré de P) et de même coefficient dominant 1, on peut donc remplacer les Qi par le reste euclidien de Qi par Pi sans changer l’égalité.

### 7.6 Pour en savoir plus

Pour factoriser des polynômes ayant des coefficients dans des extensions algébriques, il existe un algorithme assez simple, l’algorithme de Trager, qui n’est pas forcément le plus performant (la recherche est encore active dans ce domaine), cf. le livre de Henri Cohen pp. 142-144.

Pour factoriser sur des corps finis, on peut consulter la thèse de Bernardin disponible sur le web (`http://www.bernardin.lu`).

On peut aussi consulter le code source de Mupad, les routines de factorisation se trouvent dans le répertoire `lib/POLYLIB/FACLIB` après avoir désarchivé la `lib.tar`. Le point d’entrée pour factoriser des polynômes à plusieurs variables sur ℤ est le fichier `mfactor.mu`, on observera que l’algorithme utilisé par Mupad est assez différent de celui qu’on a détaillé dans la section précédente.

### 7.7 Exercices (factorisation des polynômes)

1. Déterminer le nombre de racines de −x7+x4+12x−5 comprises entre 0 et 6 (en utilisant les suites de Sturm, on donnera les détails des calculs).
2. Écrire un programme calculant la suite de Sturm d’un polynôme supposé squarefree (on peut tester avec `sqrfree`), en utilisant l’algorithme d’Euclide.
3. Trouver les facteurs de degré 1 s’ils existent de 3x5+25x4+67x3+77x2+55x+13 en remontant ses racines dans ℤ/pZ[X] pour p premier bien choisi.
4. Factoriser le polynôme x5+x+1 par la méthode de Berlekamp.
5. Calculer avec un logiciel les valeurs numériques des racines complexes de P(x)=x5+x+1. Trouver les combinaisons de racines dont la somme est entière (aux arrondis près). En déduire la factorisation en facteurs irréductibles sur ℤ de P.
6. Factorisation numérique sur ℂ. Écrire un programme qui calcule une racine d’un polynôme à coefficients complexes en utilisant une méthode itérative de type méthode de Newton (avec éventuellement un préfacteur lorsqu’on débute la recherche). Les polynômes seront représentés par la liste de leurs coefficients et l’évaluation faite par la méthode de Horner. Trouver ensuite toutes les racines du polynôme en éliminant la racine trouvée (toujours avec Horner). Trouver les combinaisons de racines correspondant à un facteur à coefficients entiers.
7. Même question pour les facteurs de degré 2 d’un polynôme à coefficients réels sans racines réelles en utilisant la méthode de Bairstow décrite ci-dessous.
   On cherche un facteur F=x2+sx+p de P, on calcule le quotient et le reste de la division P=FQ+R par une méthode de type Horner, il s’agit de rendre R (vu comme un vecteur à 2 composantes) nul. On calcule donc ∂s,p R (en cherchant le quotient et le reste de xQ et Q par F, pourquoi?) et on pose :

   (s,p)n+1=(s,p)n− λ (∂s,p R)−1 R (s,p)n

   où λ est un préfacteur compris entre 0 et 1 et ajusté à 1 lorsqu’on est proche du facteur.
8. Soit p un entier premier et P un polynôme à coefficients dans ℤ/pℤ. On a la relation

   gcd(Xpk−X,P) =

   ∏
   f | P, deg(f) | k

   f, f irréductible

   En utilisant cette relation, déterminer les degrés des facteurs de

   (x3+x+1)(x4+x+1)

   modulo 5 et 7 (sans utiliser la commande factor). Peut-on en déduire que x3+x+1 et x4+x+1 sont irréductibles sur ℤ?
9. Utiliser les options “verbose” de votre logiciel de calcul formel pour factoriser x202+x101+1 et vérifiez que vous avez compris la méthode utilisée.
10. Montrer que 2x+x2y+x3+2x4+y3+x5 est irréductible sur ℤ sans utiliser l’instruction factor à 2 variables (on pourra factoriser pour quelques valeurs de x ou de y)
11. Que se passe-t-il lorsqu’on exécute l’algorithme de Yun dans ℤ/nℤ?
12. Déterminer les degrés des facteurs de (x3+x+1)(x4+x+1) modulo 5 et 7 (sans utiliser la commande factor). Peut-on en déduire que x3+x+1 et x4+x+1 sont irréductibles sur ℤ?
13. Utiliser les options “verbose” de votre logiciel de calcul formel pour factoriser x202+x101+1 et vérifiez que vous avez compris la méthode utilisée.
14. Montrer que 2x+x2y+x3+2x4+y3+x5 est irréductible sur ℤ sans utiliser directement l’instruction factor (on pourra factoriser pour quelques valeurs de x ou de y)

## 8 Intégration

### 8.1 Introduction

Que peut-on espérer d’un système de calcul formel lorsqu’il s’agit de calculer une primitive? Tout d’abord, on peut espérer qu’il sache résoudre ce que l’on donne en exercice à nos étudiants! Ceci suppose donc de connaitre quelques méthodes classiques, par exemple: intégration de polynômes (!), polynômes multipliés par exponentielle ou/et fonctions trigonométriques, de polynômes trigonométriques par linéarisation, de fractions rationnelles, de fractions trigonométriques, de fractions de racines carrées de polynômes du second ordre, de fonctions s’y ramenant par une ou plusieurs intégrations par parties ou par changement de fonction (par exemple reconnaissance de formes F(u)u′ ) ou par changement de variables, etc.

Mais au-delà de ces méthodes (qui ont l’avantage de la rapidité mais tiennent parfois plus de la recette de cuisine que de l’algorithme...), on peut se demander si la primitive d’une fonction donnée peut ou non s’exprimer en terme des fonctions “élémentaires”. Par exemple, tout le monde “sait” que la fonction ex2 n’admet pas de primitive “simple”, encore faut-il donner un sens mathématique précis à cette affirmation. Ceci nécessite de donner une définition rigoureuse du terme fonction élémentaire. On peut alors appliquer un algorithme développé par Risch (pour les extensions dites transcendantes, obtenue par ajout des fonctions exponentielle et logarithme) qui permet de répondre à la question : il s’agit vu de très loin d’une extension de l’algorithme d’intégration des fractions rationnelles.

Cet article se décompose en deux parties principales :

- la section 8.2 présente les définitions de fonctions élémentaires, de tour de variables, et donne deux théorèmes, le théorème de structure de Risch qui permet d’écrire une fonction contenant des exponentielles et des logarithmes comme une fonction élémentaire par rapport à une tour de variable, et le théorème de Liouville qui donne la forme que peut prendre une primitive d’une fonction élémentaire lorsqu’elle est aussi élémentaire.
- la section 8.3 décrit l’algorithme d’intégration de Risch permettant de décider si une fonction élémentaire donnée possède ou non une primitive élémentaire et de la calculer dans le premier cas. Nous ne présentons ici l’algorithme de Risch que pour les extensions transcendantes pures (ln et exp).

Le lecteur intéressé par le cas des extensions algébriques pourra consulter la thèse de Trager. Pour les extensions plus générales (incluant en particulier les fonctions tangente, arctangente), la référence est le livre de Bronstein donnée en section 8.4.

### 8.2 Fonctions élémentaires

#### 8.2.1 Extensions transcendantes, tour de variables

On se donne une expression f(x) dépendant de la variable x que l’on souhaite intégrer par rapport à x. L’algorithme de Risch s’applique à cette expression si on peut l’écrire comme une fraction rationnelle à plusieurs variables algébriquement indépendantes

x, f1(x), f2(x,f1(x)), ..., fn(x,f1(x),f2(x,f1(x)),...,fn−1(x,f1(x),...,fn−2(x)))

où les fi sont soit l’exponentielle soit le logarithme d’une fraction rationnelle (le corps de base appelé aussi corps de constantes ici est soit ℂ, soit une extension algébrique de ℚ ou une extension algébrique d’un corps de fractions rationnelles s’il y a des paramètres). On appelle tour de variables la suite des x,f1,...,fn (chaque étage est donc une exponentielle d’une fraction rationnelle ou le logarithme d’une fraction rationnelle dépendant des étages précédents) et on dira que f est une fonction élémentaire par rapport à cette tour de variables.

L’intérêt de l’écriture d’une expression sous forme de tour est qu’elle est stable par dérivation : si on dérive par rapport à x une fonction élémentaire dépendant d’une tour de variables, on obtient encore une fonction élémentaire dépendant de la même tour de variables. Autrement dit, l’ensemble des fonctions élémentaires pour une tour fixée est un corps différentiel.

Exemples:

- ex2 est bien dans ce cas, pour n=1, f1 est l’exponentielle de x2 qui est algébriquement indépendant de x. Les fonctions (2x2−1)ex2 ou x/(ex2−1) sont aussi élémentaires par rapport à la tour de variables {x,ex2 }.
- x ln(x) exp(x) est élémentaire par rapport à la tour { x, ln(x), exp(x)}, mais aussi par rapport à la tour { x, exp(x), ln(x)}.
- xex ln(x) est élémentaire, en prenant n=2, f1=ln(x) et f2=ex f1.
- xn=enln(x), où n est un paramètre, convient avec comme tour {x, ln(x), en ln(x)
- eln(x) ne convient pas car il n’est pas algébriquement indépendant de x,ln(x) mais on peut le réécrire sous une forme acceptable puisque eln(x)=x.
- eln(x)/2 ne convient pas non plus car son carré est égal à x. Une réécriture ne suffit pas, cet exemple est bien sûr une extension algébrique et non transcendante.

Dans la suite, on va s’intéresser aux tours de variables dans lesquelles on a effectué des simplifications évidentes. On élimine les ln∘ exp de la manière suivante : si fk=ln(gk), on regarde si gk vu comme fraction en f1,...,fk−1 possède un facteur fjm (avec m ∈ ℤ) lorsque fj=exp(gj) est une exponentielle. Si c’est le cas, on a fk= m gj + ln(gk/gjm). On change alors de tour en remplaçant fk par fk=ln(gk/gjm)=fk−mgj. On élimine aussi les exp∘ ln, si fk=exp(gk), pour j<k si fj est un logarithme, on regarde si cj=∂fjgk|fj=0 est un entier, si c’est le cas on remplace fk par fk=fk/gkcj.

Exemples:

ln(

ex2+1
ex2

)

→

−x2 + ln(ex2+1)

e3 ln(x)+ln(x)2+5 | → | x3 eln(x)2+5

#### 8.2.2 Théorème de structure de Risch

On voit donc qu’il est nécessaire de disposer d’un algorithme pour décider si des exponentielles et logarithmes sont algébriquement indépendants. Cet algorithme est basé sur un théorème de structure dû à Risch :

Théorème 7 Soit f=ln(g(x)) le logarithme d’une fonction élémentaire g par rapport à une tour de variables T, alors soit f est algébriquement indépendant des variables de T, soit f est élémentaire et plus précisément combinaison linéaire rationnelle des logarithmes et des arguments des exponentielles de la tour T.

Soit f=exp(g) l’exponentielle d’une fonction élémentaire g par rapport à une tour de variables T, alors soit f est algébriquement indépendante des variables de T, soit il existe n tel que fn soit élémentaire par rapport à T (on peut alors appliquer le cas précédent à ng=ln(fn))

Démonstration :
Commençons par le cas de l’exponentielle. On considère le polynôme minimal de f=exp(g) :

an fn+...+a0=0, an ≠ 0 , a0 ≠ 0

où les ai sont des fractions rationnelles en T. On dérive et on applique f′=g′f :

(an′+n an g′) fn + ... + ( ak′ + kak g′)fk +... =0

c’est un multiple du polynôme minimal donc il existe une fraction rationnelle C (par rapport à la tour de variables) telle que :

∀ k, (ak′+k ak g′) = C ak

Comme an≠ 0, cela entraine an′/an+ng′=C. Le coefficient constant a0 est aussi non nul, donc a0′/a0=C et

n g′ = a0′/a0 − an′/an ⇒ ng=ln(

a0
an

) + k

où k est constant, donc fn=exp(ng)=ek a0/an est élémentaire.

Passons au cas du logarithme, supposons que f=ln(g) dépende algébriquement de la tour T, on va commencer par montrer que f est élémentaire. On écrit :

an fn+...+a0=0

où les ai sont des fractions rationnelles en T. On dérive en appliquant f′=g′/g :

an′ fn + (n an f′ + an−1′)fn−1 ... + a1 f′+a0 ′

Comme f′ est une fraction rationnelle en T, le polynôme an′ Xn + (n an f′+an−1′) Xn−1+...+ a1 f′+a0′ qui annule f doit être un multiple du polynôme minimal de f, il existe donc une fraction rationnelle C par rapport à T telle que :

an′ = C an (n an f′+an−1′) = C an−1 ...

On en déduit f′ :

f′=

an′
an

an−1−an−1′

n an

=

⎛
⎜
⎜
⎝

−an−1
n an

⎞
⎟
⎟
⎠

′

donc il existe une constante c telle que :

f=

−an−1
n an

+c

donc f est élémentaire par rapport à la même tour T que g.

Montrons maintenant qu’un logarithme f=ln(g) qui est élémentaire par rapport à une tour de variable T est combinaison linéaire à coefficients rationnelles des logarithmes et des arguments des exponentielles de T9. Soit X la dernière variable de la tour T. On factorise maintenant le numérateur et le dénominateur de g en ∏j Pjj où les Pj sont sans facteurs multiples et premiers entre eux 2 à 2 (par rapport à X), il existe C indépendant de X tel que :

g=C

∏
j ∈ ℤ

Pjj ⇒ ln(g)=ln(C)+

∑
j ∈ ℤ

j ln(Pj) (16)

Alors f′=ln(C)′+∑j j Pj′/Pj donc ∏Pj f′ est un polynôme en X. Soit N/D la fraction irréductible représentant f, on a :

f′=

N′ D −N D′
D2

on vient donc de montrer que :

⎛
⎜
⎜
⎝

∏
j

Pj

⎞
⎟
⎟
⎠

N′ D − N D′
D2

est un polynôme en X (17)

Soit P un facteur irréductible de D de multiplicité k tel que D=Pk Q (donc P premier avec Q, mais P est aussi premier avec N car f=N/D est irréductible). Alors en simplifiant numérateur et dénominateur par Pk−1, on a :

⎛
⎜
⎜
⎝

∏
j

Pj

⎞
⎟
⎟
⎠

N′ P Q − N (kP′Q+PQ′)
Pk+1 Q2

est un polynôme en X. (18)

On en déduit, après simplification d’au plus un facteur P au dénominateur avec l’un des Pj, que Pk divise N′ P Q − N (kP′Q+PQ′) donc P divise P′. Ceci n’est possible que si P=1 (et donc le dénominateur de f est égal à 1) ou si la variable X est une exponentielle et P=X.

Montrons que ce deuxième cas est en fait exclus: en effet si P=X=exp(Y) est une exponentielle, on a alors D=Xk et Q=1. Comme P′=Y′X, (18) devient :

⎛
⎜
⎜
⎝

∏
j

Pj

⎞
⎟
⎟
⎠

X (N′ − k N Y′ )
Xk+1

est un polynôme en X

Comme X ne divise pas N, N possède donc un coefficient constant a0 non nul. Le coefficient constant de N′−kNY′ est a0′−ka0 Y′. Si ce terme était nul alors a0′=ka0 Y′ donc a0=c exp(kY)=cXk or a0 ne dépend pas de X donc c=0 donc a0=0, absurde. Donc X ne divise pas N′−kNY′. Comme Xk+1 divise ∏Pj X (N′ − k N Y′ ), on en déduit que Xk divise un des Pj. Donc k=1 et Pj=XQj. Revenons maintenant à (16), on a :

f=ln(g) = ln(C)+j ln(XQj)+

∑
l ≠ j

l ln(Pl)

on dérive :

f′=ln(C)′+jY′+j

Qj′
Qj

+

∑
l ≠ j

l

Pl′
Pl

on voit qu’il n’est plus nécessaire de multiplier f′ par Pj pour avoir un polynôme, multiplier par Qj suffit, plus précisément

⎛
⎜
⎜
⎝

∏
l ≠ j

Pl

⎞
⎟
⎟
⎠

Qj

N′ D − N D′
D2

est un polynôme en X.

donc Xk+1 divise (∏l ≠ jPl ) Qj X (N′ − k N Y′ ) ce qui est impossible.

Donc D=1 dans tous les cas et on a f=N. Donc

f′=N′=ln(C)′+

∑
j

j Pj′/Pj est un polynôme par rapport à X

On en déduit que les Pj ne dépendent pas de X sauf si X est une exponentielle et Pj=X. Dans les deux cas N′ ne dépend pas de X donc le polynôme N est de degré 0 ou 1 en X (si X est une exponentielle, N est forcément de degré 0)

- Si X=exp(Y) est une exponentielle (avec Y élémentaire ne dépendant pas de X), alors f=N est indépendant de X. On retire jY à f et on divise g par Xj (en posant j=0 si aucun des Pj n’est égal à X), qui devient indépendant de X, on conserve ainsi l’égalité f=ln(g) mais avec une variable de moins dans la tour de variables par rapport à laquelle f et g sont élémentaires.
- Si X n’est pas une exponentielle, N=cX+d avec c dans le corps de constantes, et d indépendant de X. Si X=x, on a g=exp(cx+d) qui n’est rationnel que si c=0. On a alors d donc f et g constants. Si X=ln(Y) est un logarithme (avec Y élémentaire ne dépendant pas de X), alors ∀ j, Pj=1 donc g est élémentaire indépendante de X. On a alors :

  f=N=cln(Y)+d = ln(g)

  avec c dans le corps des constantes, d et g élémentaires indépendants de X. On cherche maintenant la fonction élémentaire d. Cette fonction n’est pas le logarithme d’une fonction élémentaire en général car c n’est pas forcément entier, mais d′ a les mêmes propriétés que la dérivée du logarithme d’une fonction élémentaire. On peut donc reprendre le même raisonnement mais avec une variable de moins dans la tour de variables. Si la tour qu’on a choisie est normalisée, alors Y ne contient au numérateur et au dénominateur aucune puissance d’une exponentielle d’une variable de la tour donc le polynôme Pj du cas précédent ne peut provenir de Y ce qui entraine que j est bien entier dans le cas précédent (bien que c ne le soit pas forcément).

Après avoir fait une récurrence sur le nombre de variables de la tour, on a donc f qui s’exprime comme combinaison linéaire à coefficients entiers des arguments gk des variables exponentielles fk=exp(gk) de la tour et à coefficients a priori quelconque des variables logarithmes fl=ln(gl) de la tour :

f =

∑
k

jk gk +

∑
l

xl ln(gl) = ln(g)

Comme g est élémentaire, h=g/∏k exp(gk)jk est élémentaire de logarithme ∑l xl ln(gl) . Montrons que si les arguments des ln sont des polynômes sans facteurs multiples, alors les xl sont entiers. Rappelons que les ln(gl) sont algébriquement indépendants, on peut donc construire des polynômes irréductibles Il par rapport aux variables de la tour tels que Il divise une fois gl mais ne divise pas les gk précédents. Soit h=∏j ∈ ℤ Pjj la factorisation sans facteurs multiples de h. On dérive alors ln(h) ce qui donne :

∑
l

xl gl′/gl =

∑
j

j Pj′/Pj

où ∏j Pjj est la décomposition sans facteurs multiples de h. Comme Il divise un et un seul des Pj on en déduit que xl est égal au j correspondant et est donc entier. (Remarque: si on n’impose pas aux arguments des logarithmes d’être des polynômes sans facteurs carrés, on obtiendrait ici des coefficients rationnels).

En pratique:
On peut effecter l’algorithme de la manière suivante :

- on cherche les variables généralisées de l’expression qui dépendent de x.
- On ajoute les variables généralisées en commençant par la moins longue
- Si c’est un logarithme, on extrait les puissances des exponentielles précédentes dont il dépend. On cherche des relations entre fonctions ln en les réécrivant comme combinaison linéaire de ln indépendants. Pour avoir des ln indépendants, on se ramène d’abord à des polynômes sans facteurs multiples en utilisant la relation ln(a/b)=ln(a)−ln(b) et en écrivant la factorisation sans facteurs multiples de chaque polynôme argument, puis on extrait le PGCD 2 à 2 des arguments de logarithmes jusqu’à obtenir des arguments de ln premiers entre eux.
- Si c’est une exponentielle, on teste si son argument est combinaison linéaire à coefficients rationnels :
  - des arguments des exponentielles précédentes,
  - des ln des logarithmes précédents,
  - de ln(x) et de i*π.
  Pour cela on substitue les ln par des indéterminées, et on dérive une fois par rapport à cette indéterminée, le résultat doit être un rationnel, pour les variables exponentielles, il faut réduire au même dénominateur et résoudre le système linéaire obtenu en identifiant les coefficients du numérateur. Si l’exponentielle est indépendante des précédentes, on extrait de l’exponentielle à rajouter la partie linéaire de la dépendance en les ln précédents si le coefficient correspondant est entier. Par exemple, on réécrit :

  xe2 ln(x)+ln(x)2 = x3 eln(x)2

Remarque
On n’est pas obligé de se limiter aux seules fonctions logarithmes et exponentielles, l’essentiel est de pouvoir tester l’indépendance algébrique des expressions créées. Pour éviter d’avoir à introduire des exponentielles et logarithmes complexes dans une expression réelle, on peut autoriser par exemple des extensions en tangente ou en arctangente.

#### 8.2.3 Théorème de Liouville

On a vu que la dérivée d’une fonction élémentaire dépendant d’une tour de variables est une fonction élémentaire dépendant de la même tour de variables. Réciproquement, supposons qu’une fonction élémentaire admette une primitive qui soit élémentaire, c’est-à-dire qu’elle doit être une fraction rationelle par rapport à une tour de variables mais pas forcément identique à celle de départ. Alors, si une telle écriture existe, à des termes logarithmiques près, elle ne peut dépendre que de la même tour de variables, plus précisément on a le théorème de Liouville :

Théorème 8 Soit f une fonction élémentaire par rapport à une tour de variables T et un corps de constantes K admettant une primitive élémentaire F. Alors il existe un nombre fini de constantes c1,...,cn et de fonctions élémentaires v1,...,vn par rapport à T avec comme corps de constantes une extension algébrique K′ de K tel que F − ∑k ck ln(vk) soit élémentaire par rapport à T et K.

Preuve:10
Soit f élémentaire de tour T1 (corps K) et F sa primitive supposée élémentaire de tour T2 et de corps K′ une extension algébrique de K. On commence par rajouter après les élements de T1 les élements nécessaires de T2 pour obtenir une tour T par rapport à laquelle f et F sont élémentaires (plus précisément F sera élémentaire quitte à autoriser des puissances fractionnaires des variables exponentielles de T1). Le théorème de structure de Risch permet de faire cela, en effet on regarde pour chaque élément de T2 s’il est algébriquement indépendant des éléments de T1 ou non. S’il l’est, on le rajoute à la tour T, s’il ne l’est pas alors dans le cas d’un logarithme il est élémentaire et dans le cas d’une exponentielle, une de ses puissances est élémentaire. Donc F est bien une fraction rationnelle par rapport aux éléments logarithmiques de T1, aux racines n-ième des éléments exponentiels de T1 et à des éléments de T2 dans cet ordre (le corps des constantes étant K′).

Première étape:
Commençons par les éléments restant de T2. Soit Xk l’élément au sommet de la tour T. La dérivée f de F par rapport à Xk ne dépend pas de Xk. Donc soit F ne dépend pas de Xk et on passe à la variable suivante, soit Xk=ln(vk) est un logarithme et F=ck ln(vk)+dk avec ck ∈ K′ et vk et dk indépendants de Xk. S’il n’y a pas d’autres éléments restants de T2, on passe à la 2ème étape. Sinon soit Xk−1 la variable suivante (juste en-dessous de Xk dans la tour). En dérivant, on a :

F′= ck

vk′
vk

+ dk′ = f

Supposons que vk dépende de Xk−1, on fait alors un raisonnement analogue à celui de la preuve du théorème de structure de Risch, en décomposant vk en produit/quotient de facteurs sans multiplicités vk=∏Pjj et en écrivant dk=N/D on a :

⎛
⎜
⎜
⎝

∏
j

Pj

⎞
⎟
⎟
⎠

N′ D − N D′
D2

est un polynôme en Xk−1. On en déduit comme précédemment que D=1, N′=dk′ est indépendant de Xk−1. Comme on a supposé que vk dépend de Xk−1, Xk−1=exp(Yk−1) est alors une exponentielle, N=dk ne dépend pas de Xk−1 et l’un des Pj=Xk−1 (sinon tous les Pj seraient constants en Xk−1 donc vk aussi). On élimine alors la variable Xk−1 en écrivant ln(vk)=jYk−1+ln(wk), avec Yk−1 et wk élémentaires et indépendants de Xk−1.

Si vk est indépendant de Xk−1, alors dk′ aussi donc soit dk est indépendant de Xk−1 et on passe à la variable suivante, soit Xk−1 est un logarithme et dk=ck−1ln(vk−1)+dk−1. En continuant pour toutes les variables restantes de T2, on obtient

F=

∑
k

ck lnvk +d

avec d et vk élémentaires pour T1 (avec exponentielles modifiées en en prenant une racine n-ième) et K′.

Deuxième étape Il s’agit de montrer que pour les exponentielles, il n’est en fait pas nécessaire de prendre de racines n-ième. La compréhension de cette étape demande un peu de familiarité avec l’algorithme de Risch (cf. infra). On va faire la preuve pour la variable au sommet de la tour T1 si c’est une exponentielle. On verra dans le déroulement de l’algorithme de Risch que pour les autres variables, il y a appel récursif de l’algorithme d’intégration, donc traiter la variable au sommet suffira. Soit donc exp(Y) la variable au sommet de la tour T1, on note X=exp(Y/n) la racine n-ième de cette variable qui est utilisée pour exprimer F=∑ck lnvk + N/D comme une fraction rationnelle en X alors que f=F′ est une fraction rationnelle en Xn. On a donc :

∑ck

vk′
vk

+

N
D

′ =f=fraction rationnelle en (Xn)

Notons que le fait que X soit une exponentielle est essentiel, car par exemple l’intégrale d’une fraction rationnelle dépendant de xn comme x3 ou 1/(x3−1) ne s’exprime pas en fonction de x3. On traite d’abord la partie polynomiale généralisée de f en Xn:

∑
j∈ ℤ

aj (Xn)j

Son intégrale est un polynôme généralisé, éventuellement dépendant de X, soit ∑j∈ ℤ Aj Xj. On dérive, et on obtient pour k non multiple de n, Ak Y/n+Ak′=0 dont Ak=0 est solution. La partie polynôme généralisé ne dépend donc que de Xn. On effectue aussi les intégrations par parties pour réduire le dénominateur de f à un polynôme sans facteurs multiples (réduction de Hermite), ce qui se fait en introduisant des fractions rationnelles en Xn uniquement. Reste la partie logarithmique. On utilise le critère du résultant, les coefficients des logarithmes sont les racines ck du polynôme en t

ResX (D,N−tD′)

où ces racines doivent être indépendantes de x (puisque F existe) et les vk correspondants sont égaux à

gcd(D,N−ck D′)

Or comme X est une exponentielle, D′ est un polynôme en Xn, de même que D et N, donc vk est un polynôme en Xn.

Troisième étape Il reste enfin à montrer que seuls les ck et vk nécessitent une extension algébrique de K. Ceci est encore une conséquence de l’algorithme de Risch, la construction de la partie polynomiale (éventuellement généralisée) et de la partie fractionnaire ne font en effet intervenir que des coefficients dans le corps K.

### 8.3 L’algorithme de Risch

On suppose dans la suite qu’on s’est ramené à une fraction rationnelle par rapport à une tour de variables (où on a effectué les simplifications évidentes ln∘ exp, ainsi que exp∘ ln, dans le premier cas en extrayant les facteurs évidents en les variables précédentes exponentielles, dans le deuxième cas en extrayant la partie linéaire à coefficient entier en les variables logarithmes précédentes). On note X la variable au sommet de la tour et N0/D0 l’écriture de la fonction élémentaire comme fraction irréductible avec N0 et D0 polynômes en X.

Exemples

∫ | (2x2+1) ex2

X=ex2

N0=(2x2+1) X, D0=1

∫

x ln(x)
x+ln(x)

X=ln(x)

N0=xX, D0=x+X

La première étape va consister à se ramener à un dénominateur sans facteurs multiples. Elle est analogue au cas des fractions rationnelles de x et est basée sur l’identité de Bézout entre P et P′ vu comme polynômes en la variable du haut de la tour. Il apparait toutefois une difficulté pour les extensions exponentielles, à savoir que X=ef et X′=f′ X ne sont pas premiers entre eux comme polynômes en X, on devra traiter le pôle 0 d’une fraction rationnelle en une exponentielle X comme on traite l’intégration d’un polynôme en x. Si P est sans facteurs multiples et premier avec X, alors P(X) et P(X)′=f′ X P′(X) vu comme polynômes en X n’ont pas de facteurs en commun.

On commence donc, si X est une exponentielle et D0 un multiple de X, par appliquer Bézout pour décomposer la fraction N0/D0 en :

N0
D0

=

N1
D1

+

P
Xk

, gcd(X,D1)=1, D0=Xk D1

On isole aussi la partie polynômiale en effectuant la division euclidienne de N0 par D0 (ou de N1 par D1 si X est une exponentielle), on obtient alors une écriture sous la forme :

N
D

+

∑
j

aj Xj

où la somme sur j est finie et porte sur des entiers positifs ou nul si X n’est pas une exponentielle, ou sur des entiers relatifs si X est une exponentielle.

On effectue la même écriture sur la partie fractionnaire de F, et en identifiant les parties polynomiales et éventuellement la partie polaire en 0 si X est une exponentielle, on peut séparer l’intégration en 2 parties: intégration de la partie polynomiale (généralisée) et intégration de la partie fractionnaire propre.

Exemples

- (2x2+1) ex2 = 0+(2x2+1)X est un polynôme,

- x ln(x)
  x+ln(x)

  =

  xX
  x+X

  =−

  x2
  x+X

  +x

  la partie polynomiale est x (de degré 0 en X), la partie fractionnaire est −x2/(x+X)

- x(e2x+1)
  ex(ex+1)2

  =

  x(X2+1)
  X(X+1)2

  = −

  2x
  (X+1)2

  + xX−1

  la partie polynôme généralisé est xX−1

#### 8.3.1 Intégration d’une fraction propre

#### 8.3.2 Réduction sans facteurs multiples

On factorise D en ∏i Pii avec Pi sans facteurs multiples (et les Pi premiers entre eux 2 à 2) et on décompose en éléments simples relativement à cette factorisation (en appliquant Bézout) :

N
D

=

∑
i>0

Ni
Pii

Pour chaque polynome Pi, on applique Bézout à Pi et P′i :

Ni = AiPi+BiP′i ⇒

Ni
Pii

=

Ai
Pii−1

+

BiPi′
Pii

on intègre par parties le second terme

∫

Ni
Pii

=

∫

Ai
Pii−1

−

Bi
(i−1)Pii−1

+

∫

Bi′
(i−1)Pii−1

on rassemble les deux intégrales ayant Pii−1 au dénominateur et on recommence jusqu’à avoir une puissance 1 au dénominateur. Il reste alors à intégrer une somme de fractions du type N/D avec D et D′ premiers entre eux.

Exemple
On reprend le dernier exemple de la section précédente pour éliminer la puissance 2 au dénominateur: N2=2x et P2=(X+1) avec X=ex. On a P2′=X, donc A2=2x et B2=−2x :

∫

2x
(X+1)2

=

∫

2x
P2

+

∫

−2x P2′
P22

=

∫

2x
P2

+

2x
P2

−

2
P2

il reste donc à intégrer (2x−2)/(ex+1).

#### 8.3.3 La partie logarithmique

Comme on l’a vu lors de la preuve du théorème de structure de Risch, si on dérive une fraction en X, le dénominateur de la dérivée ne peut se décomposer qu’en produit de facteurs de multiplicité supérieure ou égale à 2. Il en résulte que la fraction à intégrer résiduelle (encore notée f=N/D) après l’étape de réduction ci-dessus ne peut provenir que de la dérivation de F=∑k ck ln(vk) :

f=

N
D

=F′= (

∑
k

ck ln(vk))′=

∑
k

ck

vk′
vk

En identifiant les décompositions en éléments simples de F′ et f, on montre également que les vk divisent D, plus précisément on peut imposer aux vk d’être premiers entre eux 2 à 2 et dans ce cas D=∏vk. Donc :

∑
k

ck

vk′
vk

=

N

∏
k

vk

=

N
D

et :

N =

∑
k

ck vk′

∏
j≠ k

vj

Soit t un paramètre, formons le polynôme N−tD′ :

N−tD′ =

∑
k

⎛
⎜
⎜
⎝

(ck −t) vk′

∏
j≠ k

vj

⎞
⎟
⎟
⎠

donc le pgcd en X des polynômes N−tD′ et D est :

- si t n’est égal à aucun des ck, N−tD′ est premier avec vk pour tout k car vk divise ∑l ≠ k (cl −t) vl′ ∏j≠ l vj et vk′∏j≠ k vj est premier avec vk. Donc le pgcd est 1.
- si t est égal à l’un des ck, alors le pgcd est le produit des vk tels que ck=t (notons que dans ce cas on peut rassembler ces vk à l’intérieur d’un même logarithme)

Considérons le polynôme R de la variable t égal au résultant par rapport à X des polynômes D et N−tD′ (rappelons qu’il s’agit du déterminant du système linéaire AD+B(N−tD′)=1 où les inconnues sont les coefficients des polynômes A et B, ce déterminant est nul si et seulement si le système n’a pas de solution donc si et seulement si D et N−tD′ ne sont pas premiers entre eux), alors ce polynôme en t s’annule si et seulement si t=ck. On cherche les racines ck en t de ce polynôme, elles doivent être indépendantes de x si F est élémentaire, et dans ce cas la primitive F de f=N/D vaut

F=

∑
ck racine de R

ck ln(gcd(N−ck D′,D))

Exemples

- 2x−2
  ex+1

  , D=X+1, D′=ex=X, N−tD′=2x−2−tX

  On calcule R=−2*x−t+2, l’unique racine est t=2−2x qui n’est pas constante donc cette fonction n’admet pas de primitive élémentaire.

- (2x2−x−2)X−1
  X2+(x+1)X+x

  , X=exp(x2+x)

  On a D′=2(2x+1)X2+(1+(2x+1)(x+1))X+1

  R=−(2x−1)(x+1)(2x+1)(x−1)2(t+1)(t−1)

  les racines en t sont constantes et égales à 1 et -1, donc c1=1 et v1=gcd(N−D′,D)=X+1 et c2=−1, v2=gcd(N+D′,D)=x+X donc :

  ∫

  (2x2−x−2)X−1
  X2+(x+1)X+x

  = ln(X+1)−ln(x+X)

Remarque importante
Pour les extensions exponentielles ou logarithmiques, la dérivée de la partie logarithmique calculée comme ci-dessus contiendra en général une partie entière constante par rapport à X, il faut donc retirer cette partie entière à la partie polynomiale.

#### 8.3.4 La partie polynomiale (généralisée)

On doit résoudre :

(

∑
j

Aj Xj)′=

∑
j

aj Xj

avec une somme sur j ∈ℤ si X est une exponentielle et j∈ ℕ sinon.

Si X=x, j≥ 0 et la résolution est immédiate: on prend A0=0 et Aj+1=aj/(j+1).

#### 8.3.5 Extension logarithmique

Si X=ln(Y) est un logarithme, j ≥ 0 et on doit résoudre :

∑
j≥ 0

(Aj′+(j+1)Aj+1

Y′
Y

) Xj =

∑
j

aj Xj

Soit k la plus grande puissance non nulle de f (aj=0 si j>k et ak≠ 0). Pour j>k, on a :

Aj′+(j+1)Aj+1

Y′
Y

=0

On résout pour des valeurs de j décroissante, pour j suffisamment grand, on a Aj+1=0 car la somme sur j est finie, donc Aj est constant. Si Aj ≠ 0, alors au rang j−1, on a Aj−1 ′ = −j Aj Y′/Y qui n’admet pas de solutions car Aj−1 ne peut pas dépendre de X=ln(Y). On en déduit que pour j>k+1, on a Aj=0 et Ak+1 est constant. En fait la valeur constante de Ak+1 sera déterminée par une condition de compatibilité en résolvant l’équation au rang du dessous. On continue la résolution de

Aj′+(j+1)Aj+1 ln(Y)′ = aj

par valeur décroissante de j, à chaque rang on va déterminer Aj à une constante près en résolvant un problème d’intégration (par appel récursif de l’algorithme de Risch, mais si j ≠ 0 sans autoriser l’ajout de nouveaux logarithmes sauf ln(Y)) et la valeur de la constante de Aj+1 (on fait varier Aj+1 de la constante nécessaire pour absorber le terme en ln(Y) qui apparait lors de l’appel récursif de Risch). Au rang 0, on est ramené à un problème d’intégration avec une variable de moins (la constante indéterminée dans A1 peut par exemple être choisie comme le coefficient constant de ln(Y) s’il en apparait un en intégrant).

Exemple
X=ln(x2+1) et on cherche l’intégrale de X2. On a donc A3 est constant,

A2′ + 3 A3 ln(x2+1)′ = 1

La primitive de 1 est élémentaire et ne fait pas intervenir de ln donc A3=0 et A2=x+C2. Au rang 1, on a :

A1′ + 3 x

2x
x2+1

+ C2 ln(x2+1)′ = 0

On calcule la primitive de 6x2/(x2+1) qui doit être une fraction rationnelle à un Cln(x2+1) près, on voit que ce n’est pas le cas donc X2 n’admet pas de primitive élémentaire. Remarque: si on avait voulu intégrer X au lieu de X2, la même méthode montre que la primitive existe, car au rang 0 il n’y a plus de contraintes sur les ln qu’on peut rajouter.

#### 8.3.6 Extension exponentielle

Si X=exp(Y) est une exponentielle, on doit résoudre :

∑
j

(Aj′+j Y′Aj) Xj =

∑
j

aj Xj

Ceci va se faire degré par degré :

Aj′+j Y′ Aj = aj (19)

Exemple
Pour calculer ∫a(x) exp(x2), on a j=1, et on doit résoudre l’équation différentielle :

A1′+2xA1= a(x)

Pour j=0, il suffit de faire un appel récursif à l’algorithme de Risch, mais pour j≠ 0, la situation se complique! Notons Z la variable située juste en-dessous de X dans la tour de variables (dans l’exemple ci-dessus Z=x), il s’agit de résoudre :

y′+f y=g (20)

avec f, g élémentaires par rapport à une tour dont le variable au sommet est Z, on cherche y élémentaire par rapport à cette tour (ici f=jY′ est une dérivée mais dans certains cas nous devrons résoudre par appel récursif des équations du type ci-dessus où f ne sera pas une dérivée).

Élimination des dénominateurs
Soit P un facteur irréductible du dénominateur de y, notons α<0 la valuation de y par rapport à P, β celle de f, γ celle de g. Si P n’est pas une exponentielle, la valuation de y′ est α−1, celle de f y est α +β . Si β ≠ −1, il n’y a pas de simplification possible dans le membre de gauche donc α + min(β,−1) =γ. Autrement dit, si β ≥ 0 alors α=γ+1 et si β<−1 alors α=γ−β. On observe que γ<0 donc P est un facteur du dénominateur gd de g. De plus, on va montrer que la valuation α de P dans y est l’opposé de celle de P dans :

D=

gcd(gd,∂Z gd)
gcd(c,∂Z c)

, c=gcd(fd,gd) (21)

En effet, si β ≥ 0, P ne divise pas fd donc ne divise pas c, donc la valuation de P dans D est −γ−1. Si β < −1, alors α=γ − β <0 entraine −γ > −β donc la valuation de P dans c est −β et la valuation de P dans D est −γ−1 − (−β−1).

Si β=−1, s’il n’y a pas de simplifications dans le membre de gauche pour les termes de plus petite puissance en P, alors α=γ+1. S’il y a simplification, on décompose en éléments simples (avec Bézout) puis on ordonne par puissances croissantes de P :

y= N1 Pα+..., f= N2 P−1+...,

avec N1,N2 de degré plus petit que P, puis on remplace dans (20). On cherche les termes de valuation α−1 en P qui doivent se simplifier :

α N1 P′ Pα−1 + N2 P−1 N1 Pα=0

donc :

N2 = −α P′

ce qui détermine α.

Récapitulons
Si f est une dérivée, alors β=−1 est exclus et on peut appliquer (21) pour déterminer D. Si f n’est pas une dérivée, on calcule les facteurs de degré 1 de fd :

f1=

fd
gcd(fd,∂Z fd)

on décompose f par Bézout en isolant la partie N/f1 les α possibles sont alors les racines entières (en t) du résultant en Z de N−tf1′ et f1, ils correspondent aux facteurs gcd(N−α f1′,f1) que l’on retire de fd pour appliquer (21).

Exemple
Reprenons y′+2xy=a(x). Si a(x)=1 (résolution de ∫exp(x2)), ou plus généralement si a(x) est un polynôme, alors D=1. Si a(x)=1/x2, on trouve D=x et on pose y=xz, donc x2(xz′+z)+2x4z=1 soit x3z′+(2x4+1)z=1.

Reste le cas où Z est une exponentielle et P=exp(z). On reprend le même raisonnement, y′ a pour valuation −α<0, fy a pour valuation −β−α, donc si β > 0, α=γ et si β<0, α=γ−β. Si β=0, s’il n’y a pas de simplifications du terme de plus bas degré, on est ramené au cas précédent. Si β=0 et s’il y a simplification des termes de plus bas degré en Z, notons f0 le coefficient constant de f par rapport à Z et yα le coefficient de Zα dans y, on a

yα′ + (α z′ + f0) yα=0

donc :

yα= exp(−α z− | ∫ | f0)

Comme yα est élémentaire et indépendant de Z on en déduit par le théorème de structure de Risch que −α z −∫f0 est combinaison linéaire à coefficients rationnels des logarithmes et des arguments des exponentielles de la tour, de plus le coefficient de z doit être nul pour que yα soit indépendant de Z, ce qui impose la valeur de α (après avoir résolu récursivement le problème d’intégration pour f0)

Majoration du degré du numérateur de y
En multipliant y par D Z−α, puis en réduisant au même dénominateur, on se ramène alors à une équation différentielle à coefficients polynomiaux par rapport à la variable Z dont l’inconnue est un polynôme N :

R N′ + S N = T (22)

On va chercher une majoration sur le degré possible de N puis utiliser l’identité de Bézout pour simplifier cette équation.

On écrit maintenant N=∑k=0n Nk Zk et on remplace, il y a à nouveau trois cas selon le type de Z.

Si Z=x: cas exponentielle rationnelle
Donc Z′=1, le degré de RN′ est r+n−1 (si N est non constant c’est-à-dire si T n’est pas un multiple de S), le degré de SN est s+n. Si r−1≠ s, on en déduit que :

n=t−max(r−1,s)

Si r−1=s, on peut avoir une simplification du terme de plus haut degré s+n (sinon on est dans le cas précédent) si n Rr =Ss d’où on déduit le degré n de N.

Par exemple, pour y′+2xy=T ou pour x3z′+(2x4+1)z=1 on a r=s−1 donc n+s=t, donc pas de solution dans le deuxième cas, dans le premier cas il ne peut y avoir de solutions que si t ≥ s, en particulier il n’y a pas de solution pour t=1, on a donc démontré que ∫exp(x2) n’admet pas de primitive élémentaire.

Si Z=exp(z): cas exponentielle d’exponentielle
Ici les Nk peuvent ne pas être constants, on a :

N′=

n
∑
k=0

(Nk′+kNk z′) Zk

Comme on l’a déjà observé, Nn′+n Nn z′≠ 0, donc le degré de N′ est égal au degré de N. On a donc trois cas :

- si r≠ s, alors n=t−max(r,s)
- si r=s et les termes de plus haut degré du membre de gauche ne se simplifient pas, alors, n=t−r=t−s.
- si r=s et s’il y a simplification, alors :

  Rr(Nn′+nNnz′)+SsNn=0

  donc :

  Nn′ + (

  Ss
  Rr

  +nz′)Nn = 0

  et :

  Nn = C exp(−nz−

  ∫

  Ss
  Rr

  )

  On appelle alors l’algorithme de Risch avec une variable de moins (Ss et Rr ne dépendent plus de Z) pour calculer I=∫Ss/Rr. Il s’agit alors de trouver n tel que l’exponentielle précédente soit élémentaire et indépendante de la variable Z. Le théorème de structure de Risch implique que −nz−∫Ss/Rr est combinaison linéaire à coefficients rationnels des logarithmes et des arguments des exponentielles de autres variables de la tour (jusqu’à z non compris). Ceci permet de déterminer n de manière unique (c’est le coefficient rationnel de ∫Ss/Rr en z).

Si Z=ln(z): exponentielle de logarithme
Ici aussi, les Nk peuvent ne pas être constants, on a :

N′=

n
∑
k=0

(Nk′Zk+kNk

z′
z

Zk−1)

Si Nn n’est pas constant, le terme de plus haut degré de RN′ est Nn′ Rr Zn+r, si Nn est constant, le terme de plus haut degré de RN′ est Rr(nNnz′/z+Nn−1′) Zr−1 qui est non nul (sinon z′/z=CNn−1′ et z=exp(CNn−1) serait une exponentielle). Le terme de plus haut degré de SN est Nn Ss Zn+s.

- Si r<s ou si r=s sans simplifications, alors n=t−s.
- Si r>s+1 ou si r=s+1 sans simplifications, alors deg(N′)=t−r donc n=t−r ou n=t−r+1.
- Si r=s+1, et s’il y a simplifications, alors Nn est constant et :

  Rr(nNnz′/z+Nn−1′)+ Ss Nn = 0

  alors Nn−1=C (−∫Nn Ss/Rr −n Nn ln(z)) doit être élémentaire et indépendante de Z donc ∫Ss/Rr est élémentaire, on détermine n en éliminant le coefficient de Z=ln(z) provenant de ∫Ss/Rr.
- Si r=s, et s’il y a simplification des termes de plus haut degré du membre de gauche, alors Nn′ Rr+Nn Ss=0 donc Nn=exp(−∫Ss/Rr) est élémentaire et indépendante de Z. On peut donc changer d’inconnue N=Nn M sans changer le fait que M est un polynôme de même degré que N. On se ramène alors à une équation du même type

  RM′+(S−R

  Ss
  Rr

  )M=

  T
  Nn

  mais avec s diminué de 1 au moins.

Réduction (algorithme SPDE de Rothstein)
On observe d’abord que si R et S ont un facteur en commun, alors ce facteur divise T car N′ et N sont des polynômes en Z. On peut donc quitte à simplifier par gcd(R,S) se ramener au cas où R et S sont premiers entre eux, il existe donc deux polynômes U et V tels que :

RU+SV=T, deg(V)< deg(R) (23)

En soustrayant (23) de (22), on montre que R divise N−V. Soit H=(N−V)/R. Alors N=RH+V donc

R (RH′+R′H+V′)+SRH+SV= T=RU+SV

donc après simplification par SV et division par R, H vérifie l’équation :

R H′ + (S+R′) H = U − V′

C’est une équation du même type mais avec deg(H)=deg(N)-deg(R) ou H=0 (si N=V). Donc si deg(R)>0, au bout d’un nombre fini d’étapes on doit tomber sur un second membre nul ou des simplifications de R avec S+R′ telles que R simplifié soit constant en Z.

Résolution
Si R est constant par rapport à Z, on simplifie par R et on doit résoudre

N′+SN=T

Si S=0, c’est un problème d’intégration. Supposons donc que S≠ 0. Si S est non constant par rapport à Z ou si Z=x, le degré de N′ est strictement inférieur au degré de SN, on peut donc facilement résoudre. Reste le cas où S=b est constant non nul par rapport à Z et Z est une exponentielle ou un logarithme.

Si Z=exp(z)
On a alors doit alors résoudre

Nk′+ k Nk z′ + b Nk=Tk

c’est une équation différentielle de Risch mais avec une variable de moins.

Si Z=ln(z)
On doit alors résoudre

Nk′+ (k+1) Nk+1

z′
z

+ b Nk =Tk

c’est aussi une équation différentielle de Risch avec une variable de moins.

Exemple
Voyons comment on intègre xn avec n un paramètre par l’algorithme de Risch (cela illustre les possibilités couvertes par l’algorithme mais aussi l’efficacité des méthodes traditionnelles d’intégration lorsqu’elles s’appliquent). On écrit d’abord xn=en ln(x), donc la tour de variables est { x, Z=ln(x), X=en ln(x)}, il s’agit donc d’intégrer X qui est un polynôme généralisé. On cherche donc A1 solution de l’équation différentielle de Risch

A1′+ n /x A1=1

Par rapport à Z=ln(x) la fonction f=n/x est un polynôme, donc on applique le dernier cas ci-dessus, A1 est aussi indépendant de ln(x) et on se ramène à résoudre la même équation mais avec comme variable principale x et non Z. Cette fois, il y a un dénominateur x en f. Si A1 possède un dénominateur, il faut qu’il y ait annulation du terme de plus bas degré en x car le second membre n’a pas de dénominateur, on obtient n+α=0 qui n’a pas de solution, donc A1 est un polynôme en x et l’équation se réécrit en :

xA1′+nA1=x

On majore alors le degré en x de A1 par 1, car il ne peut pas y avoir d’annulation de terme de plus grand degré. Ensuite, on peut appliquer l’algorithme SPDE de Rothstein pour réduire le degré, ou ici conclure à la main, x divise nA1 donc A1=Cx qu’on remplace et C=1/(n+1). Finalement, A1=x/(n+1) et ∫xn=x/(n+1) xn.

### 8.4 Quelques références

- M. Bronstein:
  Symbolic Integration I, Transcendental functions, Springer
- M. Bronstein:
  Integration tutorial,
  `http://www-sop.inria.fr/cafe/Manuel.Bronstein/publications/mb_papers.html`
- J.H. Davenport, Y. Siret, E. Tournier:
  Calcul formel: Systèmes et algorithmes de manipulations algébriques
- R. Risch:
  les références des articles originaux de Risch sont dans le “Integration tutorial” de Bronstein.
- B. Trager:
  PHD thesis MIT, 1984
- On peut lire en clair le code source de l’implémentation en MuPAD (sous Unix, désarchiver le fichier `lib.tar` du répertoire `/usr/local/MuPAD/share/lib` et regarder dans le sous-répertoire `lib/INTLIB`)

## 9 Intégration numérique

Les fractions rationnelles admettent une primitive que l’on calcule en décomposant la fraction avec Bézout comme expliqué précédemment. Mais elles font figure d’exceptions, la plupart des fonctions n’admettent pas de primitives qui s’expriment à l’aide des fonctions usuelles. Pour calculer une intégrale,on revient donc à la définition d’aire sous la courbe, aire que l’on approche, en utilisant par exemple un polynome de Lagrange.

Le principe est donc le suivant : on découpe l’intervalle d’intégration en subdivisions [a,b]=[a,a+h] + [a+h,a+2h]+...[a+(n−1)h,a+nh=b, où h=(b−a)/n est le pas de la subdivision, et sur chaque subdivision, on approche l’aire sous la courbe.

### 9.1 Les rectangles et les trapèzes

Sur une subdivision [α,β], on approche la fonction par un segment. Pour les rectangles, il s’agit d’une horizontale : on peut prendre f(α), f(β) (rectangle à droite et gauche) ou f((α+β)/2) (point milieu), pour les trapèzes on utilise le segment reliant [α,f(α)] à [β,f(β)].

Exemple : calcul de la valeur approchée de ∫01 t3 dt (on en connait la valeur exacte 1/4=0.25) par ces méthodes en subdivisant [0,1] en 10 subdivisions (pas h=1/10), donc α=j/10 et β=(j+1)/10 pour j variant de 0 à 9. Pour les rectangles à gauche, on obtient sur une subdivision f(α)=(j/10)3 que l’on multiplie par la longueur de la subdivision soit h=1/10 :

1
10

9
∑
j=0

(

j
10

)3 =

81
400

= 0.2025

Pour les rectangles à droite, on obtient

1
10

10
∑
j=1

(

j
10

)3 =

121
400

= 0.3025

Pour le point milieu f((α+β)/2)=f((j/10+(j+1)/10)/2)=f(j/10+1/20)

1
10

9
∑
j=0

(

j
10

+

1
20

)3 = 199/800 = 0.24875

Enfin pour les trapèzes, l’aire du trapèze délimité par l’axe des x, les verticales y=α, y=β et les points sur ces verticales d’ordonnées respectives f(α) et f(β) vaut

h

f(α)+f(β)
2

donc

1
10

9
∑
j=0

⎛
⎜
⎜
⎝

(

j
10

)3 +(

j+1
10

)3

⎞
⎟
⎟
⎠

=

101
400

= 0.2525

Dans la somme des trapèzes, on voit que chaque terme apparait deux fois sauf le premier et le dernier.

Plus générallement, les formules sont donc les suivantes :

rectangle gauche

=

h

n−1
∑
j=0

f(a+jh)

(24)

rectangle droit

=

h

n
∑
j=1

f(a+jh)

(25)

point milieu

=

h

n−1
∑
j=0

f(a+jh+

h
2

)

(26)

trapezes

=

h

⎛
⎜
⎜
⎝

f(a)+f(b)
2

+

n−1
∑
j=1

f(a+jh)

⎞
⎟
⎟
⎠

(27)

où h=(b−a)/n est le pas de la subdivision, n le nombre de subdivisions.

On observe sur l’exemple que le point milieu et les trapèzes donnent une bien meilleure précision que les rectangles. Plus généralement, la précision de l’approximation n’est pas la même selon le choix de méthode. Ainsi pour les rectangles à gauche (le résultat est le même à droite), si f est continument dérivable, de dérivée majorée par une constante M1 sur [a,b], en faisant un développement de Taylor de f en α, on obtient

|

∫

β
α

f(t) dt −

∫

β
α

f(α) dt | = |

∫

β
α

f′(θt)(t−α) dt | ≤ M1

∫

β
α

(t−α) dt = M1

(β−α)2
2

Ainsi dans l’exemple, on a M1=3, l’erreur est donc majorée par 0.015 sur une subdivision, donc par 0.15 sur les 10 subdivisions.

Pour le point milieu, on fait le développement en (α+β)/2 à l’ordre 2, en supposant que f est deux fois continument dérivable :

|

∫

β
α

f(t) −

∫

β
α

f(

α+β
2

) |

=

|

∫

β
α

f′(

α+β
2

)(t−

α+β
2

) dt

+

∫

β
α

f′′(θt)
2

(t−

α+β
2

)2 |

≤

M2
2

2

∫

β

α+β
2

(t−

α+β
2

)2 dt

≤

M2

(β−α)3
24

Dans l’exemple, on a M2=6, donc l’erreur sur une subdivision est majorée par 0.25e−3, donc sur 10 subdivisions par 0.25e−2=0.0025.

Pour les trapèzes, la fonction g dont le graphe est le segment reliant [α,f(α)] à [β,f(β)] est f(α)+(t−α)/(β−α)f(β), c’est en fait un polynome de Lagrange, si f est deux fois continument dérivable, on peut donc majorer la différence entre f et g en utilisant (41), on intègre la valeur absolue ce qui donne

|

∫

β
α

f(t) dt −

∫

β
α

g(t) dt | ≤

∫

β
α

|

f′′(ξx)
2

(x−α)(x−β)| ≤ M2

(β−α)3
12

où M2 est un majorant de |f′′| sur [a,b].

Lorsqu’on calcule l’intégrale sur [a,b] par une de ces méthodes, on fait la somme sur n=(b−a)/h subdivisions de longueur β−α=h, on obtient donc une majoration de l’erreur commise sur l’intégrale :

- pour les rectangles à droite ou gauche nM1h2/2=M1 h (b−a)/2
- pour le point milieu M2 h2 (b−a)/24
- pour les trapèzes M2h2 (b−a)/12.

Lorsque h tend vers 0, l’erreur tend vers 0, mais pas à la même vitesse, plus rapidement pour les trapèzes et le point milieu que pour les rectangles. Plus on approche précisément la fonction sur une subdivision, plus la puissance de h va être grande, plus la convergence sera rapide lorsque h sera petit, avec toutefois une contrainte fixée par la valeur de Mk, borne sur la dérivée k-ième de f (plus k est grand, plus Mk est grand en général). Nous allons voir dans la suite comment se comporte cette puissance de h en fonction de la facon dont on approche f.

### 9.2 Ordre d’une méthode

On appelle méthode d’intégration l’écriture d’une approximation de l’intégrale sur une subdivision sous la forme

∫

β
α

f(t) dt ≈ I(f)=

k
∑
j=1

wj f(yj)

où les yj sont dans l’intervalle [α,β], par exemple équirépartis sur [α,β]. On utilise aussi la définition :

∫

β
α

f(t) dt ≈ I(f)= (β−α)

k
∑
j=1

wj f(yj)

On prend toujours ∑j wj=β−α (ou ∑j wj=1) pour que la méthode donne le résultat exact si la fonction est constante.

On dit qu’une méthode d’intégration est d’ordre n si il y a égalité ci-dessus pour tous les polynômes de degré inférieur ou égal à n et non égalité pour un polynôme de degré n+1. Par exemple, les rectangles à droite et gauche sont d’ordre 0, le point milieu et les trapèzes sont d’ordre 1. Plus générallement, si on approche f par son polynôme d’interpolation de Lagrange en n+1 points (donc par un polynôme de degré inférieur ou égal à n), on obtient une méthode d’intégration d’ordre au moins n.

Si une méthode est d’ordre n avec des wj≥ 0 et si f est n+1 fois continument dérivable, alors sur une subdivision, on a :

|

∫

β
α

f−I(f)| ≤ Mn+1

(β−α)n+2
(n+1)!

(

1
n+2

+1) (28)

En effet, on fait le développement de Taylor de f par exemple en α à l’ordre n

f(t)

=

Tn(f)+

(t−α)n+1
(n+1)!

f[n+1](θt),

Tn(f)

=

f(α)+(t−α)f′(α)+...+

(t−α)n
n!

f[n](α)

Donc

|

∫

β
α

f−

∫

β
α

Tn(f)| ≤

∫

β
α

(t−α)n+1
(n+1)!

|f[n+1](θt)| ≤

⎡
⎢
⎢
⎣

Mn+1

(t−α)n+2
(n+2)!

⎤
⎥
⎥
⎦

β
α

De plus,

|I(f) −I(Tn(f))| =|I

⎛
⎜
⎜
⎝

f[n+1](θt)

(t−α)n+1
(n+1)!

⎞
⎟
⎟
⎠

|

≤

k
∑
j=1

|wj| Mn+1

(yj−α)n+1
(n+1)!

≤

k
∑
j=1

|wj| Mn+1

(β−α)n+1
(n+1)!

Donc comme la méthode est exacte pour Tn(f), on en déduit que

|

∫

β
α

f−I(f)|

=

|

∫

β
α

f−

∫

β
α

Tn(f)+I(Tn(f))− I(f)|

≤

|

∫

β
α

f−

∫

β
α

Tn(f)|+|I(Tn(f))− I(f)|

≤

Mn+1

(β−α)n+2
(n+2)!

+

k
∑
j=1

|wj| Mn+1

(β−α)n+1
(n+1)!

Si les wj≥ 0, alors ∑j=1k |wj|=∑j=1k wj=β−α et on obtient finalement (28)

On remarque qu’on peut améliorer la valeur de la constante en faisant tous les développement de Taylor en (α+β)/2 au lieu de α, Après sommation sur les n subdivisions, on obtient que :

Théorème 9 Pour une méthode d’ordre n à coefficients positifs et une fonction f n+1 fois continument dérivable

|

∫

b
a

f−I(f)| ≤ Mn+1

hn+1
2n+1(n+1)!

(b−a) (

1
(n+2)

+1)

On observe que cette majoration a la bonne puissance de h sur les exemples déja traités, mais pas forcément le meilleur coefficient possible, parce que nous avons traité le cas général d’une méthode d’ordre n.

### 9.3 Simpson

Il s’agit de la méthode obtenue en approchant la fonction sur la subdivision [α,β] par son polynome de Lagrange aux points α,(α+β)/2,β. On calcule l’intégrale par exemple avec un logiciel de calcul formel, avec Xcas :

`factor(int(lagrange([a,(a+b)/2,b],[fa,fm,fb]),x=a..b))`

qui donne la formule sur une subdivision

I(f) =

h
6

(f(α)+4f(

α+β
2

) + f(β))

et sur [a,b] :

I(f) =

h
6

⎛
⎜
⎜
⎝

f(a)+f(b)+ 4

n−1
∑
j=0

f(a+jh+

h
2

) + 2

n−1
∑
j=1

f(a+jh)

⎞
⎟
⎟
⎠

(29)

Si on intègre t3 sur [0,1] en 1 subdivision par cette méthode, on obtient

1
6

(0+ 4

1
23

+ 1)=

1
4

c’est-à-dire le résultat exact, ceci est aussi vérifié pour f polynome de degré inférieur ou égal à 2 puisque l’approximation de Lagrange de f est alors égale à f. On en déduit que la méthode de Simpson est d’ordre 3 (pas plus car la méthode de Simpson appliquée à l’intégrale de t4 sur [0,1] n’est pas exacte). On peut même améliorer (cf. par exemple Demailly) la constante générale de la section précédente pour la majoration de l’erreur en :

|

∫

b
a

f − I(f)| ≤

h4
2880

(b−a) M4

Cette méthode nécessite 2n+1 évaluations de f (le calcul de f est un point étant presque toujours l’opération la plus couteuse en temps d’une méthode de quadrature), au lieu de n pour les rectangles et le point milieu et n+1 pour les trapèzes. Mais on a une majoration en h4 au lieu de h2 donc le “rapport qualité-prix” de la méthode de Simpson est meilleur, on l’utilise donc plutot que les méthodes précédentes sauf si f n’a pas la régularité suffisante (ou si M4 est trop grand).

### 9.4 Newton-Cotes

On peut généraliser l’idée précédente, découper la subdivision [α,β] en n parts égales et utiliser le polynôme d’interpolation en ces n+1 points x0=α, x1, ..., xn=β. Ce sont les méthodes de Newton-Cotes, qui sont d’ordre n au moins. Comme le polynôme d’interpolation dépend linéairement des ordonnées, cette méthode est bien de la forme :

I(f)=(β−α)

n
∑
j=0

wj f(xj)

De plus les wj sont universels (ils ne dépendent pas de la subdivision), parce qu’on peut faire le changement de variables x=α+t(β−α) dans l’intégrale et le polynôme d’interpolation et donc se ramener à [0,1].

Exemple : on prend le polynôme d’interpolation en 5 points équidistribués sur une subdivision [a,b] (méthode de Boole). Pour calculer les wj, on se ramène à [0,1], puis on tape

`int(lagrange(seq(j/4,j,0,4),[f0,f1,f2,f3,f4]),x=0..1)`

et on lit les coefficients de `f0` à `f4` qui sont les w0 à w4: 7/90, 32/90, 12/90, 32/90, 7/90. La méthode est d’ordre au moins 4 par construction, mais on vérifie qu’elle est en fait d’ordre 5 (exercice), la majoration de l’erreur d’une méthode d’ordre 5 est

|

∫

b
a

f −I(f)| ≤

M6
26 6!

(1+

1
7

) h6 (b−a)

elle peut être améliorée pour cette méthode précise en

|

∫

b
a

f −I(f)| ≤

M6
1935360

h6 (b−a)

En pratique, on ne les utilise pas très souvent, car d’une part pour n≥ 8, les wj ne sont pas tous positifs, et d’autre part, parce que la constante Mn devient trop grande. On préfère utiliser la méthode de Simpson en utilisant un pas plus petit.

Il existe aussi d’autres méthodes, par exemple les quadratures de Gauss (on choisit d’interpoler en utilisant des points non équirépartis tels que l’ordre de la méthode soit le plus grand possible) ou la méthode de Romberg qui est une méthode d’accélération de convergence basée sur la méthode des trapèzes (on prend la méthode des trapèzes en 1 subdivision de [a,b], puis 2, puis 22, ..., et on élimine les puissances de h du reste ∫f−I(f) en utilisant un théorème d’Euler-Mac Laurin qui montre que le développement asymptotique de l’erreur en fonction de h ne contient que des puissances paires de h). De plus, on peut être amené à faire varier le pas h en fonction de la plus ou moins grande régularité de la fonction.

### 9.5 En résumé

Intégration sur [a,b], h pas d’une subdivision, Mk majorant de la dérivée k-ième de la fonction sur [a,b]

| formule | Lagrange degré | ordre | erreur
rectangles | (24), (25) | 0 | 0 | M1 h (b−a)/2
point milieu | (26) | 0 | 1 | M2 h2 (b−a)/24
trapèzes | (27) | 1 | 1 | M2 h2 (b−a)/12
Simpson | (29) | 2 | 3 | M4 h4 (b−a)/2880

## 10 Algèbre linéaire

On présente ici des algorithmes autour de la résolution exacte de systèmes (réduction des matrices sous forme échelonnée) et la recherche de valeurs propres et de vecteurs propres (diagonalisation et jordanisation des matrices).

### 10.1 Résolution de systèmes, calcul de déterminant.

#### 10.1.1 La méthode du pivot de Gauß.

- Le pivot : on détermine à partir d’une ligne i la ligne j où apparait le premier coefficient non nul p dans la colonne à réduire. On échange les lignes i et j. Puis pour j>i (réduction sous-diagonale) ou j≠ i (réduction complète), on effectue l’opération Lj ← Lj − pj/p Li.
  Inconvénient : avec des données exactes de taille non bornée, la complexité des coefficients augmente plus vite qu’en choisissant le pivot le plus simple possible, (remarque, lorsque les données sont approchées, on n’utilise pas non plus cette méthode pour des raisons de stabilité numérique). Le domaine d’utilisation naturel concerne donc les coefficients dans un corps fini (par exemple ℤ/nℤ).
- Le pivot partiel. On choisit le meilleur coefficient non nul de la colonne, où meilleur dépend du type de coefficient : avec des données exactes, on choisirait le coefficient de taille la plus petite possible, avec des données approximatives, on choisit le coefficient de plus grande norme dans la colonne. Le domaine d’utilisation naturel concerne les coefficients approchés. Pour les coefficients exacts, on remplacerait la réduction par Lj ← pLj −pj Li pour ne pas effectuer de division. Mais avec cette méthode, la taille des coefficients augmente de manière exponentielle. On peut améliorer la taille des coefficients intermédiaires en divisant chaque ligne par le PGCD de ses coefficients, mais comme pour le calcul du PGCD par l’algorithme du sous-résultant, il existe une méthode plus efficace présentée ci-dessous.
- La méthode de Bareiss : on initialise un coefficient b à 1. On remplace l’étape de réduction ci-dessus par Lj ← (pLj −pj Li)/b. À la fin de l’étape de réduction, on met le coefficient b à la valeur du pivot p. L’intérêt de la méthode est que la division se fait sans introduire de fraction (la preuve pour les deux premières étapes se fait facilement à la main ou avec un système de calcul formel (cf. infra), pour le cas général, on vérifie que le déterminant de la matrice de départ est égal au dernier coefficient sur la diagonale obtenu par cette méthode de réduction, ce dernier est donc entier, le même raisonnement fait sur des sous-matrices dont on prend les k premières lignes et colonnes et une autre ligne et une autre colonne montre que tous les coefficients des matrices intermédiaires sont entiers). On peut utiliser cette méthode aussi bien pour la réduction sous-diagonale que pour la réduction complète (les lignes intervenant dans la combinaison linéaire subissent des modifications identiques dans les deux cas).

Montrons avec MuPAD ou xcas en mode mupad (commande `maple_mode(2)`) qu’en effet, on n’introduit pas de dénominateur dans la méthode de Bareiss. Sans restreindre la généralité, il suffit de le montrer avec une matrice 3x3 à coefficients symboliques génériques.

    pivot:=proc (M,n,m,r) // n ligne du pivot, m colonne, r ligne a modifier
          local col,i,a,b;
           begin
             col:=ncols(M);
             a:=M[n,m];
             b:=M[r,m];
             for i from 1 to col do
               // print(i,a,b,n,m,r);
               M[r,i]:=a*M[r,i]-b*M[n,i];
             end_for;
             return(M);
           end_proc; /* End of pivot */
    A:=matrix(3,3,[[a,b,c],[d,e,f],[g,h,j]]);
    A:=pivot(A,1,1,2); A:=pivot(A,1,1,3); /* reduction 1ere colonne */
    A:=pivot(A,2,2,3); A:=pivot(A,2,2,1); /* reduction 2eme colonne */
    factor(A[3,3]);

Ce qui met bien en évidence le facteur a dans A3,3.

#### 10.1.2 Le déterminant.

On peut bien sûr appliquer les méthodes ci-dessus en tenant compte des pivots utilisés et du produit des coefficients diagonaux. Dans le cas de la méthode de Bareiss, si on effectue la réduction sous-diagonale uniquement, il n’est pas nécessaire de garder une trace des pivots et de calculer le produit des coefficients diagonaux, montrons que la valeur du déterminant est égal au dernier coefficient diagonal : en effet si R désigne la matrice réduite et que l’on pose R0,0=1, alors la réduction par la méthode de Bareiss de la colonne i a pour effet de multiplier le déterminant de la matrice initiale M par (Ri,i/(Ri−1,i−1)n−i. Donc :

det(R)

=

det(M)

n−1
∏
i=1

(Ri,i/(Ri−1,i−1)n−i

n
∏
i=1

Ri,i

=

det(M)

n−1
∏
i=1

Ri,i

Rn,n | = | det(M)

Pour les matrices à coefficients entiers, on peut aussi utiliser une méthode modulaire : on calcule une borne à priori sur le déterminant et on calcule le déterminant modulo suffisamment de petits nombres premiers pour le reconstruire par les restes chinois. L’avantage de cet algorithme est qu’il est facile à paralléliser.

On utilise souvent la borne d’Hadamard sur le déterminant :

|det(M)| ≤

∏
1≤ i ≤ n

√

∑
1≤ j ≤ n

|mi,j|2

Preuve de la borne : on majore le déterminant par le produit des normes des vecteurs colonnes de M.

Remarque :
Si on veut juste prouver l’inversibilité d’une matrice à coefficients entiers, il suffit de trouver un nombre premier p tel que le déterminant de cette matrice modulo p soit non nul.

Développement par rapport à une ligne ou une colonne
On a tendance à oublier ce type de méthode car le développement complet du déterminant (faisant intervenir une somme sur toutes les permutations du groupe symétrique) nécessite d’effectuer n! produits de n coefficients et n! additions ce qui est gigantesque. Or on peut "factoriser" une partie des calculs et se ramener à n.2n opérations élémentaires au lieu de n.n!. Remarquons aussi que le nombre d’opérations élémentaires n’a guère de sens si on ne tient pas compte de la complexité des expressions, l’avantage principal de la méthode de développement étant d’éviter d’effectuer des divisions.

Calcul du déterminant par développement de Laplace
On calcule d’abord tous les mineurs 2x2 des colonnes 1 et 2 que l’on place dans une table de mineurs, puis on calcule les mineurs 3x3 des colonnes 1 à 3 en développant par rapport à la colonne 3 et en utilisant les mineurs précédents, puis les mineurs 4x4 avec les mineurs 3x3, etc.. On évite ainsi de recalculer plusieurs fois les mêmes mineurs. Cf. par exemple l’implémentation en C++ dans giac/xcas (`www-fourier.ujf-grenoble.fr/~parisse/giac.html`) qui utilise le type générique `map<>` de la librairie standard C++ (STL) pour stocker les tables de mineurs (fonction `det_minor` du fichier `vecteur.cc`).
Nombre d’opérations élémentaires : il y a (2n) mineurs d’ordre 2 à calculer nécessitant chacun 2 multiplications (et 1 addition), puis (3n) mineurs d’ordre 3 nécessitant 3 multiplications et 2 additions, etc. donc le nombre de multiplications est de 2(2n)+3(3n)+...+n(nn), celui d’additions est (2n)+2(3n)+...+(n−1)(nn) soit un nombre d’opérations élémentaires majoré par n.2n.

On observe "expérimentalement" que cet algorithme est intéressant lorsque le nombre de paramètres dans le déterminant est grand et que la matrice est plutôt creuse (majorité de coefficients nuls). Il existe des heuristiques de permutation des lignes ou des colonnes visant à optimiser la position des zéros (par exemple, les auteurs de GiNaC (`www.ginac.de`) suite à des expérimentations privilégient la simplification des petits mineurs en mettant les colonnes contenant le maximum de zéros à gauche selon la description faite ici).

Pour se convaincre de l’intérêt de cet algorithme, on peut effectuer le test O1 de Lewis-Wester
`http://www.bway.net/~lewis/calatex.html`
il s’agit de calculer un déterminant de taille 15 avec 18 paramètres.

#### 10.1.3 Systèmes linéaires

On peut appliquer la méthode du pivot de Gauß ou les règles de Cramer. Pour les systèmes à coefficients entiers non singuliers, on peut aussi utiliser une méthode p-adique asymptotiquement plus efficace. On calcule d’abord une borne sur les coefficients des fractions solutions de l’équation Ax=b en utilisant les règles de Cramer et la borne d’Hadamard. On calcule ensuite C, l’inverse de A modulo p (en changeant de p si A n’est pas inversible modulo p), puis, si

x=

∑
i

xi pi, A(

∑
i<k

xi pi)=b (mod pk )

on ajoute xk pk et on obtient l’équation :

Axk =

b−

∑
i <k

xi pi

pk

(mod p )

qui détermine xk. On s’arrête lorsque k est suffisamment grand pour pouvoir reconstruire les fractions à l’aide de l’identité de Bézout (cf. l’appendice), ce qui est le cas si pk est supérieur à 4 fois la borne de Hadamard de A au carré. Pour éviter de recalculer plusieurs fois b−∑i <k xi pi, on utilise la récurrence suivante

y0=b, xk=Cyk (mod p ), yk+1 =

yk−Axk
p

Pour une matrice de taille n, il faut O(n3) opérations pour calculer C, puis kn2 ln(n) opérations pour calculer xk (le terme ln(n) vient de la taille des coefficients de yk dans le produit Cyk), donc pour pouvoir reconstruire x, il faut prendre k de l’ordre de nln(n), ce qui nécessite finalement O(n3ln(n)2) opérations.

Application au calcul de déterminant de matrices à coefficient entiers
Cette méthode p-adique peut servir à accélérer le calcul du déterminant d’une matrice à coefficients entiers de grande taille. En effet, le PPCM f des dénominateurs des composantes de x est un diviseur du déterminant, et si b est choisi avec des coefficients aléatoires, on a une forte probabilité d’obtenir le dernier facteur invariant de la matrice A. Comme le déterminant de A a une très faible probabilité de contenir un gros facteur carré, ce dernier facteur invariant est très proche du déterminant. Ce dernier est pour une matrice A aléatoire lui-même à un facteur de l’ordre de (2/π)n proche de la borne de Hadamard. Il suffit donc de très peu de nombres premiers pour déterminer det(A)/f par le théorème des restes chinois. En pratique pour des n de l’ordre de 100 à 1000, cet algorithme est plus rapide que le calcul uniquement par les restes chinois. Pour des n plus grands, il faut se rabattre sur des algorithmes probabilistes avec arrêt prématuré pour être plus rapide (on s’arrête lorsque le déterminant n’évolue plus par reconstruction par les restes chinois pour plusieurs nombres premiers successifs), et également utiliser des méthodes d’inversion ou de réduction de type Strassen.

#### 10.1.4 Bézout et les p-adiques.

Soit n et a/b une fraction irréductible d’entiers tels que b est premier avec n et |a| < √n/2 et 0 ≤ b ≤ √n/2. Il s’agit de reconstruire a et b connaissant x=a × (b−1) (mod n ) avec x∈ [0,n[.

Unicité
S’il existe une solution (a,b) vérifiant |a| < √n/2 et 0 ≤ b ≤ √n/2, soit (a′,b′) une solution de x=a × (b−1) (mod n ) et vérifiant |a′| < √n et 0 ≤ b′ ≤ √n, alors :

a b′=a′ b (mod n )

Comme |ab′| < n/2, |a′b| <n/2, on en déduit que ab′=a′b. Donc a/b=a′/b′ donc a=a′ et b=b′ car a/b et a′/b′ sont supposées irréductibles.

Reconstruction lorsqu’on sait qu’il y a une solution
On suit l’algorithme de calcul des coefficients de Bézout pour les entiers n et x. On pose :

αk n + βk x= rk

où les rk sont les restes successifs de l’algorithme d’Euclide, avec la condition initiale :

α0=1, β0=0, α1=0, β1=1, r0=n, r1=x

et la relation de récurrence :

βk+2=βk − qk+2 βk+1, qk+2=

rk−rk+2
rk+1

On a βk x= rk (mod n ) pour tout rang mais il faut vérifier les conditions de taille sur βk et rk pour trouver le couple (a,b). Montrons par récurrence que :

βk+1 rk − rk+1 βk = (−1)k n (30)

Au rang k=0, on vérifie l’égalité, on l’admet au rang k, alors au rang k+1, on a :

βk+2 rk+1 − rk+2 βk+1 | = | βk rk+1 − qk+2 rk+1 βk+1 − rk+2 βk+1
| = | βk rk+1 − (rk−rk+2) βk+1 − rk+2 βk+1
| = | βk rk+1 − rk βk+1
| = | − (−1)k n

On vérifie aussi que le signe de βk est positif si k est impair et négatif si k est pair, on déduit donc de (30) :

|βk+1| rk < n

(avec égalité si rk+1=0)

Considérons la taille des restes successifs, il existe un rang k tel que rk ≥ √n et rk+1<√n. On a alors |βk+1| < n/rk ≤ √n.

Donc l’algorithme de Bézout permet de reconstruire l’unique couple solution s’il existe.

Exemple
On prend n=101, a=2, b=3, a/b=68 (mod 101 ). Puis on effectue Bézout pour 68 et 101 en affichant les étapes intermédiaires (par exemple avec `IEGCD` sur une HP49 ou exercice avec votre système de calcul formel) :

       = alpha*101+beta*68
    101    1        0
     68    0        1  L1 - 1*L2
     33    1       -1  L2 - 2*L3
      2   -2        3  ...

On s’arrête à la première ligne telle que le coefficient de la 1ère colonne est inférieur à √101, on retrouve bien 2 et 3. Quand on programme l’algorithme de reconstruction, on ne calcule bien sûr pas la colonne des α, ce qui donne par exemple le programme xcas ou mupad suivant :

    // Renvoie a/b tel que a/b=x mod n et |a|,|b|<sqrt(n)
    padictofrac:=proc (n,x)
      local r0,beta0,r1,beta1,r2,q2,beta2;
    begin
      r0:=n;
      beta0:=0;
      r1:=x;
      beta1:=1;
      sqrtn:=float(sqrt(n));
      while r1>sqrtn do
        r2:= irem(r0,r1);
        q2:=(r0-r2)/r1;
        beta2:=beta0-q2*beta1;
        beta0:=beta1; r0:=r1; beta1:=beta2; r1:=r2;
      end_while;
      return(r1/beta1);
    end_proc;

#### 10.1.5 Base du noyau

On présente ici deux méthodes, la première se généralise au cas des systèmes à coefficients entiers, la deuxième utilise un peu moins de mémoire (elle travaille sur une matrice 2 fois plus petite).

Première méthode Soir M la matrice dont on cherche le noyau. On ajoute à droite de la matrice transposée de M une matrice identité ayant le même nombre de lignes que Mt. On effectue une réduction sous-diagonale qui nous amène à une matrice composée de deux blocs

( Mt In ) → ( U L )

Attention, L n’est pas la matrice L de la décomposition LU de Mt, on a en fait

L Mt = U

donc

M Lt = Ut

Les colonnes de Lt correspondant aux colonnes nulles de Ut (ou si on préfère les lignes de L correspondant aux lignes nulles de U) sont donc dans le noyau de M et réciproquement si Mv=0 alors

Ut (Lt)−1 v =0

donc, comme U est réduite, (Lt)−1 v est une combinaison linéaire des vecteurs de base d’indice les lignes nulles de U. Finalement, les lignes de L correspondant aux lignes nulles de U forment une base du noyau de M.

On peut faire le raisonnement ci-dessus à l’identique si M est une matrice à coefficients entiers, en effectuant des manipulations élémentaires réversibles dans ℤ, grâce à l’idendité de Bézout. Si a est le pivot en ligne i, b le coefficient en ligne j à annuler, et u, v, d les coefficients de l’identité de Bézout a u + b v =d on fait les changements :

Li ← uLi +v Lj, Lj ← −

b
d

Li +

a
d

Lj

qui est réversible dans ℤ car le déterminant de la sous-matrice élémentaire correspondante est

⎪
⎪
⎪
⎪
⎪
⎪

u | v

−

b
d

a
d

⎪
⎪
⎪
⎪
⎪
⎪

= 1

Cette réduction (dite de Hermite) permet de trouver une base du noyau à coefficients entiers et telle que tout élément du noyau à coefficient entier s’écrit comme combinaison linéaire à coefficients entiers des éléments de la base.

Deuxième méthode On commence bien sûr par réduire la matrice (réduction complète en-dehors de la diagonale), et on divise chaque ligne par son premier coefficient non nul (appelé pivot). On insère alors des lignes de 0 pour que les pivots (non nuls) se trouvent sur la diagonale. Puis en fin de matrice, on ajoute ou on supprime des lignes de 0 pour avoir une matrice carrée de dimension le nombre de colonnes de la matrice de départ. On parcourt alors la matrice en diagonale. Si le i-ième coefficient est non nul, on passe au suivant. S’il est nul, alors tous les coefficients d’indice supérieur ou égal à i du i-ième vecteur colonne vi sont nuls (mais pas forcément pour les indices inférieurs à i). Si on remplace le i-ième coefficient de vi par -1, il est facile de se convaincre que c’est un vecteur du noyau, on le rajoute donc à la base du noyau. On voit facilement que tous les vecteurs de ce type forment une famille libre de la bonne taille, c’est donc bien une base du noyau.

### 10.2 Réduction des endomorphismes

#### 10.2.1 Le polynôme minimal

On prend un vecteur v au hasard et on calcule la relation linéaire de degré minimal entre v, Av, ..., Anv en cherchant le premier vecteur w du noyau de la matrice obtenue en écrivant les vecteurs v, Av, etc. en colonne dans cet ordre. Les coordonnées de w donnent alors par ordre de degré croissant un polynôme P de degré minimal tel que P(A)v=0 donc P divise le polynôme minimal M. Donc si P est de degré n, P=M. Sinon, il faut vérifier que le polynôme obtenu annule la matrice A. On peut aussi calculer en parallèle le polynôme P précédent pour quelques vecteurs aléatoires et prendre le PPCM des polynômes obtenus.

Exemple 1
Polynôme minimal de (

1 | −1
2 | 4

) . On prend v=(1,0), la matrice à réduire est alors :

⎛
⎜
⎝

1 | −1 | −11
2 | 10 | 38

⎞
⎟
⎠

→

⎛
⎜
⎝

1 | 0 | −6
0 | 1 | 5

⎞
⎟
⎠

Le noyau est engendré par (−6,5,−1) donc P=−x2+5x−6.

Exemple 2

A=

⎛
⎜
⎜
⎝

3 | 2 | −2
−1 | 0 | 1
1 | 1 | 0

⎞
⎟
⎟
⎠

en prenant v=(1,0,0) on obtient la matrice :

A=

⎛
⎜
⎜
⎝

1 | 3 | 5 | 7
0 | −1 | −2 | −3
0 | 1 | 2 | 3

⎞
⎟
⎟
⎠

→

⎛
⎜
⎜
⎝

1 | 0 | −1 | −2
0 | 1 | 2 | 3
0 | 0 | 0 | 0

⎞
⎟
⎟
⎠

le permier vecteur du noyau est (−1,2,−1) d’où un polynôme divisant le polynôme minimal −x2+2x−1.

#### 10.2.2 Le polynôme caractéristique

Pour une matrice générique, le polynôme caractéristique est égal au polynôme minimal, il est donc intéressant de chercher si le polynôme annulateur de A sur un vecteur aléatoire est de degré n, car le temps de calcul du polynôme caractéristique est alors en O(n3). Si cette méthode probabiliste échoue, on se rabat sur une des méthode déterministe ci-dessous:

- on utilise la formule det(λ I −A) déterminé par une des méthodes de calcul de déterminant ci-dessus. Cela nécessite O(n3) opérations mais avec des coefficients polynômes en λ.
- on fait une interpolation de Lagrange en donnant n+1 valeurs distinctes à λ. Ce qui nécessite O(n4) opérations mais avec des coefficients indépendants de λ, de plus cette méthode est facile à programmer de manière parallèle.
- si la matrice est à coefficients entiers on peut utiliser la méthode de Hessenberg (voir ci-dessous), on calcule une borne à priori sur les coefficients du polynôme caractéristique (cf. Cohen p.58-59) :

  |Pk| ≤

  ⎛
  ⎜
  ⎝

  n
  n−k

  ⎞
  ⎟
  ⎠

  (n−k)(n−k)/2 |M|n−k ,

  on calcule le polynôme caractéristique modulo suffisamment de petits entiers puis on remonte par les restes chinois.

#### 10.2.3 La méthode de Hessenberg

Pour les matrices à coefficients de taille bornée (modulaires par exemple) on préfère la méthode de Hessenberg qui est plus efficace, car elle nécessite de l’ordre de n3 opérations sur les coefficients.

On se raméne d’abord à une matrice triangulaire supérieure à une diagonale près qui est semblable à la matrice de départ puis on applique une formule de récurrence pour calculer les coefficients du polynôme caractéristique.

Algorithme de réduction de Hessenberg:
Dans une colonne m donnée de la matrice H, on cherche à partir de la ligne m+1 un coefficient non nul. S’il n’y en a pas on passe à la colonne suivante. S’il y en a un en ligne i, on échange les lignes m+1 et i et les colonnes m+1 et i. Ensuite pour tout i≥ m+2, soit u=Hi,m/Hm+1,m, on remplace alors la ligne Li de H par Li−uLm+1 et la colonne Cm+1 par Cm+1+uCi ce qui revient “à remplacer le vecteur em+1 de la base par le vecteur em+1+uei” ou plus précisément à multiplier à gauche par (

1 | 0
−u | 1

) et à droite par la matrice inverse (

1 | 0
u | 1

) (en utilisant les lignes et colonnes m+1 et i au lieu de 1 et 2 pour ces matrices). Ceci a pour effet d’annuler le coefficient Hi,m dans la nouvelle matrice.

On obtient ainsi en O(n3) opérations une matrice H′ semblable à H de la forme :

⎛
⎜
⎜
⎜
⎜
⎜
⎜
⎝

H′1,1 | H′1,2 | ... | H′1,n−2 | H′1,n−1 | H′1,n
H′2,1 | H′2,2 | ... | H′2,n−2 | H′2,n−1 | H′2,n
0 | H′3,2 | ... | H′3,n−2 | H′3,n−1 | H′3,n
0 | 0 | ... | H′4,n−2 | H′4,n−1 | H′4,n
⋮ | ⋮ | ... | ⋮ | ⋮ | ⋮
0 | 0 | ... | 0 | H′n,n−1 | H′n,n

⎞
⎟
⎟
⎟
⎟
⎟
⎟
⎠

On calcule alors le polynôme caractéristique de H′ par une récurrence qui s’obtient en développant le déterminant par rapport à la dernière colonne :

hn(λ) = det(λ In−H) | = | (λ−H′n,n) hn−1(λ) −(−H′n−1,n) (−H′n,n−1) hn−2(λ) +
|  | + (−H′n−2,n) (−H′n,n−1) (−H′n−1,n−2) hn−3(λ) − ...

où les hi s’entendent en gardant les i premières lignes/colonnes de H′. On peut écrire cette formule pour m≤ n :

hm(λ)= (λ − H′m,m) hm−1(λ) −

m−1
∑
i=1

H′m−i,m

i−1
∏
j=1

H′m−j+1,m−j hi−1(λ)

Pour effectuer cette récurrence de manière efficace, on conserve les hm(λ) dans un tableau de polynômes et on utilise une variable produit contenant successivement les ∏H′m−j+1,m−j.

#### 10.2.4 La méthode de Leverrier-Faddeev-Souriau

Cette méthode permet le calcul simultané des coefficients pi (i=0..n) du polynôme caractéristique P(λ)=det(λ I−A) et des coefficients matriciels Bi (i=0..n−1) du polynôme en λ donnant la matrice adjointe (ou comatrice) B(λ) de λ I −A :

(λ I −A)B(λ)=(λ I −A)

∑
k≤ n−1

Bk λk = (

∑
k≤ n

pk λk)I =P(λ)I (31)

Remarquons que cette équation donne une démonstration assez simple de Cayley-Hamilton puisque le reste de la division euclidienne du polynôme P(λ)I par λ I −A est P(A).

Pour déterminer simultanément les pk et Bk, on a les relations de récurrence :

Bn−1=pn I=I, Bk−ABk+1=pk+1 I (32)

Il nous manque une relation entre les pk et Bk pour pouvoir faire le calcul par valeurs décroissantes de k, on va montrer le :

Théorème 10 La dérivée du polynôme caractéristique P′(λ), est égale à la trace de la matrice adjointe de λ I−A

tr(B)=P′(λ)

Le théorème nous donne tr(Bk) = (k+1)pk+1 . Si on prend la trace de (32), on a :

tr(Bn−1)=n pn, (k+1)pk+1 −tr(ABk+1) =npk+1

donc on calcule pk+1 en fonction de Bk+1 puis Bk :

pk+1=

tr(ABk+1)
k+1−n

, Bk=ABk+1+pk+1 I

Démonstration du théorème:
Soient V1(λ),...Vn(λ) les vecteurs colonnes de λ I−A et bi,j(λ) les coefficients de B, on a :

P′(λ0) | = | det(V1(λ),V2(λ),...,Vn(λ) )′ |λ=λ0
| = | det(V′1(λ0),V2(λ0),...,Vn(λ0) )+ det(V1(λ0),V′2(λ0),...,Vn(λ0) )+
|  | +...+det(V1(λ0),V2(λ0),...,V′n(λ0) )

Il suffit alors de remarquer que V′i(λ0) est le i-ième vecteur de la base canonique donc :

det(V1(λ0),V2(λ0),...,V′i(λ0),...,Vn(λ0) ) =bi,i(λ0)

Finalement :

P′(λ0)=

n
∑
i=1

bi,i(λ0)=tr (B(λ0))

Remarque :
En réindexant les coefficients de P et B de la manière suivante :

P(λ) | = | λn+p1λn−1+p2λn−2...+pn
B(λ) | = | λn−1I+λn−2B1+...+Bn−1

on a montré que :

⎧
⎪
⎪
⎪
⎪
⎨
⎪
⎪
⎪
⎪
⎩

A1=A, | p1=−tr(A), | B1=A1+p1I

A2=AB1,

p2=−

1
2

tr(A2),

B2=A2+p2I

⋮ | ⋮ | ⋮

Ak=ABk−1,

pk=−

1
k

tr(Ak),

Bk=Ak+pkI

On peut alors vérifier que Bn=An+pnI=0. D’où ce petit programme à utiliser avec xcas en mode mupad (`maple_mode(2);`), ou avec MuPAD, ou à adapter avec un autre système :

    iequalj:=(j,k)->if j=k then return(1); else return(0); end_if;
    faddeev:=proc(A) // renvoie la liste des matrices B et le polynome P
    local Aj,AAj,Id,coef,n,pcara,lmat;
    begin
     n:=ncols(A);
     Id:=matrix(n,n,iequalj);     // matrice identite
     Aj:=Id;
     lmat:=[];                    // B initialise a liste vide
     pcara:=[1];                  // coefficient de plus grand degre de P
     for j from 1 to n do
      lmat:=append(lmat,Aj);      // rajoute Aj a la liste de matrices
      AAj:=Aj*A;
      coef:=-trace(AAj)/j;        // mupad linalg::tr
      pcara:=append(pcara,coef);  // rajoute coef au polynome caracteristique
      Aj:=AAj+coef*Id;
     end_for;
     lmat,pcara;                  // resultat
    end_proc;

#### 10.2.5 Les vecteurs propres simples.

On suppose ici qu’on peut factoriser le polynôme caractéristique (ou calculer dans une extension algébrique d’un corps). Lorsqu’on a une valeur propre simple λ0, en écrivant la relation (A−λ0 I)B(λ0)=P(λ0)I=0, on voit que les vecteurs colonnes de la matrice B(λ0) sont vecteurs propres. Remarquer que B(λ0) ≠ 0 sinon on pourrait factoriser λ−λ0 dans B(λ) et apres simplifications on aurait :

(A−λ0 I)

B
λ−λ0

(λ0)=

P
λ−λ0

(λ0)I

or le 2ème membre est inversible en λ0 ce qui n’est pas le cas du premier. Pour avoir une base des vecteurs propres associés à λ0, on calcule B(λ0) par la méthode de Horner appliquée au polynôme B(λ) en λ=λ0, et on réduit en colonnes la matrice obtenue.

#### 10.2.6 La forme normale de Jordan

Pour les valeurs propres de multiplicité plus grande que 1, on souhaiterait généraliser la méthode ci-dessus pour obtenir une base de l’espace caractéristique, sous forme de cycles de Jordan. Soit λ i, ni les valeurs propres comptées avec leur multiplicité. On fait un développement de Taylor en λ i:

−P(λ )I

=

(A−λ I)

⎛
⎜
⎜
⎝

B(λi )+ B′(λ i)(λ −λ i) + ... +

B(n−1)(λi )
(n−1)!

(λ −λ i)n−1

⎞
⎟
⎟
⎠

=

−(λ −λ i)ni

∏
j≠ i

(λ −λ j)nj I

Comme A−λ I=A−λ i I − (λ −λ i)I, on obtient pour les ni premières puissances de λ −λ i:

(A−λ i I) B(λ i) | = | 0 | (33)
(A−λ i I) B′(λ i) | = | B(λi ) | (34)
| ... |  | (35)

(A−λ i I)

B(ni−1)(λ i)
(ni−1)!

=

B(ni−2)(λ i)
(ni−2)!

(36)

(A−λ i I)

B(ni)(λi)
ni!

−

B(ni−1)(λi)
(ni−1)!

=

−

∏
j≠ i

(λ i−λ j)nj I

(37)

Le calcul des matrices B(n)(λ i)/n! pour n<ni se fait en appliquant ni fois l’algorithme de Horner (avec reste).

Théorème 11 L’espace caractéristique de λ i est égal à l’image de B(ni−1)(λ i)/(ni−1)!.

Preuve :
On montre d’abord que ImB(ni−1)(λ i)/(ni−1)! est inclus dans l’espace caractéristique correspondant à λi en appliquant l’équation (36) et les équations précédentes. Réciproquement on veut prouver que tout vecteur caractéristique v est dans l’image de B(ni−1)(λ i)/(ni−1)!. Prouvons le par récurrence sur le plus petit entier m tel que (A−λ i)mv=0. Le cas m=0 est clair puisque v=0. Supposons le cas m vrai, prouvons le cas m+1. On applique l’équation (37) à v, il suffit alors de prouver que

w=(A−λ i)

B(ni)(λi)
ni!

v

appartient à l’image de B(ni−1)(λ i)/(ni−1)!. Comme B(ni)(λi) commute avec A (car c’est un polynôme en A ou en appliquant le fait que B(λ) inverse de A−λ I):

(A−λ i)m w=

B(ni)(λi)
ni!

(A−λ i)m+1v=0

et on applique l’hypothèse de récurrence à w.

Pour calculer les cycles de Jordan, nous allons effectuer une réduction par le pivot de Gauß simultanément sur les colonnes des matrices B(k)(λ i)/k! où k<ni. La simultanéité a pour but de conserver les relations (33) à (36) pour les matrices réduites. Pour visualiser l’algorithme, on se représente les matrices les unes au-dessus des autres, colonnes alignées. On commence par réduire la matrice B(λ i) jusqu’à ce que l’on obtienne une matrice réduite en recopiant les opérations élémentaires de colonnes faites sur B(λ i) sur toutes les matrices B(k)(λ i)/k!. On va continuer avec la liste des matrices réduites issues de B′(λ i), ..., B(ni−1)(λ i)/(ni−1)!, mais en déplacant les colonnes non nulles de B(λ i) d’une matrice vers le bas (pour une colonne non nulle de la matrice réduite B(λ ) les colonnes correspondantes de B(k)(λ i) réduite sont remplacées par les colonnes correspondantes de B(k−1)(λ i) réduite pour k décroissant de ni−1 vers 1). À chaque étape, on obtient une famille (éventuellement vide) de cycles de Jordan, ce sont les vecteurs colonnes correspondants aux colonnes non nulles de la matrice réduite du haut de la colonne. On élimine bien sûr les colonnes correspondant aux fins de cycles déjà trouvés.

Par exemple, si B(λ i)≠ 0, son rang est 1 et on a une colonne non nulle, et un cycle de Jordan de longueur ni fait des ni vecteurs colonnes des matrices B(k)(λ i)/k! réduites. Plus généralement, on obtiendra plus qu’un cycle de Jordan (et dans ce cas B(λ i)= 0).

#### 10.2.7 Exemple 1

A=

⎛
⎜
⎜
⎝

3 | −1 | 1
2 | 0 | 1
1 | −1 | 2

⎞
⎟
⎟
⎠

λ =2 est valeur propre de multiplicité 2, on obtient :

B(λ )= λ 2 I + λ

⎛
⎜
⎜
⎝

−2 | −1 | 1
2 | −5 | 1
1 | −1 | −3

⎞
⎟
⎟
⎠

+

⎛
⎜
⎜
⎝

1 | 1 | −1
−3 | 5 | −1
−2 | 2 | 2

⎞
⎟
⎟
⎠

on applique l’algorithme de Horner :

B(2)

=

⎛
⎜
⎜
⎝

1 | −1 | 1
1 | −1 | 1
0 | 0 | 0

⎞
⎟
⎟
⎠

,

B′(2)

=

⎛
⎜
⎜
⎝

2 | −1 | 1
2 | −1 | 1
1 | −1 | 1

⎞
⎟
⎟
⎠

Comme B(2)≠ 0, on pourrait arrêter les calculs en utilisant une colonne non nulle et le cycle de Jordan associé (2,2,1)→ (1,1,0) → (0,0,0) . Expliquons tout de même l’algorithme général sur cet exemple. La réduction de B(2) s’obtient en effectuant les manipulations de colonnes C2+C1 → C2 et C3−C1 → C3. On effectue les mêmes opérations sur B′(2) et on obtient :

⎛
⎜
⎜
⎝

1 | 0 | 0
1 | 0 | 0
0 | 0 | 0

⎞
⎟
⎟
⎠

,

⎛
⎜
⎜
⎝

2 | 1 | −1
2 | 1 | −1
1 | 0 | 0

⎞
⎟
⎟
⎠

L’étape suivante consiste à déplacer vers le bas d’une matrice les colonnes non nulles de la matrice du haut, on obtient :

⎛
⎜
⎜
⎝

1 | 1 | −1
1 | 1 | −1
0 | 0 | 0

⎞
⎟
⎟
⎠

qui se réduit en :

⎛
⎜
⎜
⎝

1 | 0 | 0
1 | 0 | 0
0 | 0 | 0

⎞
⎟
⎟
⎠

on chercherait alors dans les colonnes 2 et 3 de nouveaux cycles (puisque la colonne 1 a déja été utilisée pour fournir un cycle).

#### 10.2.8 Exemple 2

A=

⎛
⎜
⎜
⎝

3 | 2 | −2
−1 | 0 | 1
1 | 1 | 0

⎞
⎟
⎟
⎠

λ =1 est valeur propre de multiplicité 3. On trouve :

B(1)

=

⎛
⎜
⎜
⎝

0 | 0 | 0
0 | 0 | 0
0 | 0 | 0

⎞
⎟
⎟
⎠

,

B′(1)

=

⎛
⎜
⎜
⎝

2 | 2 | −2
−1 | −1 | 1
1 | 1 | −1

⎞
⎟
⎟
⎠

,

B′′(1)
2

=

⎛
⎜
⎜
⎝

1 | 0 | 0
0 | 1 | 0
0 | 0 | 1

⎞
⎟
⎟
⎠

Le processus de réduction commence avec B′(1) en haut de la liste de matrices, on effectue les opérations élémentaires de colonne C2−C1→ C2 et C3+C1 → C3 et on obtient:

⎛
⎜
⎜
⎝

2 | 0 | 0
−1 | 0 | 0
1 | 0 | 0

⎞
⎟
⎟
⎠

,

⎛
⎜
⎜
⎝

1 | −1 | 1
0 | 1 | 0
0 | 0 | 1

⎞
⎟
⎟
⎠

La première colonne donne le premier cycle de Jordan (1,0,0) → (2,−1,1). On déplace les premières colonnes d’une matrice vers le bas :

⎛
⎜
⎜
⎝

2 | −1 | 1
−1 | 1 | 0
1 | 0 | 1

⎞
⎟
⎟
⎠

qu’on réduit par les opérations 2C2 +C1 → C2 et 2C3−C1→ C3 en :

⎛
⎜
⎜
⎝

2 | 0 | 0
−1 | 1 | 1
1 | 1 | 1

⎞
⎟
⎟
⎠

Puis on effectue C3−C2 → C3 et la deuxième colonne nous donne le deuxième cycle de Jordan, réduit ici à un seul vecteur propre (0,1,1).

#### 10.2.9 Le polynôme minimal par Faddeev

On vérifie aisément que le degré du facteur (λ−λi) dans le polynôme minimal de A est égal à ni−k où k est le plus grand entier tel que :

∀ j<k, B(j)(λi)=0

#### 10.2.10 Formes normales rationnelles

On se place ici dans une problématique différente : trouver une matrice semblable la plus simple possible sans avoir à introduire d’extension algébrique pour factoriser le polynôme caractéristique. Quitte à “compléter” plus tard la factorisation et la jordanisation à partir de la forme simplifiée. Il existe diverses formes associées à une matrice et plusieurs algorithmes permettant de les relier entre elles, forme de Smith, de Frobenius, forme normale de Jordan rationnelle.

On va présenter une méthode directe de calcul d’une forme normale contenant le maximum de zéros (dont la forme dite normale de Jordan rationnelle peut se déduire) en utilisant le même algorithme que pour la forme normale de Jordan. Soit Q(λ)=q0+...+qd λd un facteur irréductible de degré d et de multiplicité q du polynôme caractéristique P. Il s’agit de construire un sous-espace de dimension dq formé de “cycles de Jordan rationnels”. On part toujours de la relation (λ I −A) ∑k≤ n−1 Bk λk=P(λ)I. On observe que Q(λ)I−Q(A) est divisible par (λ I −A) donc il existe une matrice M(λ) telle que :

(Q(λ) I −Q(A)) (

∑
k≤ n−1

Bk λk) =Q(λ)q M(λ)

On observe aussi que Q a pour coefficient dominant 1 puisqu’il divise P, on peut donc effectuer des divisions euclidiennes de polynômes donc de polynômes à coefficients matriciels par Q sans avoir à diviser des coefficients. Ce qui nous permet de décomposer B(λ)=∑k≤ n−1 Bk λk en puissances croissantes de Q :

B(λ)=

∑
k

Ck(λ) Q(λ)k, deg(Ck)<q

On remplace et on écrit que les coefficients des puissances inférieures à q de Q sont nulles (la k-ième étant non nulle car M(λ) n’est pas divisible par Q pour les mêmes raisons que pour la forme normale de Jordan). On a donc les relations :

Q(A)C0 = 0, Ck = Q(A) Ck+1

ce qui donne une colonne de matrice Cq−1 → Cq−2 ... → C0 → 0 qui sont images l’une de l’autre en appliquant Q(A). On peut alors faire l’algorithme de réduction simultanée sur les colonnes des Cj. On observe ensuite que le nombre de cycles de Jordan de Q(A) de longueur donnée est un multiple de d, en effet il suffit de multiplier un cycle par A, ..., Ad−1 pour créer un autre cycle, de plus ces cycles forment des familles libres car on a supposé Q irréductible. On peut donc choisir pour un cycle de longueur k des bases de la forme (vk−1,Avk−1...,Ad−1vk−1) → ... → (v0,Av0...,Ad−1v0) → (0,...,0) où la flèche → désigne l’image par Q(A). Si on écrit la matrice de A dans la base v0,Av0...,Ad−1v0,...,vk−1,Avk−1...,Ad−1vk−1 on obtient un “quasi-bloc de Jordan rationnel” de taille kd multiple de d :

⎛
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎝

0 | 0 | ... | −q0 |  | 0 | 0 | ... | 1 | ...
1 | 0 | ... | −q1 |  | 0 | 0 | ... | 0 | ...
0 | 1 | ... | −q2 |  | 0 | 0 | ... | 0 | ...
⋮ | ⋮ | ... | ⋮ |  | ⋮ | ⋮ | ... | ⋮ | ...
0 | 0 | ... | −qd−1 |  | 0 | 0 | ... | 0 | ...
0 | 0 | ... | 0 |  | 0 | 0 | ... | −q0 | ...
0 | 0 | ... | 0 |  | 1 | 0 | ... | −q1 | ...
⋮ | ⋮ | ... | ⋮ |  | ⋮ | ⋮ | ... | ⋮ | ...

⎞
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎠

Exemple
Soit la matrice

A=

⎛
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎝

1 | −2 | 4 | −2 | 5 | −4

0

1

5
2

−7
2

2

−5
2

1

−5
2

2

−1
2

5
2

−3

0

−1

9
2

−7
2

3

−7
2

0 | 0 | 2 | −2 | 3 | −1

1

−3
2

−1
2

1

3
2

1
2

⎞
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎠

Son polynôme caractéristique est (x−2)2(x2−2)2 et on va déterminer la partie bloc de Jordan rationnel correspondant au facteur irréductible sur les entiers Q(x)=(x2−2) de multiplicité q=2. On calcule B(x) et l’écriture de B comme somme de puissances de Q (ici avec `xcas` en mode `xcas`) :

    A:=[[1,-2,4,-2,5,-4],[0,1,5/2,(-7)/2,2,(-5)/2],[1,(-5)/2,2,1/(-2),5/2,-3],
        [0,-1,9/2,(-7)/2,3,(-7)/2],[0,0,2,-2,3,-1],[1,(-3)/2,1/(-2),1,3/2,1/2]];
    P:=det(A-x*idn(6));
    B:=normal(P*inv(A-x*idn(6))); // preferer un appel a faddeev bien sur!
    ecriture(B,Q,q):={
      local j,k,l,n,C,D,E;
      C:=B;
      D:=B;
      E:=NULL;
      n:=coldim(B);
      for (j:=0;j<q;j++){
        for (k:=0;k<n;k++){
          for (l:=0;l<n;l++){
            D[k,l]:=rem(C[k,l],Q,x);
            C[k,l]:=quo(C[k,l],Q,x);
          }
        }
        E:=E,D;
      }
      return E;
    };
    E:=ecriture(B,x^2-2,2);
    QA:=A*A-2*idn(6);

On vérifie bien que `normal(QA*E(0))` et `normal(QA*E(1))-E(0))` sont nuls. On sait qu’on a un bloc de taille 2 de cycles de Jordan de longueur 2, donc il n’est pas nécessaire de faire des réductions ici, il suffit de prendre une colonne non nulle de E(0), par exemple la première colonne en x=0 et la colonne correspondante de E(1) et leurs images par A, ici cela donne (4,24,12,32,8,−4) correspondant à (0,4,−4,8,4,−4), on calcule les images par A, la matrice de l’endomorphisme restreint à ce sous-espace est alors le bloc de taille 4 :

⎛
⎜
⎜
⎜
⎝

0 | 2 | 0 | 1
1 | 0 | 0 | 0
0 | 0 | 0 | 2
0 | 0 | 1 | 0

⎞
⎟
⎟
⎟
⎠

Cette forme normale minimise le nombre de coefficients non nuls, mais présente un inconvénient, la partie nilpotente ne commute pas avec la partie bloc-diagonale, contrairement à la forme normale rationnelle de Jordan qui contient des blocs identités au-dessus de la diagonale de blocs. Pour créer la forme normale rationnelle de Jordan, on doit donc remplacer les blocs (

... | 0 | 1
... | 0 | 0
...

) par des matrices identités. Supposons constitués les j premiers blocs de taille d numérotés de 0 à j−1 avec comme base de vecteurs (v0,0,...,v0,d−1,...,vj−1,d−1). Il s’agit de trouver un vecteur vj,0 pour commencer le bloc suivant. On définit alors vj,l en fonction de vj,l−1 en appliquant la relation Avj,l−1=vj,l+vj−1,l−1. Il faut donc chercher vj,0 tel que

Avj,d−1=−q0 vj,0−...−qd−1 vj,d−1+vj−1,d−1 (38)

En utilisant les relations de récurrence précédentes, on voit que cela revient à fixer Q(A)vj,0 en fonction des vj′,l avec j′<j (l quelconque). Ce qui est toujours possible en utilisant la colonne de matrices Cj′ qui s’obtiennent en fonction des Cj′+1 en appliquant Q(A).

Plus précisément, calculons les vj,l en fonction de vj,0 et des vj′,l′ (j′<j). On utilise les coefficients binomiaux ( ml) calculés par la règle du triangle de Pascal et on montre par récurrence que :

vj,l = Al vj,0 −

inf(l,j)
∑
m=1

⎛
⎝

l
m

⎞
⎠

vj−m,l−m (39)

On remplace dans (38) d’où :

Ad vj,0 −

inf(d,j)
∑
m=1

⎛
⎝

d
m

⎞
⎠

vj−m,l−m +

d
∑
l=0

ql (Al vj,0 −

inf(l,j)
∑
m=1

⎛
⎝

l
m

⎞
⎠

vj−m,l−m )=0

finalement :

Q(A) vj,0=

d
∑
l=1

ql

inf(l,j)
∑
m=1

⎛
⎝

l
m

⎞
⎠

vj−m,l−m (40)

Application à l’exemple :
Ici v0,0=(4,24,12,32,8,−4) et v0,1=Avj,0 dont une préimage par Q(A) est w1,0=(0,4,−4,8,4,−4) et w1,1=Aw1,0. On applique (40), comme q1=0 et q2=1 on doit avoir :

Q(A) v1,0 =

2
∑
l=1

ql

inf(l,1)
∑
m=1

⎛
⎝

l
m

⎞
⎠

v1−m,l−m =2v0,1

donc :

v1,0 | = | 2A(0,4,−4,8,4,−4) | = | (−8,−32,0,−48,−16,16)
v1,1 | = | Av1,0−v0,0 | = | (4,40,−4,64,24,−20)

On vérifie bien que Av1,1=2v1,0+v0,1.

#### 10.2.11 Fonctions analytiques

Soit f une fonction analytique et M une matrice. Pour calculer f(M), on calcule la forme normale de Jordan de M=P(D+N)P−1 où D=diag(d1,...,dm) est diagonale et N nilpotente d’ordre n. On calcule aussi le développement de Taylor formel de f en x à l’ordre n−1, on a alors :

f(N)=P

⎛
⎜
⎜
⎝

n−1
∑
j=0

diag(f(j)(d1),..., f(j)(dm))
j!

Nj

⎞
⎟
⎟
⎠

P−1

### 10.3 Quelques autres algorithmes utiles

#### 10.3.1 Complexité asymptotique

Pour calculer le produit de matrices, on peut utiliser l’algorithme de Strassen, on présente ici la variante de Winograd. Soit à calculer :

⎛
⎜
⎝

a1,1 | a1,2
a2,1 | a2,2

⎞
⎟
⎠

⎛
⎜
⎝

b1,1 | b1,2
b2,1 | b2,2

⎞
⎟
⎠

=

⎛
⎜
⎝

c1,1 | c1,2
c2,1 | c2,2

⎞
⎟
⎠

On calcule :

s1=a2,1+a2,2, s2=s1−a1,1, s3=a1,1− a2,1, s4=a1,2−s2
t1=b1,2−b1,1, t2=b2,2−t1, t3=b2,2−b1,2, t4=b2,1−t2

puis :

p1=a1,1 b1,1, p2=a1,2b2,1, p3=s1 t1, p4=s2 t2
p5=s3 t3, p6=s4 b2,2, p7=a2,2 t4
u1= p1+p2 u2=p1+p4, u3=u2+p5, u4=u3+p7
u5=u3+p3, u6=u2+p3, u7=u6+p6

Alors c1,1=u1, c1,2=u7, c2,1=u4, c2,2=u5.
Cet algorithme utilise 7 multiplications et 15 additions ce qui économise 1 multiplication et permet en appliquant récursivement cet algorithme pour des matrices blocs de réduire la complexité d’un produit de grandes matrices normalement en O(n3=nln(8)/ln(2)) à O(nln(7)/ln(2)) (la preuve est analogue à celle de la multiplication des polynômes par l’algorithme de Karatsuba).

En utilisant une factorisation LU par blocs, on peut montrer que cette complexité asymptotique se généralise au calcul de l’inverse. On peut d’ailleurs améliorer l’exposant, mais la constante non explicitée dans le O augmente aussi. En pratique, Strassen n’est pas utilisée pour des matrices de taille plus petites que plusieurs centaines de lignes et colonnes.

De même on peut gagner sur le calcul du polynôme minimal en faisant des opérations de multiplication par bloc.

#### 10.3.2 Numériques

La plupart des algorithmes d’algèbre linéaire “numérique” ont une utilité en calcul exact : par exemple la factorisation LU (avec les variations décrites dans la section réduction de Gauß), la factorisation QR (et donc la méthode de Gram-Schmidt, ici pour des raisons d’efficacité on orthogonalise d’abord la base de départ et on la normalise à la fin seulement), Cholesky,....

Certains algorithmes numériques peuvent s’utiliser conjointement à des algorithmes exacts. Par exemple, pour une matrice M à coefficients rationnels, on peut localiser par des méthodes exactes les racines du polynôme caractéristique, on trouve une valeur approchée r d’une valeur propre à une précision fixée, puis calculer par la méthode de la puissance appliquée à (M−rI)−1 un vecteur propre approché. Inversement, des méthodes de diagonalisation numériques couplées à du calcul exact peuvent permettre de localiser des valeurs propres complexes.

#### 10.3.3 Décomposition de Schur

Il s’agit d’une factorisation de matrice sous la forme

A = P S P−1

où P est unitaire et S diagonale supérieure. Existence (théorique) : on prend une valeur propre et un vecteur propre correspondant, puis on projette sur l’orthogonal de ce vecteur propre et on s’y restreint, on prend à nouveau une valeur propre et un vecteur propre correspondant, etc.

On peut approcher cette factorisation par un algorithme itératif qui utilise la factorisation QR d’une matrice quelconque comme produit d’une matrice unitaire par une matrice triangulaire supérieure à coefficients positifs sur la diagonale. On fait l’hypothèse que les valeurs propres de S sur la diagonale sont classées par ordre de module strictement décroissant |λ1|>|λ2|>...>|λn| (développement inspiré par Peter J. Olver dans le cas symétrique `http://www.math.umn.edu/~olver/aims_/qr.pdf`). On peut toujours s’y ramener quitte à remplacer A par A− α I. Posons A1=A, et par récurrence An=QnRn (avec Qn unitaire et R triangulaire supérieure à coefficients diagonaux positifs), An+1=RnQn. On a alors

Ak | = | (Q1 R1) (Q1 R1) (Q1 R1) ... (Q1 R1) (Q1 R1)
| = | Q1 (R1 Q1) (R1 Q1) (R1 ... Q1) (R1 Q1) R1
| = | Q1 (Q2 R2) (Q2 R2) .. (Q2 R2) R1
| = | Q1 Q2 (R2 Q2) R2 .. Q2 R2 R1
| = | Q1 Q2 (Q3 R3) ... Q3 R3 R2 R1
| = | Q1 ... Qk Rk ...R1

D’autre part A=PSP−1 donc Ak = P Sk P−1. Soit D la forme diagonale de S et U la matrice de passage S=UDU−1, où U est triangulaire supérieure et où on choisit la normalisation des coefficients sur la diagonale de U valant 1. On a donc

Ak = P U Dk U−1 P−1

Ensuite, on suppose qu’on peut factoriser U−1P−1=LŨ sans permutations, donc qu’on ne rencontre pas de pivot nul, et quitte à multiplier les vecteurs unitaires de P−1 par une constante complexe de module 1 on peut supposer que les pivots sont positifs donc que Ũ a des coefficients positifs sur la diagonale, on a alors

Ak = P U Dk L Ũ = Q1 ... Qk Rk ...R1

puis en multipliant par U−1 |D|−k

P U Dk L |D|−k = Q1 ... Qk Rk ...R1 Ũ−1 |D−−k

où Rk ...R1 Ũ−1 |D|−k est triangulaire supérieure à coefficients positifs sur la diagonale et Q1 ... Qk est unitaire. On regarde ensuite les entrées de la matrice Dk L |D|−k, sous la diagonale elles convergent (géométriquement) vers 0, donc UDk L |D|−k tend vers une matrice triangulaire supérieure dont les coefficients diagonaux valent ei karg(λj). On montre que cela entraine que Q1 ... Qk est équivalent à P(D/|D|)k

Q1 ... Qk ≈ P (D/|D|)k, Rk ...R1 Ũ−1 |D|−k ≈ (D/|D|)−k UDk L |D|−k

Donc, Qk tend à devenir diagonale, et Rk Qk=Ak+1 triangulaire supérieure. De plus

A=Q1 A2 Q1−1 = ... = Q1 ... Qk Ak+1 (Q1 ... Qk)−1

la matrice Ak+1 est donc semblable à A.

En pratique, on n’impose pas la positivité des coefficients diagonaux de R dans la factorisation QR, ce qui ne change évidemment pas le fait que Qk s’approche d’une matrice diagonale et Ak d’une matrice triangulaire supérieure (avec convergence à vitesse géométrique). On utilise aussi des “shifts” pour accélerer la convergence, c’est-à-dire qu’au lieu de faire QR et RQ sur la matrice Ak on le fait sur Ak − αk I où λk est choisi pour accélerer la convergence vers 0 du coefficient d’indice ligne n colonne n−1 (idéalement il faut prendre αk proche de λn la valeur propre de module minimal, afin de minimiser |λn−αk|/|λn−1−αk|). En effet, si Ak − λk I = Qk Rk et Ak+1=RkQk+λk I alors :

(A−α1 I) ... (A−αk I) | = | Q1R1(Q1R1−(α2−α1)I) ...(Q1R1−(α2−α1)I)
| = | Q1 (R1Q1 − (α2−α1)I)R1 (Q1R1−(α3−α1)I) ...(Q1R1−(α2−α1)I)
| = | Q1 (A2 − α1 I −(α2−α1)I) R1 Q1(R1Q1−(α3−α1)I) R1...(Q1R1−(α2−α1)I)
| = | Q1 (A2 − α2 I) (A2 − α3 I) ... (A2 − αk−1I) R1
| = | ...
| = | Q1 ... Qk Rk ...R1

On peut aussi éliminer la dernière ligne et la dernière colonne de la matrice pour accélerer les calculs dès que le coefficient en ligne n colonne n−1 est suffisamment petit.

On remarque que pour une matrice réelle si on choisit des shifts conjugués, alors Q1...Qk Rk...R1 est réel. Or si QR=Q R et si R est inversible

Q

−1 Q =

R

R−1

On a donc une matrice symétrique (car Q−1=Qt) et triangulaire supérieure. On en déduit que Q−1 Q=D est diagonale, donc Q=Q D. On peut donc rendre Q réelle en divisant chaque colonne par un eiθ, et rendre R réelle en conjuguant par la matrice D. Mais ce procédé de retour au réel après élimination de 2 valeurs propres complexes conjuguées d’une matrice réelle se heurte à un problème de conditionnement parce que le choix d’un shift intéressant pour la convergence va rendre la matrice R proche d’une matrice non inversible (les deux derniers coefficients diagonaux de R sont proches de 0). On a alors seulement

Q

−1 Q R =

R

Si on décompose Q−1 Q, R, R par blocs n−2,n−2, n−2,2, 2,n−2 et 2,2, on a

⎛
⎜
⎝

QQ11 | QQ12
QQ21 | QQ22

⎞
⎟
⎠

⎛
⎜
⎝

R11 | R12
0 | R22

⎞
⎟
⎠

=

⎛
⎜
⎝

QQ11 R11 | QQ21R11
QQ11 R12 + QQ12 R22 | QQ21 R12 + QQ22 R22

⎞
⎟
⎠

=

⎛
⎜
⎜
⎜
⎜
⎜
⎝

R

11

R

12

0

R

22

⎞
⎟
⎟
⎟
⎟
⎟
⎠

Donc on a QQ11 =R11 R11−1. Comme Q est unitaire, QQ=Q−1 Q=Qt Q est symétrique, donc QQ11 est diagonale puisque symétrique et triangulaire supérieure. On peut donc ramener Q11 et R11 en des matrices réelles.

Revenons à la localisation des valeurs propres. On suppose qu’on a maintenant une matrice unitaire P et une matrice triangulaire supérieure S (aux erreurs d’arrondi près) telles que

P−1 A P = S

Que peut-on en déduire ? On va d’abord arrondir P en une matrice exacte à coefficients rationnels, dont les dénominateurs sont une puissance de 2 (en fait c’est exactement ce que donne l’écriture d’un flottant en base 2, une fois ramené tous les exposants à la même valeur). On a donc une matrice Pe presque unitaire exacte et telle que

Se = Pe−1 A Pe

est semblable à A, et presque triangulaire supérieure. (comme Pe est presque unitaire, sa norme et la norme de son inverse sont proches de 1 donc Se est proche de S, les coefficients de Se sont de la même taille que les coefficients de A : le changement de base est bien conditionné et c’est la raison pour laquelle on a choisi d’effectuer des transformations unitaires).

Notons µ1, ..., µn les coefficients diagonaux de Se, soit ε un majorant de la norme des coefficients sous-diagonaux de Se, et soit δ un minorant de l’écart entre 2 µj distincts. On a donc Se=U+E où U est triangulaire supérieure, E est triangulaire inférieure avec des 0 sous la diagonale et des coefficients de module majorés par ε. Si ε est suffisamment petit devant δ, on va montrer qu’on peut localiser les valeurs propres de Se (qui sont celles de A) au moyen des µj.

En effet, fixons j et soit C un cercle de centre µ=µj et de rayon α ≤ δ/2. Si A est une matrice diagonalisable, on sait que

nombre de valeurs propres ∈ C =

1
2iπ

trace

∫

C

(A−zI)−1

En prenant A=Se, et en écrivant

(Se−zI)−1 = (U−zI+E)−1 = ( I + (U−zI)−1E)−1(U−zI)−1

on développe le second terme si la norme de (U−zI)−1E est strictement inférieure à 1

(Se−zI)−1 = (U−zI)−1 −(U−zI)−1E(U−zI)−1 + (U−zI)−1E(U−zI)−1E(U−zI)−1 + ...

puis on calcule la trace

trace(Se−zI)−1 =

∑
j

(µj−z)−1 + η

avec

|η| ≤ 2π α || (U−zI)−1 ||

|| (U−zI)−1E ||
1−|| (U−zI)−1E ||

Au final, le nombre de valeurs propres dans C est donné par

1 + η, |η| ≤ α maxz ∈ C || (U−zI)−1 ||

|| (U−zI)−1E ||
1−|| (U−zI)−1E ||

Il suffit donc que le max soit plus petit que 1 pour avoir l’existence d’une valeur propre et une seule de Se dans le cercle C (à distance au plus α de µ). Ce sera le cas si

ε ≤

1
2

⎛
⎜
⎜
⎝

δ
2 ||Se||

⎞
⎟
⎟
⎠

n−1

α

√

n−1

on choisit donc α pour réaliser l’égalité ci-dessus, sous réserve que δ ne soit pas trop petit, rappelons que α doit être plus petit ou égal à δ/2. Si δ est petit, il peut être nécessaire d’utiliser une précision plus grande pour les calculs de la décomposition de Schur en arithmétique flottante.

Typiquement, on peut espérer (pour un écart δ pas trop petit) pouvoir localiser les racines d’un polynôme de degré n par cette méthode avec précision b bits en O(n3 b2 + n2 b3) opérations pour le calcul de la décomposition de Schur en flottant (n3b2 pour Hessenberg initial puis n2b2 par itération et un nombre d’itérations proportionnel à b). Pour le calcul exact de Se, il faut inverser une matrice de taille n avec des coefficients de taille proportionnelle à b donc O(n4bln(n)) opérations (en modulaire, la taille des coefficients de l’inverse est O(nb ln(n))) puis calculer un produit avec une matrice n,n de coefficients de taille proportionnelle à b, soit O(n4b2ln(nb)) opérations. Asymptotiquement, on peut faire mieux avec des méthodes de multiplication et d’opérations matricielles par blocs. Pour éviter la perte d’un facteur n, on peut aussi ne pas faire de calculs en mode exact et controler les erreurs sur la matrice S. On peut regrouper les valeurs propres par “clusters” si elles sont trop proches à la précision de b bits. Pour la recherche des racines d’un polynôme P, on peut montrer, en calculant le résultant de P et de P′ qui est en module plus grand ou égal à 1, et en l’écrivant comme produit des différences des racines, et en majorant toutes les différences de racine sauf une à l’aide de la norme infinie de P, qu’il faut b=O(n) bits pour séparer les racines).

#### 10.3.4 Autres

On peut aussi facilement programmer la recherche de la décomposition tP D P d’une matrice symétrique et en déduire la signature d’une forme quadratique. Citons enfin l’algorithme LLL (cf. Cohen) qui est utile dans de nombreux domaines (il permet de trouver des vecteurs assez courts dans un réseau, ce ne sont pas les plus courts, mais en contrepartie on les trouve très vite).

### 10.4 Quelques références

- Comme toujours on renvoie à l’excellent livre de Henri Cohen: A Course in Computational Algebraic Number Theory
- Gantmacher: Théorie des matrices
- Pour une implémentation des algorithmes de forme normale de Smith ou de Frobenius, cf. le source de MuPAD ou
  `http://www.mapleapps.com/maplelinks/share/normform.html`
- Ferrard, Lemberg: Mathématiques Concrètes, Illustrées par la TI 92 et la TI 89
  Présente aussi des algorithmes plus numériques, et le lien avec la diagonalisation numérique de matrices.
- Press et al.: Numerical recipies in Fortran/C/Pascal.
  Pour des algorithmes numériques (sur les matrices et autres).

### 10.5 Exercices (algèbre linéaire)

#### 10.5.1 Instructions

- Les commandes d’algèbre linéaire de Xcas sont regroupées dans le menu `Cmds->Alglin`. En maple V, la commande `?linalg` affiche la liste des commandes d’algèbre linéaire.
- En maple V il est conseillé d’exécuter `with(linalg);`, sinon il faut précéder chaque commande de `linalg::`. Attention il faut utiliser le caractère `&` avant la multiplication et il faut souvent utiliser `evalm` dans les programmes utilisant des matrices et vecteurs. Notez aussi que les matrices sont toujours passées par référence en maple V, en Xcas le choix revient à l’utilisateur (affectation par `:=` par valeur ou par `=<` par référence)
- Pour travailler avec des coefficients modulaires, en Xcas on fait suivre les coefficients ou matrices de `% n` (utiliser `% 0` pour enlever les modulos), en maple V, on utilise les noms de commandes avec une majuscule (forme inerte) suivi de `mod n`.

#### 10.5.2 Exercices

1. En utilisant un logiciel de calcul formel, comparez le temps de calcul d’un déterminant de matrice aléatoire à coefficients entiers de tailles 50 et 100, d’une matrice de taille 6 et 12 avec comme coefficients symboliques ligne j colonne k, xj+k lorsque j+k est pair et 0 sinon. Peut-on en déduire une indication sur l’algorithme utilisé?
2. Écrire un programme calculant la borne de Hadamard d’un déterminant à coefficients réels (rappel : c’est la borne obtenue en faisant le produit des normes euclidiennes des vecteurs colonnes).
3. Créez une matrice 4x4 aléatoire avec des coefficients entiers compris entre -100 et 100, calculer la borne de Hadamard de son déterminant avec le programme précédent, calculer ce déterminant modulo quelques nombres premiers choisis en fonction de la borne de Hadamard et vérifiez le résultat de la reconstruction modulaire du déterminant.
4. Créez une matrice 100x100 aléatoire à coefficients entiers et calculez son déterminant modulo quelques nombres premiers. Dans quels cas peut-on conclure que la matrice est inversible dans ℝ? dans ℤ?
5. Écrire un programme calculant par interpolation de Lagrange le polynôme caractéristique d’une matrice (en donnant à λ de det(λ I −A), n+1 valeurs distinctes).
6. (Long) Écrire un programme qui calcule un déterminant de matrice en calculant les mineurs 2x2 puis 3x3 etc. (méthode de Laplace)
7. Recherche du polynôme minimal. On prend un vecteur aléatoire à coefficients entiers et on calcule v, Av, ..., Anv puis on cherche une relation linéaire minimale entre ces vecteurs, en calculant le noyau de la matrice ayant ces vecteurs colonnes. Si le noyau est de dimension 1, alors le polynôme minimal est égal au polynome caractéristique et correspond à un vecteur de la base du noyau. Sinon, il faut choisir un vecteur du noyau correspondant au degré le plus petit possible puis faire le PPCM avec les polynomes obtenurs avec d’autres vecteurs pour obtenir le polynôme minimal avec une grande probabilité. Essayez avec la matrice A de taille 3 ayant des 0 sur la diagonale et des 1 ailleurs. Écrire un programme mettant en oeuvre cette recherche, testez-le avec une matrice aléatoire de taille 30.
8. Testez l’algorithme méthode de Fadeev pour la matrice A ci-dessus. Même question pour

   A=

   ⎛
   ⎜
   ⎜
   ⎝

   3 | −1 | 1
   2 | 0 | 1
   1 | −1 | 2

   ⎞
   ⎟
   ⎟
   ⎠

   , A=

   ⎛
   ⎜
   ⎜
   ⎝

   3 | 2 | −2
   −1 | 0 | 1
   1 | 1 | 0

   ⎞
   ⎟
   ⎟
   ⎠

9. Écrire un programme calculant par une méthode itérative la valeur propre de module maximal d’une matrice à coefficients complexes. Dans le cas réel, modifier le programme pour pouvoir traiter le cas d’un couple de complexes conjugués de module maximal. Dans le cas hermitien ou réel symétrique, éliminer le couple valeur propre/vecteur propre et continuer la diagonalisation numérique.
10. Soient |a|,|b|<√n/2 Écrire une fonction ayant comme arguments a/b (mod n ) qui calcule a et b.
    Utiliser ce programme pour résoudre un système 4,4 à coefficients entiers par une méthode p-adique.

## 11 Interpolation

Étant donné la facilité de manipulation qu’apportent les polynomes, on peut chercher à approcher une fonction par un polynôme. De plus l’interpolation est un outil très utilisé pour calculer des polynômes en calcul formel.

### 11.1 Interpolation de Lagrange

La méthode la plus naturelle consiste à chercher un polynôme de degré le plus petit possible égal à la fonction en certains points x0,...,xn et à trouver une majoration de la différence entre la fonction et le polynôme. Le polynome interpolateur de Lagrange répond à cette question.

#### 11.1.1 Existence et contrôle de l’erreur.

Soit donc x0,...,xn des réels distincts et y0,...,yn les valeurs de la fonction à approcher en ces points (on posera yj=f(xj) pour approcher la fonction f). On cherche donc P tel que P(xj)=yi pour j ∈ [0,n].

Commencons par voir s’il y a beaucoup de solutions. Soit P et Q deux solutions distinctes du problème, alors P−Q est non nul et va s’annuler en x0, ...,xn donc possède n+1 racines donc est de degré n+1 au moins. Réciproquement, si on ajoute à P un multiple du polynome A=∏j=0n (X−xj), on obtient une autre solution. Toutes les solutions se déduisent donc d’une solution particulière en y ajoutant un polynome de degré au moins n+1 multiple de A.

Nous allons maintenant construire une solution particulière de degré au plus n. Si n=0, on prend P=x0 constant. On procède ensuite par récurrence. Pour construire le polynôme correspondant à x0,...,xn+1 on part du polynoôme Pn correspondant à x0,...,xn et on lui ajoute un multiple réel de A

Pn+1=Pn+a

n
∏
j=0

(X−xj)

Ainsi on a toujours Pn+1(xj)=yj pour j=0,..n, on calcule maintenant a pour que Pn+1(xn+1)=yn+1. En remplacant avec l’expression de Pn+1 ci-dessus, on obtient

Pn(xn+1)+a

n
∏
j=0

(xn+1−xj) = yn+1

Comme tous les xj sont distincts, il existe une solution unique a :

a=

yn+1−Pn(xn+1)

n
∏
j=0

(xn+1−xj)

On a donc prouvé le :

Théorème 12 Soit n+1 réels distincts x0,...,xn et n+1 réels quelconques y0,...,yn. Il existe un unique polynôme P de degré inférieur ou égal à n, appelé polynome de Lagrange, tel que :

P(xi)=yi

Exemple : déterminons le polynome de degré inférieur ou égal à 2 tel que P(0)=1, P(1)=2, P(2)=1. On commence par P0=1. Puis on pose P1=P0+aX=1+aX. Comme P(1)=2=1+a on en tire a=1 donc P1=1+X. Puis on pose P2=P1+aX(X−1), on a P2(2)=3+2a=1 donc a=−1, finalement P2=1+X−X(X−1).

On peut calculer le polynome de Lagrange comme indiqué ci-dessus, la méthode dite des différences divisées permettant de le faire de la manière la plus efficace possible (cf. par exemple Demailly).

Reste à estimer l’écart entre une fonction et son polynome interpolateur, on a le :

Théorème 13 Soit f une fonction n+1 fois dérivable sur un intervalle I=[a,b] de ℝ, x0,...,xn des réels distincts de I. Soit P le polynome de Lagrange donné par les xj et yj=f(xj). Pour tout réel x ∈ I, il existe un réel ξx ∈ [a,b] (qui dépend de x) tel que :

f(x)−P(x) =

f[n+1](ξx)
(n+1)!

n
∏
j=0

(x−xj) (41)

Ainsi l’erreur commise dépend d’une majoration de la taille de la dérivée n+1-ième sur l’intervalle, mais aussi de la disposition des points xj par rapport à x. Par exemple si les points xj sont équidistribués, le terme |∏j=0n(x−xj)| sera plus grand près du bord de I qu’au centre de I.

Preuve du théorème : Si x est l’un des xj l’égalité est vraie. Soit

C=(f(x)−P(x))/

n
∏
j=0

(x−xj)

on considère maintenant la fonction :

g(t)=f(t)−P(t) − C

n
∏
j=0

(t−xj)

elle s’annule en xj pour j variant de 0 à n ainsi qu’en x suite au choix de la constante C, donc g s’annule au moins n+2 fois sur l’intervalle contenant les xj et x, donc g′ s’annule au moins n+1 fois sur ce même intervalle, donc g′′ s’annule au moins n fois, etc. et finalement g[n+1] s’annule une fois au moins sur cet intervalle. Or

g[n+1] = f[n+1] − C (n+1)!

car P est de degré inférieur ou égal à n et ∏j=0n(x−xj) − xn+1 est de degré inférieur ou égal à n. Donc il existe bien un réel ξx dans l’intervalle contenant les xj et x tel que

C=

f[n+1](ξx)
(n+1)!

#### 11.1.2 Différences divisées

Calcul efficace du polynôme de Lagrange.
Avec la méthode de calcul précédent, on remarque que le polynôme de Lagrange peut s’écrire à la Horner sous la forme :

P(x) | = | α0 + α1 (x−x0) + ... + αn (x−x0)...(x−xn−1)
| = | α0 + (x−x0)( α1 + (x−x1)(α2 + ... + (x−xn−2)(αn−1+(x−xn−1) αn)...))

ce qui permet de le calculer rapidement une fois les αi connus. On observe que

α0=f(x0), α1=

f(x1)−f(x0)
x1−x0

On va voir que les αk peuvent aussi se mettre sous forme d’une différence. On définit les différences divisées d’ordre n par récurrence

f[xi]=f(xi), f[xi,...,xk+i+1]=

f[xi+1,...,xk+i+1]−f[xi,...,xk+i]
xk+i+1−xi

On va montrer que αk=f[x0,...,xk]. C’est vrai au rang 0, il suffit donc de le montrer au rang k+1 en l’admettant au rang k. Pour cela on observe qu’on peut construire le polynôme d’interpolation en x0,...,xk+1 à partir des polynômes d’interpolation Pk en x0,...,xk et Qk en x1,...,xk+1 par la formule :

Pk+1(x)=

(xk+1−x)Pk + (x−x0)Qk
xk+1−x0

en effet on vérifie que Pk+1(xi)=f(xi) pour i∈ [1,k] car Pk(xi)=f(xi)=Qk(xi), et pour i=0 et i=k+1, on a aussi Pk+1(x0)=f(x0) et Pk+1(xk+1)=f(xk+1). Or αk+1 est le coefficient dominant de Pk+1 donc c’est la différence du coefficient dominant de Qk et de Pk divisée par xk+1−x0, c’est-à-dire la définition de f[x0,...,xk+1] en fonction de f[x1,...,xk+1] et f[x0,...,xk].

Exemple : on reprend P(0)=1, P(1)=2, P(2)=1. On a

xi | f[xi] | f[xi,xi+1] | f[x0,x1,x2]

0

1

(2−1)/(1−0)=

1

1

2

(−1−1)/(2−0)=

-1

|  | (1−2)/(2−1)=−1 |
2 | 1 |  |

donc P(x)=1+(x−0)(1+(x−1)(−1))=1+x(2−x).

On peut naturellement utiliser l’ordre que l’on souhaite pour les xi, en observant que le coefficient dominant de P ne dépend pas de cet ordre, on en déduit que f[x0,...,xk] est indépendant de l’ordre des xi, on peut donc à partir du tableau ci-dessus écrire P par exemple avec l’ordre 2,1,0, sous la forme

P(x)=1+(x−2)(−1+(x−1)(−1))=1+(x−2)(−x)

### 11.2 Les splines

Il s’agit de fonctions définies par des polynomes de degré borné sur des intervalles, dont on fixe la valeur aux extrémités des intervalles (comme pour le polynome de Lagrange) ce qui rend la fonction continue, de plus on exige un degré de régularité plus grand, par exemple etre de classe C2. Enfin, on fixe des conditions aux bornes de la réunion des intervalles, par exemple avoir certaines dérivées nulles.

Par exemple supposons qu’on se donne n intervalles, donc n+1 points x0,...,xn, on se fixe une régularité Cd−1. Ceci entraine (n−1)d conditions de recollement, on y ajoute n+1 conditions de valeur en x0,...,xn, on a donc nd+1 conditions, la borne sur le degré des polynomes doit donc etre d (ou plus, mais d suffit) ce qui donne n(d+1) degrés de liberté, on peut donc ajouter d−1 conditions, par exemple pour les splines naturelles, on impose que les dérivées d’ordre d/2 à d−1 soient nulles en x0 et xn (si d est pair, on commence à la dérivée d/2+1-ième nulle en xn).

Pour trouver les polynomes, on doit donc résoudre un grand système linéaire. Une méthode permettant de diminuer la taille du système linéaire à résoudre dans le cas des splines naturelles consiste à se fixer n inconnues z0,..,zn−1 représentant les dérivées d-ième de la spline f en x0 sur [x0,x1] à xn−1 sur [xn−1,xn], et (d−1)/2 inconnues fj, représentant la valeur de la dérivée de f en x0 pour j variant de 1 à (d−1)/2. On peut alors écrire le polynome sur l’intervalle [x0,x1] car on connait son développement de Taylor en x0. On effectue un changement d’origine (par application répétée de Horner) en x1. On obtient alors le polynome sur [x1,x2] en remplaçant uniquement la dérivée d-ième par z1. On continue ainsi jusqu’en xn−1. Le système s’obtient en calculant la valeur du polynome en x0,...,xn et la nullité des dérivées d’ordre (d−1)/2 à d/2 en xn. On résoud le système et on remplace pour avoir les valeurs numériques des coefficients du polynome.

## 12 La moyenne arithmético-géométrique.

La moyenne arithmético-géométrique est un processus itératif qui converge très rapidement et est très utile pour calculer les fonctions transcendantes réciproques en multi-précision. On peut alors trouver les fonctions transcendantes directes par application de la méthode de Newton.

### 12.1 Définition et convergence

Soient a et b deux réels positifs, on définit les 2 suites

u0=a, v0=b, un+1=

un+vn
2

, vn+1=

√

unvn

(42)

On va montrer que ces 2 suites sont adjacentes et convergent donc vers une limite commune notée M(a,b) et il se trouve que la convergence est très rapide, en raison de l’identité :

un+1−vn+1=

1
2

(

√

un

−

√

vn

)2 =

1

2(

√

un

+

√

vn

)2

(un−vn)2 (43)

la convergence est quadratique.

On suppose dans la suite que a≥ b sans changer la généralité puisque échanger a et b ne change pas la valeur de un et vn pour n>0. On a alors un ≥ vn (d’après (43) pour n>0) et un+1 ≤ un car

un+1−un=

1
2

(vn−un) ≤ 0

et vn+1=√unvn ≥ √vnvn=vn. Donc (un) est décroissante minorée (par v0), (vn) est croissante majorée (par u0), ces 2 suites sont convergentes et comme un+1=un+vn/2, elles convergent vers la même limite l qui dépend de a et b et que l’on note M(a,b). On remarque aussi que M(a,b)=bM(a/b,1)=aM(1,b/a).

Précisons maintenant la vitesse de convergence lorsque a ≥ b>0. On va commencer par estimer le nombre d’itérations nécessaires pour que un et vn soient du même ordre de grandeur. Pour cela, on utilise la majoration

ln(un+1)−ln(vn+1) ≤ ln(un)−ln(vn+1) =

1
2

(ln(un)−ln(vn))

donc

ln

un
vn

= ln(un)−ln(vn) ≤

1
2n

(ln(a)−ln(b)) =

1
2n

ln

a
b

Donc si n ≥ ln( ln(a/b)/m)/ln(2) alors lnun/vn ≤ m (par exemple, on peut prendre m=0.1 pour avoir un/vn ∈ [1,e0.1]). Le nombre minimum d’itérations n0 est proportionnel au log du log du rapport a/b. Ensuite on est ramené à étudier la convergence de la suite arithmético-géométrique de premiers termes a=un0 et b=vn0 et même en tenant compte de M(a,b)=aM(1,b/a) à a=1 et b=vn/un donc 0≤ a−b ≤ 1−e−0.1. Alors l’équation (43) entraine

un+1−vn+1 ≤

1
8

(un−vn)2

puis (par récurrence)

0 ≤ un−vn ≤

1
82n−1

(a−b)2n

Donc comme M(a,b) est compris entre vn et un, l’erreur relative sur la limite commune est inférieure à une précision donnée є au bout d’un nombre d’itérations proportionnel au ln(ln(1/є)).

Typiquement dans la suite, on souhaitera calculer M(1,b) avec b de l’ordre de 2−n en déterminant n chiffres significatifs, il faudra alors O(ln(n)) itérations pour se ramener à M(1,b) avec b∈ [e−0.1,1] puis O(ln(n)) itérations pour avoir la limite avec n chiffres significatifs.

Le cas complexe
On suppose maintenant que a, b ∈ ℂ avec ℜ(a)>0, ℜ(b)>0. On va voir que la suite arithmético-géométrique converge encore.
Étude de l’argument
On voit aisément (par récurrence) que ℜ(un)>0 ; de plus ℜ(vn) > 0 car par définition de la racine carrée ℜ(vn)≥ 0 et est de plus non nul car le produit de deux complexes d’arguments dans ]−π/2,π/2[ ne peut pas être un réel négatif. On en déduit que arg(un+1)=arg(un+vn) se trouve dans l’intervalle de bornes arg(un) et arg(vn) et que arg(vn+1)=1/2(arg(un)+arg(vn)) donc

| arg(un+1−arg(vn+1) | ≤

1
2

|arg(un)−arg(vn)|

Après n itérations, on a

|arg(un)−arg(vn)| ≤

π
2n

Après quelques itérations, un et vn seront donc presque alignés. Faisons 4 itérations. On peut factoriser par exemple vn et on est ramené à l’étude de la suite de termes initiaux a=un/vn d’argument arg(un)−arg(vn) petit (inférieur en valeur absolue à π/16) et b=1. On suppose donc dans la suite que

|arg(

un
vn

)| ≤

π/16
2n

Étude du module
On a :

un+1
vn+1

=

1
2

⎛
⎜
⎜
⎜
⎜
⎜
⎜
⎜
⎝

√

un
vn

+

1

√

un
vn

⎞
⎟
⎟
⎟
⎟
⎟
⎟
⎟
⎠

Posons un/vn=ρn eiθn, on a :

|

un+1
vn+1

|

=

1
2

⎪
⎪
⎪
⎪
⎪
⎪

√

ρn

eiθn/2 +

1

√

ρn

e−iθn/2

⎪
⎪
⎪
⎪
⎪
⎪

=

1
2

⎪
⎪
⎪
⎪
⎪
⎪

(

√

ρn

+

1

√

ρn

)cos

θn
2

+ i (

√

ρn

−

1

√

ρn

)sin

θn
2

⎪
⎪
⎪
⎪
⎪
⎪

=

1
2

√

(

√

ρn

+

1

√

ρn

)2cos2

θn
2

+ (

√

ρn

−

1

√

ρn

)2sin2

θn
2

=

1
2

√

ρn+

1
ρn

+2cosθn

Si ρ désigne le max de ρn et 1/ρn, on a alors la majoration

|

un+1
vn+1

| ≤

1
2

√

ρ + ρ + 2 ρ

=

√

ρ

donc en prenant les logarithmes

lnρn+1 ≤

1
2

lnρ=

1
2

|lnρn| (44)

On rappelle qu’on a la majoration

|arg(

un
vn

)| = |θn| ≤

π/16
2n

≤

1
2n+1

qui va nous donner la minoration de ρn+1

ρn+1=|

un+1
vn+1

|

=

1
2

√

ρn+

1
ρn

+2 − 2 (1−cosθn)

=

1
2

√

ρn+

1
ρn

+2 − 4 sin2 (

θn
2

)

≥

1
2

√

ρn+

1
ρn

+2 − θn2

≥

1
2

√

ρn+

1
ρn

+2

×

√

1 −

θn2

ρn+

1
ρn

+2

≥

1
2

√

1
ρ

+

1
ρ

+2

1
ρ

×

√

1 −

θn2
4

≥

1

√

ρ

√

1 −

θn2
4

≥

1

√

ρ

√

1 −

1
4 × 22n+2

en prenant les log et en minorant ln(1−x) par −2x

lnρn+1 ≥

1
2

(−|lnρn|+ln(1 −

1
4 × 22n+2

)) ≥ −

1
2

(|lnρn|+

1
22n+3

)

Finalement avec (44)

|lnρn+1| ≤

1
2

(|lnρn|+

1
22n+3

)

On en déduit

|lnρn| ≤

1
2n

lnρ0 +

1
2n+3

+ ... +

1
22n+1

+

1
22n+2

=

1
2n

lnρ0 +

1
2n+2

La convergence du ln(un/vn) vers 0 est donc géométrique, donc un et vn convergent quadratiquement.

### 12.2 Lien avec les intégrales elliptiques

Le calcul de la limite commune des suites un et vn en fonction de a et b n’est pas trivial au premier abord. Il est relié aux intégrales elliptiques, plus précisément on peut construire une intégrale dépendant de deux paramètres a et b et qui est invariante par la transformation un,vn → un+1,vn+1 (42)

I(a,b)=

∫

+∞
−∞

dt

√

(a2+t2)(b2+t2)

On a en effet

I(

a+b
2

,

√

ab

) =

∫

+∞
−∞

du

√

((

a+b
2

)2+u2)(ab+u2)

On pose alors

u=

1
2

(t−

ab
t

), t>0

où t → u est une bijection croissante de t∈]0,+∞[ vers u ∈ ]−∞,+∞[, donc

I(

a+b
2

,

√

ab

)

=

∫

+∞
0

dt/2(1+ab/t2)

√

((

a+b
2

)2+1/4(t−ab/t)2)(ab+1/4(t−ab/t)2)

=

2

∫

+∞
0

dt

√

(a2+t2)(b2+t2)

= I(a,b)

On note au passage que I est définie si a,b ∈ ℂ vérifient ℜ(a)>0, ℜ(b)>0, on peut montrer que la relation ci-dessus s’étend (par holomorphie).

Lorsque a=b=l (par exemple lorsqu’on est à la limite), le calcul de I(l,l) est explicite

I(l,l)=

∫

+∞
−∞

dt
(l2+t2)

=

π
l

donc

I(a,b)=I(M(a,b),M(a,b))=

π
M(a,b)

On peut transformer I(a,b) en posant t=bu

I(a,b)=2

∫

+∞
0

du

√

(a2+b2u2)(1+u2)

=

2
a

∫

+∞
0

du

√

(1+(b/a)2u2)(1+u2)

Puis en posant u=tan(x) (du=(1+u2) dx)

I(a,b)=

2
a

∫

π
2

0

√

1+tan(x)2
1+(b/a)2tan(x)2

dx

et enfin en posant tan2(x)=sin(x)2/1−sin(x)2

I(a,b)=

2
a

∫

π
2

0

√

1

1−(1−

b2
a2

)sin(x)2

dx

Si on définit pour m<1

K(m)=

∫

π
2

0

dx

√

1−m sin(x)2

alors on peut calculer K en fonction de I, en posant m=1−b2/a2 soit b2/a2=1−m

K(m)=

a
2

I(a,a

√

1−m

)=

a
2

π

M(a,a

√

1−m

)

=

π

2M(1,

√

1−m

)

d’où l’on déduit la valeur de l’intégrale elliptique en fonction de la moyenne arithmético-géométrique :

K(m)=

∫

π
2

0

dx

√

1−m sin(x)2

=

π

2M(1,

√

1−m

)

(45)

Dans l’autre sens, pour x et y positifs

K( (

x−y
x+y

)2 )=

π

2M(1,

√

1−(

x−y
x+y

)2

)

=

π

2M(1,

2
x+y

√

xy

)

=

π

2

2
x+y

M(

x+y
2

,

√

xy

)

=

π
4

x+y
M(x,y)

et finalement

M(x,y)=

π
4

x+y

K

⎛
⎜
⎜
⎝

(

x−y
x+y

⎞
⎟
⎟
⎠

2

)

### 12.3 Application : calcul efficace du logarithme.

On peut utiliser la moyenne arithmético-géométrique pour calculer le logarithme efficacement, pour cela on cherche le développement asymptotique de K(m) lorsque m tend vers 1. Plus précisément, on va poser 1−m=k2 avec k ∈ ]0,1], donc

K(m)=

∫

π
2

0

dx

√

1−(1−k2) sin(x)2

=

∫

π
2

0

dy

√

1−(1−k2) cos(y)2

en posant y=π/2−x, et

K(m)=

∫

π
2

0

dy

√

sin(y)2+k2 cos(y)2

la singularité de l’intégrale pour k proche de 0 apparait lorsque y est proche de 0. Si on effectue un développement de Taylor en y=0, on trouve

sin(y)2+k2 cos(y)2 = k2 + (1−k2) y2 + O(y4)

Il est donc naturel de comparer K(m) à l’intégrale

J=

∫

π
2

0

dy

√

k2 + (1−k2) y2

qui se calcule en faisant par exemple le changement de variables

y=

k

√

1−k2

sinh(t)

ou directement avec Xcas,

`supposons(k>0 && k<1);`
`J:=int(1/sqrt(k^2+(1-k^2)*y^2),y,0,pi/2)`

qui donne après réécriture :

J=

1

√

1−k2

⎛
⎜
⎜
⎜
⎜
⎝

ln

⎛
⎜
⎜
⎝

π
k

⎞
⎟
⎟
⎠

+ ln

⎛
⎜
⎜
⎜
⎜
⎝

1
2

⎛
⎜
⎜
⎜
⎜
⎝

√

1−k2 +4

k2
π2

+

√

1−k2

⎞
⎟
⎟
⎟
⎟
⎠

⎞
⎟
⎟
⎟
⎟
⎠

⎞
⎟
⎟
⎟
⎟
⎠

(46)

et on peut calculer le développement asymptotique de J en 0

`series(J,k=0,5,1)`

qui renvoie :

J =ln

⎛
⎜
⎜
⎝

π
k

⎞
⎟
⎟
⎠

+O(

⎛
⎜
⎜
⎝

−1
ln(k)

⎞
⎟
⎟
⎠

5

)

on peut alors préciser ce développement par

`series(J+ln(k)-ln(pi),k=0,5,1)`

qui renvoie (après simplifications et où la notation Õ peut contenir des logarithmes)

⎛
⎜
⎜
⎝

1
π2

+

ln(π)−ln(k)−1
2

⎞
⎟
⎟
⎠

k2 + Õ(k4)

donc

J=−ln(k)+ln(π)+

⎛
⎜
⎜
⎝

1
π2

+

ln(π)−ln(k)−1
2

⎞
⎟
⎟
⎠

k2 + Õ(k4) (47)

Examinons maintenant K−J, il n’a plus de singularité en y=0, et il admet une limite lorsque k → 0, obtenue en remplacant k par 0

(K−J)|k=0 =

∫

π
2

0

⎛
⎜
⎜
⎝

1
sin(y)

−

1
y

⎞
⎟
⎟
⎠

dy =

⎡
⎢
⎢
⎣

ln

⎛
⎜
⎜
⎝

tan

⎛
⎜
⎜
⎝

y
2

⎞
⎟
⎟
⎠

⎞
⎟
⎟
⎠

− ln(y)

⎤
⎥
⎥
⎦

π
2

0

= ln(

4
π

)

D’où pour K

Kk → 0 = ln

⎛
⎜
⎜
⎝

4
k

⎞
⎟
⎟
⎠

+ O(

⎛
⎜
⎜
⎝

−1
ln(k)

⎞
⎟
⎟
⎠

5

)

Pour préciser la partie du développement de K en puissances de k, nous allons majorer K−J−ln(4/π), puis J−ln(π/k). Posons

A=sin(y)2+k2 cos(y)2, B=y2+(1−y2)k2

Majoration de K−J−ln(4/π)
L’intégrand de la différence K−J−ln(4/π) est

1

√

A

−

1

√

B

−

⎛
⎜
⎜
⎝

1
sin(y)

−

1
y

⎞
⎟
⎟
⎠

=

√

B

−

√

A

√

A

√

B

−

y−sin(y)
ysin(y)

(48)

=

B−A

√

A

√

B

(

√

A

+

√

B

)

−

y−sin(y)
ysin(y)

(49)

=

(y2−sin(y)2)(1−k2)

√

A

√

B

(

√

A

+

√

B

)

−

y−sin(y)
ysin(y)

(50)

Soit

K−J−ln(

4
π

)=

∫

π
2

0

(y−sin(y))[(1−k2)y sin(y)(y+sin(y))−

√

AB

(

√

A

+

√

B

)]

√

A

√

B

(

√

A

+

√

B

)ysin(y)

(51)

On décompose l’intégrale en 2 parties [0,k] et [k,π/2]. Sur [0,k] on utilise (49), on majore chaque terme séparément et on minore A et B par

A=k2+(1−k2)sin(y)2 ≥ k2, B=k2+(1−k2)y2 ≥ k2

Donc

|

∫

k
0

|

≤

∫

k
0

|B−A|
2k3

dy +

∫

k
0

(

1
sin(y)

−

1
y

) dy

≤

∫

k
0

y2−sin(y)2
2k3

dy + ln(tan(

k
2

)) −ln(

k
2

)

≤

1
3

k3+

−1
2

k+

1
4

sin(2 k)

2 k3

+ ln(sin(

k
2

)) −ln(

k
2

) − ln(cos(

k
2

))

≤

1
3

k3+

−1
2

k+

1
4

(2k−

8k3
6

+

32k5
5!

2 k3

− ln(cos(

k
2

))

≤

k2
30

− ln(1−

1
2!

⎛
⎜
⎜
⎝

k
2

⎞
⎟
⎟
⎠

2

)

≤

k2
30

+

k2
4

Sur [k,π/2], on utilise (51) et on minore A et B par

A=sin(y)2+k2 cos(y)2 ≥ sin(y)2, B=y2+(1−y2)k2 ≥ y2

on obtient

|

∫

π
2

k

| ≤

∫

π
2

k

(y−sin(y))|C|
y sin(y) (y+sin(y))

,

où :

C

=

(1−k2)y sin(y)(y+sin(y))−A

√

B

+B

√

A

=

−A(

√

B

−y)−B(

√

A

−sin(y)) −Ay−Bsin(y) + (1−k2)y sin(y)(y+sin(y))

=

−A(

√

B

−y)−B(

√

A

−sin(y)) − k2(y+sin(y))

Donc

|C|

≤

A(

√

B

−y)+B(

√

A

−sin(y)) + k2(y+sin(y))

≤

A

B−y2

√

B

+y

+ B

A−sin(y)2

√

A

+sin(y)

+ k2(y+sin(y))

≤

A

k2
2y

+ B

k2
2sin(y)

+ k2(y+sin(y))

et

|

∫

π
2

k

| ≤

∫

π
2

k

(y−sin(y))k2(

A
2y

+

B
2sin(y)

+ (y+sin(y)))

y sin(y) (y+sin(y))

On peut majorer y−sin(y) ≤ y3/6, donc

|

∫

π
2

k

| ≤

k2
6

∫

π
2

k

Ay
2sin(y) (sin(y)+y)

+

By2
sin(y)2(sin(y)+y)

+

y2
sin(y)

On majore enfin A et B par 1,

|

∫

π
2

k

| ≤

k2
6

∫

π
2

k

y
2sin(y)2

+

y2
sin(y)

Le premier morceau se calcule par intégration par parties

k2
6

∫

π
2

k

y
2sin(y)2

=

k2
6

⎛
⎜
⎜
⎜
⎜
⎝

[−

y
tan(y)

]kπ/2 +

∫

π
2

k

1
tan(y)

⎞
⎟
⎟
⎟
⎟
⎠

=

k2
6

⎛
⎜
⎜
⎝

k
tan(k)

+ [ln(sin(y))]

π
2

k

⎞
⎟
⎟
⎠

=

k2
6

⎛
⎜
⎜
⎝

k
tan(k)

−ln(sin(k))

⎞
⎟
⎟
⎠

≤

k2
6

(1−ln(k))

Le deuxième morceau se majore en minorant sin(y)≥ (2y)/π

k2
6

∫

π
2

k

y2
sin(y)

≤

k2
6

∫

π
2

0

π
2

y =

k2π3
96

Finalement

|K−J−ln(

4
π

)| ≤ k2

⎛
⎜
⎜
⎝

−

1
6

ln(k) +

π3
96

+

1
6

+

1
30

+

1
4

⎞
⎟
⎟
⎠

où J est donné en (46).

Majoration de J−ln(π/k)
On a

|J − ln

⎛
⎜
⎜
⎝

π
k

⎞
⎟
⎟
⎠

| =

⎪
⎪
⎪
⎪
⎪
⎪

(

1

√

1−k2

−1) ln

⎛
⎜
⎜
⎝

π
k

⎞
⎟
⎟
⎠

+

1

√

1−k2

ln

⎛
⎜
⎜
⎜
⎜
⎝

1
2

⎛
⎜
⎜
⎜
⎜
⎝

√

1−k2 +4

k2
π2

+

√

1−k2

⎞
⎟
⎟
⎟
⎟
⎠

⎞
⎟
⎟
⎟
⎟
⎠

⎪
⎪
⎪
⎪
⎪
⎪

et on va majorer la valeur absolue de chaque terme de la somme. Pour k≤ 1/2, on a

1

√

1−k2

−1=

k2

√

1−k2

+1−k2

≤

k2

3/4+

√

3

/2

Pour le second terme, on majore le facteur 1/√1−k2 par 2/√3, l’argument du logarithme est inférieur à 1 et supérieur à

1
2

(1 −

k2
2

+1−

k2(1−

4
π2

)

2

) = 1 − k2 ( 1−

1
π2

) > 1−k2

donc le logarithme en valeur absolue est inférieur à

2 k2

donc, pour k≤ 1/2,

|J−ln

⎛
⎜
⎜
⎝

π
k

⎞
⎟
⎟
⎠

| ≤

k2

3/4+

√

3

/2

ln

⎛
⎜
⎜
⎝

π
k

⎞
⎟
⎟
⎠

+ k2

4

√

3

Finalement, pour k<1/2

|K−ln

⎛
⎜
⎜
⎝

4
k

⎞
⎟
⎟
⎠

| ≤ k2

⎛
⎜
⎜
⎜
⎜
⎝

lnπ

3/4+

√

3

/2

+

4

√

3

+

π3
96

+

9
20

− (

1

3/4+

√

3

/2

+

1
6

) ln(k)

⎞
⎟
⎟
⎟
⎟
⎠

(52)

que l’on peut réécrire

|

π
2M(1,k)

−ln

⎛
⎜
⎜
⎝

4
k

⎞
⎟
⎟
⎠

| ≤ k2(3.8−0.8ln(k)) (53)

La formule (53) permet de calculer le logarithme d’un réel positif avec (presque) n bits lorsque k ≤ 2−n/2 (ce à quoi on peut toujours se ramener en calculant le logarithme d’une puissance 2m-ième de x ou le logarithme de 2mx, en calculant au préalable ln(2)). Par exemple, prenons k=2−27, on trouve (en 8 itérations) M(1,2−27)=M1=0.0781441403763. On a, avec une erreur inférieure à 19 × 2−54=1.1× 10−15

M(1,2−27)=M1=

π
2ln(229)

=

π
58ln(2)

,

On peut donc déduire une valeur approchée de π si on connait la valeur approchée de ln(2) et réciproquement. Si on veut calculer les deux simultanément, comme les relations entre ln et π seront des équations homogènes, on est obligé d’introduire une autre relation. Par exemple pour calculer une valeur approchée de π on calcule la différence ln(229+1)−ln(229) dont on connait le développement au premier ordre, et on applique la formule de la moyenne arithmético-géométrique. Il faut faire attention à la perte de précision lorsqu’on fait la différence des deux logarithmes qui sont très proches, ainsi on va perdre une trentaine de bits, il faut grosso modo calculer les moyennes arithmético-géométrique avec 2 fois plus de chiffres significatifs.

L’intérêt de cet algorithme apparait lorsqu’on veut calculer le logarithme avec beaucoup de précision, en raison de la convergence quadratique de la moyenne arithmético-géométrique (qui est nettement meilleure que la convergence linéaire pour les développements en série, ou logarithmiquement meilleure pour l’exponentielle), par contre elle n’est pas performante si on ne veut qu’une dizaine de chiffres significatifs. On peut alors calculer les autres fonctions transcendantes usuelles, telle l’exponentielle, à partir du logarithme, ou les fonctions trigonométriques inverses (en utilisant des complexes) et directes.

On trouvera dans Brent-Zimmermann quelques considérations permettant d’améliorer les constantes dans les temps de calcul par rapport à cette méthode (cela nécessite d’introduire des fonctions spéciales θ) et d’autres formules pour calculer π.

On peut ensuite à partir du logarithme, calculer l’exponentielle en utilisant la méthode de Newton, rappelée ci-dessous.

### 12.4 La méthode de Newton.

La méthode de Newton est une méthode de résolution de l’équation f(x)=0, attention à la différence avec le théorème du point fixe qui permet de résoudre numériquement f(x)=x. Si x0 est proche de la racine r on peut faire un développement de Taylor à l’ordre 1 de la fonction f en x0 :

f(x)=f(x0)+(x−x0)f′(x0)+O((x−x0)2)

Pour trouver une valeur approchée de r, on ne garde que la partie linéaire du développement, on résout :

f(r)=0 ≈ f(x0) + (r−x0) f′(x0)

donc (si f′(x0)≠ 0) :

r ≈ x0 −

f(x0)
f′(x0)

Graphiquement, cela revient à tracer la tangente à la courbe représentative de f et à chercher où elle coupe l’axe des x. On considère donc la suite récurrente définie par une valeur u0 proche de la racine et par la relation :

un+1 = un −

f(un)
f′(un)

Il y a deux théorèmes importants, l’un d’eux prouve que si u0 est “assez proche” de r alors la suite un converge vers r, malheureusement il est difficile de savoir en pratique si on est “assez proche” de u0 pour que ce théorème s’applique. Le second théorème donne un critère pratique facile à vérifier qui assure la convergence, il utilise les propriétés de convexité de la fonction.

Théorème 14 Soit f une fonction de classe C2 (2 fois continument dérivable) sur un intervalle fermé I. Soit r une racine simple de f située à l’intérieur de I (telle que f(r)=0 et f′(r)≠ 0). Alors il existe ε>0 tel que la suite définie par

un+1 = un −

f(un)
f′(un)

, |u0−r| ≤ ε

converge vers r.

Si on a |f′′| ≤ M et |1/f′| ≤ m sur un intervalle [r−η,r+η] contenu dans I, alors on peut prendre tout réel ε>0 tel que ε < 2/(mM) et ε ≤ η.

Démonstration : on a

un+1−r = un − r −

f(un)
f′(un)

=

(un−r)f′(un)−f(un)
f′(un)

En appliquant un développement de Taylor de f en un à l’ordre 2, on obtient pour un réel θ situé entre r et un :

0 = f(r)=f(un)+(r−un) f′(un) + (r−un)2

f′′(θ)
2

donc :

(un−r)f′(un)−f(un)= (un−r)2

f′′(θ)
2

d’où :

|un+1−r| ≤ |un−r|2

1
|f′(un)|

|f′′(θ)|
2

On commence par choisir un intervalle [r−ε,r+ε] contenant strictement r et tel que |f′′|<M et |1/f′|<m sur [r−ε,r+ε] (c’est toujours possible car f′′ et 1/f′ sont continues au voisinage de r puisque f′(r)≠ 0). Si un est dans cet intervalle, alors θ aussi donc

|un+1−r| ≤ |un−r|2

Mm
2

≤

|un−r|Mm
2

|un−r|,

On a |un−r| ≤ ε, on diminue si nécessaire ε pour avoir ε < 2/(Mm), on a alors :

|un+1−r| ≤ k |un−r|, k=

ε Mm
2

<1

donc d’une part un+1 est encore dans l’intervalle [r−ε,r+ε] ce qui permettra de refaire le même raisonnement au rang suivant, et d’autre part on a une convergence au moins géométrique vers r. En fait la convergence est bien meilleure lorsqu’on est proche de r grace au carré dans |un−r|2, plus précisément, on montre par récurrence que

|un−r| ≤ |u0 − r|2n

⎛
⎜
⎜
⎝

Mm
2

⎞
⎟
⎟
⎠

2n−1

il faut donc un nombre d’itérations proportionnel à ln(n) pour atteindre une précision donnée.

Remarque : ce théorème se généralise sur ℂ et même sur ℝn.

Exemple : pour calculer √2, on écrit l’équation x2−2=0 qui a √2 comme racine simple sur I=[1/2,2], on obtient la suite récurrente

un+1 = un −

un2−2
2un

Si on prend η=1/2, on a f′=2x et f′′=2 donc on peut prendre M=2 et m=1 car |1/f′|≤ 1 sur [√2−1/2,√2+1/2]. On a 2/(mM)=1, on peut donc prendre ε=1/2, la suite convergera pour tout u0 ∈ [√2−1/2,√2+1/2].

Plus générallement, on peut calculer une racine k-ième d’un réel a en résolvant f(x)=xk−a par la méthode de Newton.

L’inconvénient de ce théorème est qu’il est difficile de savoir si la valeur de départ qu’on a choisie se trouve suffisamment près d’une racine pour que la suite converge. Pour illustrer le phénomène, on peut par exemple colorer les points du plan complexe en n+1 couleurs selon que la suite définie par la méthode de Newton converge vers l’une des n racines d’un polynôme de degré n fixé au bout de par exemple 50 itérations (la n+1-ième couleur servant aux origines de suite qui ne semblent pas converger).

Passons maintenant à un critère très utile en pratique :

Définition 1 (convexité)
Une fonction f continument dérivable sur un intervalle I de ℝ est dite convexe si son graphe est au-dessus de la tangente en tout point de I.

Il existe un critère simple permettant de savoir si une fonction de classe C2 est convexe :

Théorème 15 Si f est C2 et f′′ ≥ 0 sur I alors f est convexe.

Démonstration :
L’équation de la tangente au graphe en x0 est

y=f(x0)+f′(x0)(x−x0)

Soit

g(x)=f(x)−(f(x0)+f′(x0)(x−x0))

on a :

g(x0)=0, g′(x)=f′(x)−f′(x0), g′(x0)=0, g′′=f′′ ≥ 0

donc g′ est croissante, comme g′(x0)=0, g′ est négative pour x<x0 et positive pour x>x0, donc g est décroissante pour x<x0 et croissante pour x>x0. On conclut alors que g ≥ 0 puisque g(x0)=0. Donc f est bien au-dessus de sa tangente.

On arrive au deuxième théorème sur la méthode de Newton

Théorème 16 Si f(r)=0, f′(r)>0 et si f′′ ≥ 0 sur [r,b] alors pour tout u0 ∈ [r,b] la suite de la méthode de Newton

un+1 = un −

f(un)
f′(un)

,

est définie, décroissante, minorée par r et converge vers r. De plus

0 ≤ un −r ≤

f(un)
f′(r)

Démonstration :
On a f′′ ≥ 0 donc si f′(r)>0 alors f′>0 sur [r,b], f est donc strictement croissante sur [r,b] on en déduit que f>0 sur ]r,b] donc un+1 ≤ un. Comme la courbe représentative de f est au-dessus de la tangente, on a un+1 ≥ r (car un+1 est l’abscisse du point d’intersection de la tangente avec l’axe des x). La suite un est donc décroissante minorée par r, donc convergente vers une limite l≥ r. À la limite, on a

l=l−

f(l)
f′(l)

⇒ f(l)=0

donc l=r car f>0 sur ]r,b].

Comme (un) est décroissante, on a bien 0 ≤ un −r, pour montrer l’autre inégalité, on applique le théorème des accroissements finis, il existe θ ∈ [r,un] tel que

f(un)−f(r)=(un−r)f′(θ)

comme f(r)=0, on a

un−r =

f(un)
f′(θ)

et la deuxième inégalité du théorème en découle parce que f′ est croissante.

Variantes :
Il existe des variantes, par exemple si f′(r)<0 et f′′ ≥ 0 sur [a,r]. Si f′′ ≤ 0, on considère g=−f.

Application :
On peut calculer la valeur approchée de la racine k-ième d’un réel a>0 en appliquant ce deuxième théorème. En effet si a>0, alors xk−a est 2 fois continument dérivable et de dérivée première kxk−1 et seconde k(k−1)xk−2 strictement positives sur ℝ+∗ (car k ≥ 2). Il suffit donc de prendre une valeur de départ u0 plus grande que la racine k-ième, par exemple 1+a/k (en effet (1+a/k)k ≥ 1+k a/k=1+a). En appliquant l’inégalité du théorème, on a :

0 ≤ un −

⎛
⎝

a

⎞
⎠

1
k

≤

unk − a

k

⎛
⎝

a

⎞
⎠

1
k

k−1

≤

unk−a
ka

⎛
⎝

a

⎞
⎠

1
k

≤

unk−a
ka

(1+

a
k

)

Pour avoir une valeur approchée de (a)1/k à ε près, on peut donc choisir comme test d’arrêt

unk −a ≤

ka

1+

a
k

ε

Par exemple pour √2, le test d’arrêt serait un2−2 ≤ 2 ε.

1
  Certains systèmes de calcul formel (calculatrices par exemple) utilisent d’ailleurs des méthodes spécifiques pour gérer le problème de la fragmentation de la mémoire, appelés “garbage collector”. Ce type de méthode est intégré dans des langages comme Lisp ou Java, en C/C++ on trouve des libraries pour cela, par exemple GC de Boehm, incluse dans la distribution de GCC.
2
  un quartet=un demi octet
3
  Plus précisément deux piles, la pile de donnée et la pile gérant le flux d’exécution. Cette dernière n’est pas visible par l’utilisateur
4
  Sauf si on utilise comme dernier argument le nombre d’arguments de la fonction ou si on utilise (cf. infra) un tag de début de liste d’arguments
5
  Toutefois une adaptation du logiciel utilisant comme quantum de base par exemple 32 bits porterait cette limite à 6553665535−1
6
  Rappelons qu’il s’agit d’une majoration sur la valeur absolue des coefficients des facteurs de P
7
  Plus exactement, on multiplie Pj par le coefficient dominant de P modulo pl
8
  Ici |P| désigne le plus grand coefficient de P en valeur absolue
9
  cette preuve peut être sautée en première lecture
10
  Peut être omise en première lecture

Retour à la page principale de Giac/Xcas.

> Ce document a été traduit de LATEX par H E V E A