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 :

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 :

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 :

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, MuPAD, 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 (pour MuPAD, on pourrait sans doute en savoir plus en achetant de la documentation sur la programmation des modules dynamiques).

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 (=<). Les polynômes en représentation creuse ou en plusieurs indéterminées sont également disponibles.

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 premiers n, dont le produit est 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 qXp 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 qXp est un facteur de P, alors adXad/qp est encore un facteur de P (le quotient de P par adXad/qp 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 adXad/qp 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 adXad/qp est égal à ad(Xpk) dans ℤ/(nk ℤ), il nous suffit d’écrire en représentation modulaire symétrique ad(Xpk)=ad Xp′. Pour conclure, on sait que ad Xp′ est un multiple entier de qXp. On divise donc le facteur ad Xp′ 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 X3X2X−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(Xpk)=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.

2  Quelques algorithmes d’arithmétique de base.

2.1  Pour en savoir plus.

Sur des aspects plus théoriques :

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

3  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 2n (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 y2y6 −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 in−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

4  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 ( PQ ) = pgcd ( c ( P ), c ( Q )) pgcd ( pp ( P ), pp ( Q )) 

4.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:

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.







pnpn−1pn−2pn−3... 
0pnpn−1pn−2... 
qn−1qn−2qn−3qn−4... 
0qn−1qn−2qn−3... 
00qn−1qn−2...  
 





On effectue L1qn−1 L1pn L3 et L2qn−1 L2pn L4, ce qui correspond à l’élimination du terme en x du quotient de P par Q







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





on effectue ensuite

L1qn−1 L1 − (qn−1 pn−1 − pn qn−2)  L4 
L2qn−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







00r2,n−2...... 
000r2,n−2... 
qn−1qn−2qn−3qn−4... 
0qn−1qn−2qn−3... 
00qn−1qn−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−1qn−2... 
 r2,n−2...... 
 0r2,n−2... 
 


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




 00r3,n−3 
 r2,n−2...... 
 0r2,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.

4.2  Le pgcd en une variable

.

4.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 ⩽ in ( | 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 ) etQ(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

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.

4.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 nb 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 | dmj |, on commence par majorer | δk | par βk = max( 1, | δk | ). On est donc ramené à majorer

σjm ( β ) = 
 
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 km − 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

σjm ( β ) ⩽ 

     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.

4.3  Le pgcd à plusieurs variables.

4.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.

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).

4.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 α:

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:

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 ) ( y2x 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.

4.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 ( X1h X2, … ., h Xn ) = Oh → 0 ( hk ) 

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

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

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 ( Q1Q1′ ) = Q0 ( P1P1′ ), donc Q0 divise Q1Q1′ 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 = dd est un entier).
  3. Boucle infinie avec un compteur k initialisé à 1, incrémenté de 1 à chaque itération

Exemple:

F = (( x + 1 ) y + x2 + 1 ) ( y2 + x y + 1 ), G = (( x + 1 ) y + x2 + 1 ) ( y2x 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 QP0 = ( 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.

4.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.

4.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 :

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 :

5  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)=







aaaa−1a00
0aaa1a0
      ⋮ 
00    a0 
bbbb−1b000
      ⋮ 
00    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 :

bbab+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 bbab+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 bbkb(ab+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=dkdk+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 hkk 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 :

 gkk−1+1)dkRes(Ak−1,Ak)=gkdk−1dk+1 Res(gk−1 hk−1δk−1 Ak+1,Ak)
 =gkdk−1dk+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−1dk+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−1k−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−1dk+1−(δk−1+1)dk  


gkδk−1
hk
 


dk−1



 
  Res(Ak+1,Ak
 =
gkdk−1dk+1dk−δ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.

6  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

7  Exercices (PGCD, résultant, ...)

7.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);.

7.1.1  Entiers

7.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.

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

7.1.3  Calculs modulo n

Pour travailler dans ℤ/nℤ[X] :

7.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 (xyx+1)(xy+x2+1) et (xyxy)(xyx+1)

7.3  Exercices (résultant)

  1. Pour quelles valeurs de p le polynôme X5+X3pX+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=
    a2+b2+c2=
    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 x14x13−14x12+12x11+78x10−54x9−224x8+116x7+361x6−129x5−330x4+72x3+160x2−16x−32

7.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]?

7.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 
    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

7.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 rirj pour ij.

  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.

8  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.

8.1  Les facteurs multiples

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

Pk=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 :

Gk=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 Πjk Pj si kl, on en déduit que F divise le dernier terme de la somme de Z1, c’est-à-dire que F divise lPl′Πjl 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=Z1W1′=
 
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 :

On va montrer que Pm=Gm. Commençons au rang n=1, on voit que P1 divise Y1 (puisqu’il est commun à tous les Πjk 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′Πjl,j>1 Pj, donc diviserait Pl′. Le raisonnement en un rang quelconque est identique, les polynômes sont donnés par :

Gm=Pm,  Wmk>=m Pk,   Ym=k>m (km)Pk′Πj≥ mj≠ 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 Pk=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=YW′.
  3. Boucle infinie.
  4. Calculer le pgcd G de W et Y. Si G=1, on renvoie la liste résultat sinon ajouter G à la liste résultat.
  5. Simplifier W et Y par G, puis poser Y=YW′ 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.

8.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).

8.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 ϕ: xAxp. 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 ϕ: xxp dans ℤ/pℤ[X] (mod P(X) ) muni de sa base canonique { 1, X,...,Xdeg(P)−1 }.

8.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, XpX est le produit des Xk 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 XpkX, soit K le corps correspondant à F, alors le noyau de l’application linéaire

x ∈ K ↦ xpkx ∈ 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 XpkX (puisque X(pk)X est divisible par Xx pour tout xK), donc le degré de F est inférieur ou égal à k.

Donc Pk est égal au pgcd de Pj<k Pj avec XpkX.

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 XpkX (mod P )), on fait une boucle indéfinie sur k commençant à 1 et incrémenté de 1 à chaque itération

Exemple :
Factorisation en degré distincts de (X3+X+1)(X4X+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.

8.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 :

XpdXα ∈ 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 TpdT. En remplaçant X par T ci-dessus, on en déduit :

TpdTα ∈ K (T−α) 

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

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

Donc TpdT est divisible par XpdX (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

  TpdT=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 TpdT 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(Ud−1) et degre(Vd−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.

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=x4x3+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:=x4x3+x+2, on trouve T62=1 (mod P ), donc ce T n’aurait pas permis de casser P.

8.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ù ϕ: xxp). On suppose que Pj=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 QpQ=0 (mod P ), en utilisant la factorisation :

XpX= Πj ∈ ℤ/pℤ  (Xj)

on en tire P divise QpQj ∈ ℤ/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 T2jT1 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 T2jT1 donneront les Fk. Sinon il faudra continuer avec T3jT1 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+x3x2−2 et ϕ(x5)=x3+x2x. La matrice de ϕ est donc :

M=






1000−20
00100−1
0000−11
00−2211
001−120
0110−10







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 T2sT2=−x5x3x2 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+2x2x+2.

8.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

Pj=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

Pj=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é PPj (mod p ) à PPj,2 (mod p2 ). Le passage de PPj,l (mod pl ) à PPj,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:

Il existe une version quadratique de cette méthode. On passe alors de PPj,l (mod pl ) à PPj,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:

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)(X4X+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+2x2x+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+2x2x+2)+B(x−2)(x3+2x2x+2)+  
+C(x−2)(x3+x+1)=1 (mod 5 )

On commence par résoudre D(x3+2x2x+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+−9x3x2−4 et P=x7+x5+x3x2+1, donc Q=(Pabc)/5=x5x4+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 :

a1a+5 × (−2),    b1=b+5 × 0,     c1=c+5 × (2x2x

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

Q=(Pa1 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 x4x+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).

8.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 :

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

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+x3x2+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 x4x+1 en représentation symétrique qui est bien un facteur de P (donc un facteur irréductible).

8.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)

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 (Xzj

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 Pk 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 zZ, on a :

fj(X1,...,Xn,z)=c Πl ∈ R (zzj),     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 (Xzj

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 LC 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 :

8.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 Πkn−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.

8.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 kj 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 :

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é.

8.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.

8.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(XpkX,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)

9  Intégration

9.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 :

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 9.4.

9.2  Fonctions élémentaires

9.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

xf1(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:

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)=fkmgj. 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+5x3 eln(x)2+5 

9.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′=gf :

(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

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 anXn + (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−1an−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 (kPQ+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 NP QN (kPQ+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′=YX, (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 (∏ljPl ) 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)

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 :

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.

9.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 ckK′ 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,NtD′) 

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

gcd(D,Nck 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.

9.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=ex2N0=(2x2+1) XD0=1 
x ln(x)
x+ln(x)
X=ln(x)N0=xXD0=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′=fX 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)′=fX 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

9.3.1  Intégration d’une fraction propre

9.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 Pi :

Ni = AiPi+BiPi ⇒ 
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).

9.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 NtD′ :

NtD′ = 
 
k
 


(ck −tvk′ 
 
j≠ k
 vj 


donc le pgcd en X des polynômes NtD′ et D est :

Considérons le polynôme R de la variable t égal au résultant par rapport à X des polynômes D et NtD′ (rappelons qu’il s’agit du déterminant du système linéaire AD+B(NtD′)=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 NtD′ 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(Nck D′,D)) 

Exemples

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.

9.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).

9.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.

9.3.6  Extension exponentielle

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

 
j
 (Aj′+j YAjXj = 
 
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′+2xA1a(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 :

yN1 Pα+..., fN2 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 Ntf1′ 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′ + f0yα=0 

donc :

yα= exp(−α zf0)

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 ts, 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 Z=ln(z): exponentielle de logarithme
Ici aussi, les Nk peuvent ne pas être constants, on a :

N′=
n
k=0
 (NkZk+kNk 
z
z
 Zk−1)

Si Nn n’est pas constant, le terme de plus haut degré de RN′ est NnRr 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.

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 NV. Soit H=(NV)/R. Alors N=RH+V donc

R (RH′+RH+V′)+SRH+SVT=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.

9.4  Quelques références

10  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=(ba)/n est le pas de la subdivision, et sur chaque subdivision, on approche l’aire sous la courbe.

10.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)

h=(ba)/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(tdt − 
β


α
 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(tdt − 
β


α
 g(tdt | ≤ 
β


α
 |
f′′(ξx)
2
 (x−α)(x−β)| ≤ M2 
(β−α)3
12
 

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=(ba)/h subdivisions de longueur β−α=h, on obtient donc une majoration de l’erreur commise sur l’intégrale :

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.

10.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(tdt ≈ 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(tdt ≈ 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 :

  |
β


α
 fI(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
 |wjMn+1 
(yj−α)n+1
(n+1)!
 
 
k
j=1
 |wjMn+1 
(β−α)n+1
(n+1)!

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

|
β


α
 fI(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
 |wjMn+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
 fI(f)| ≤ Mn+1 
hn+1
2n+1(n+1)!
  (ba)  (
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.

10.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
 (baM4 

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).

10.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 (ba

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

|
b


a
 f −I(f)| ≤ 
M6
1935360
 h6 (ba

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 ∫fI(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.

10.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]

 formuleLagrange degréordreerreur
rectangles(24), (25)00M1 h (ba)/2
point milieu(26)01M2 h2 (ba)/24
trapèzes(27)11M2 h2 (ba)/12
Simpson(29)23M4 h4 (ba)/2880

11  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).

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

11.1.1  La méthode du pivot de Gauß.

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.

11.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)ni. Donc :

 det(R)=
det(M)  
n−1
i=1
(Ri,i/(Ri−1,i−1)ni 
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.

11.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 =
ykAxk
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.

11.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, |ab| <n/2, on en déduit que ab′=ab. 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 xrk 

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=nr1=x 

et la relation de récurrence :

βk+2k − qk+2 βk+1,    qk+2=
rkrk+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 − (rkrk+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+1rk < 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;

11.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

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






uv 
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.

11.2  Réduction des endomorphismes

11.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 
24

) . On prend v=(1,0), la matrice à réduire est alors :



1−1−11 
21038


→ 

10−6 
015


Le noyau est engendré par (−6,5,−1) donc P=−x2+5x−6.

Exemple 2

A=


 32−2 
−10
11



en prenant v=(1,0,0) on obtient la matrice :

A=


135
0−1−2−3 
0123






10−1−2 
012
000



le permier vecteur du noyau est (−1,2,−1) d’où un polynôme divisant le polynôme minimal −x2+2x−1.

11.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:

11.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 im+2, soit u=Hi,m/Hm+1,m, on remplace alors la ligne Li de H par LiuLm+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
u1

) et à droite par la matrice inverse (

1
u1

) (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 :








H1,1H1,2...H1,n−2H1,n−1H1,n
H2,1H2,2...H2,n−2H2,n−1H2,n 
0H3,2...H3,n−2H3,n−1H3,n 
00...H4,n−2H4,n−1H4,n 
...⋮ 
00...0Hn,n−1Hn,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(λ InH)=(λ−Hn,nhn−1(λ) −(−Hn−1,n) (−Hn,n−1hn−2(λ) + 
      + (−Hn−2,n) (−Hn,n−1) (−Hn−1,n−2hn−3(λ) − ...

où les hi s’entendent en gardant les i premières lignes/colonnes de H′. On peut écrire cette formule pour mn :

hm(λ)= (λ − Hm,mhm−1(λ) −
m−1
i=1
 Hmi,m 
i−1
j=1
 Hmj+1,mj 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 ∏Hmj+1,mj.

11.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(λ IA) et des coefficients matriciels Bi (i=0..n−1) du polynôme en λ donnant la matrice adjointe (ou comatrice) B(λ) de λ IA :

  (λ 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 λ IA est P(A).

Pour déterminer simultanément les pk et Bk, on a les relations de récurrence :

 Bn−1=pn I=I,    BkABk+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 λ IA
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 λ IA et bi,j(λ) les coefficients de B, on a :

P′(λ0)=det(V1(λ),V2(λ),...,Vn(λ) )′ |λ=λ0
 =det(V10),V20),...,Vn0) )+ det(V10),V20),...,Vn0) )+ 
  +...+det(V10),V20),...,Vn0) )

Il suffit alors de remarquer que Vi0) est le i-ième vecteur de la base canonique donc :

det(V10),V20),...,Vi0),...,Vn0) ) =bi,i0

Finalement :

P′(λ0)=
n
i=1
 bi,i0)=tr (B0)) 

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−1In−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;

11.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)B0)=P0)I=0, on voit que les vecteurs colonnes de la matrice B0) sont vecteurs propres. Remarquer que B0) ≠ 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 B0) par la méthode de Horner appliquée au polynôme B(λ) en λ=λ0, et on réduit en colonnes la matrice obtenue.

11.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)


Bi )+ 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 IB(λ i)=0    (33)
(A−λ i IB′(λ i)=Bi )    (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 Bi) jusqu’à ce que l’on obtienne une matrice réduite en recopiant les opérations élémentaires de colonnes faites sur Bi) 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 Bi) 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 Bi)≠ 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 Bi)= 0).

11.2.7  Exemple 1

A=


 3−1
20
1−1



λ =2 est valeur propre de multiplicité 2, on obtient :

B(λ )= λ 2 I + λ 


 −2−1
2−5
1−1−3 






 11−1 
−35−1 
−22



on applique l’algorithme de Horner :

B(2)=



 1−1
1−1
00



,
B′(2)=



 2−1
2−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+C1C2 et C3C1C3. On effectue les mêmes opérations sur B′(2) et on obtient :




 10
10
00






 21−1 
21−1
10



L’étape suivante consiste à déplacer vers le bas d’une matrice les colonnes non nulles de la matrice du haut, on obtient :




 11−1 
11−1
00



qui se réduit en :




 10
100
00



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).

11.2.8  Exemple 2

A=


 32−2 
−10
11



λ =1 est valeur propre de multiplicité 3. On trouve :

B(1)=



00
00
00



B′(1)=



22−2 
−1−1
11−1 



 B′′(1)
2
=



10
01
00



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 C2C1C2 et C3+C1C3 et on obtient:




20
−10
10



 


1−1
01
00



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
−11
10



qu’on réduit par les opérations 2C2 +C1C2 et 2C3C1C3 en :




20
−11
11



Puis on effectue C3C2C3 et la deuxième colonne nous donne le deuxième cycle de Jordan, réduit ici à un seul vecteur propre (0,1,1).

11.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 à nikk est le plus grand entier tel que :

∀ j<k,    B(j)i)=0 

11.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 (λ IA) ∑kn−1 Bk λk=P(λ)I. On observe que Q(λ)IQ(A) est divisible par (λ IA) 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(λ)=∑kn−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(ACk+1 

ce qui donne une colonne de matrice Cq−1Cq−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 :












00...q0 00...1... 
10...q1 00...0...
01...q2 00...0...
... ......
00...qd−1 00...0... 
 
00...0 00...q0... 
00...0 10...q1... 
... ......











Exemple
Soit la matrice

A=


















1−24−25−4 
01
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
 
002−23−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 :





020
100
000
0010
 



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
...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

vjm,lm     (39)

On remplace dans (38) d’où :

Ad vj,0 − 
inf(d,j)
m=1
 
d
 
m

vjm,lm
d
l=0
  ql (Al vj,0 − 
inf(l,j)
m=1
 
l
 
m

vjm,lm )=0

finalement :

  Q(Avj,0
d
l=1
  ql 
inf(l,j)
m=1
 
l
 
m

vjm,lm      (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(Av1,0 = 
2
l=1
ql 
inf(l,1)
m=1
 
l
 
m

v1−m,lm  =2v0,1 

donc  :

 v1,0=2A(0,4,−4,8,4,−4)=(−8,−32,0,−48,−16,16) 
 v1,1=Av1,0v0,0=(4,40,−4,64,24,−20) 

On vérifie bien que Av1,1=2v1,0+v0,1.

11.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−1D=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

11.3  Quelques autres algorithmes utiles

11.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,1a1,2 
a2,1a2,2 




b1,1b1,2 
b2,1b2,2 


=

c1,1c1,2 
c2,1c2,2 


On calcule :

s1=a2,1+a2,2,    s2=s1a1,1,     s3=a1,1− a2,1,    s4=a1,2s2
t1=b1,2b1,1,    t2=b2,2t1,    t3=b2,2b1,2,    t4=b2,1t2

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 
u1p1+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.

11.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 à (MrI)−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.

11.3.3  Décomposition de Schur

Il s’agit d’une factorisation de matrice sous la forme

A = P S P−1

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 Q1R1 
 =Q1 (Q2 R2) (Q2 R2) .. (Q2 R2R1 
 =Q1 Q2 (R2 Q2R2 .. 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 |Dk 

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=RkQkk 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)IR1  Q1(R1Q1−(α3−α1)IR1...(Q1R1−(α2−α1)I)
 =Q1 (A2 − α2 I) (A2 − α3 I) ... (A2 − αk−1IR1
 =...
 =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=QR 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



QQ11QQ12 
QQ21QQ22 
 



R11R12 
0R22 
 

=


QQ11 R11QQ21R11 
QQ11 R12 + QQ12 R22QQ21 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+EU 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
 (AzI)−1 

En prenant A=Se, et en écrivant

(SezI)−1 = (UzI+E)−1 = ( I + (UzI)−1E)−1(UzI)−1  

on développe le second terme si la norme de (UzI)−1E est strictement inférieure à 1

(SezI)−1 = (UzI)−1 −(UzI)−1E(UzI)−1 + (UzI)−1E(UzI)−1E(UzI)−1 + ...

puis on calcule la trace

trace(SezI)−1 = 
 
j
 (µjz)−1 + η 

avec

|η| ≤ 2π α || (UzI)−1 || 
|| (UzI)−1E ||
1−|| (UzI)−1E ||

Au final, le nombre de valeurs propres dans C est donné par

1 + η,    |η| ≤  α maxz ∈ C || (UzI)−1 || 
|| (UzI)−1E ||
1−|| (UzI)−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).

11.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).

11.4  Quelques références

11.5  Exercices (algèbre linéaire)

11.5.1  Instructions

11.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(λ IA), 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
    20
    1−1



    ,     A=


     32−2 
    −10
    11



  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.

12  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.

12.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.

12.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 PQ 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 (Xxj), 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
 (Xxj

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+1xj) = yn+1 

Comme tous les xj sont distincts, il existe une solution unique a :

a=
yn+1Pn(xn+1)
n
j=0
 (xn+1xj)

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+XX(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 xI, 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
(xxj)      (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(xxj)| 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
(xxj

on considère maintenant la fonction :

g(t)=f(t)−P(t) − C 
n
j=0
(txj

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(xxj) − 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)!
 

12.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 (xx0) + ... + αn (xx0)...(xxn−1
 =α0 + (xx0)( α1 + (xx1)(α2 +  ... + (xxn−2)(αn−1+(xxn−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)
x1x0
 

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+1xi
 

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+1x)Pk + (xx0)Qk
xk+1x0

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+1x0, 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

xif[xi]f[xi,xi+1]f[x0,x1,x2
0
1
  
  
(2−1)/(1−0)=
1
 
12 
(−1−1)/(2−0)=
-1
   
  (1−2)/(2−1)=−1 
21  

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)

12.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.

13  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.

13.1  Définition et convergence

Soient a et b deux réels positifs, on définit les 2 suites

  u0=av0=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+1vn+1=
1
2
(
un
vn
)2 =
1
2(
un
+
vn
)2
(unvn)2     (43)

la convergence est quadratique.

On suppose dans la suite que ab 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 unvn (d’après (43) pour n>0) et un+1un car

un+1un=
1
2
(vnun) ≤ 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 ab>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/vnm (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≤ ab ≤ 1−e−0.1. Alors l’équation (43) entraine

un+1vn+1 ≤ 
1
8
(unvn)2 

puis (par récurrence)

0 ≤ unvn ≤ 
1
82n−1
(ab)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 2n 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/vnn eiθn, on a :

|
un+1
vn+1
|
=
1
2





ρn
 eiθn/2
1
ρn
 eiθ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.

13.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,vnun+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 

tu 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(tab/t)2)(ab+1/4(tab/t)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( (
xy
x+y
)2 )=  
π
2M(1,
1−(
xy
x+y
)2
)
=  
π
2M(1,
2
x+y
xy
)
π
2
x+y
 M(
x+y
2
,
xy
π
4
 
x+y
M(x,y)

et finalement

M(x,y)=
π
4
 
x+y
 K


(
xy
x+y



2



 
 )

13.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−k2y2 + O(y4)

Il est donc naturel de comparer K(m) à l’intégrale

J=
π
2


0
 
dy
k2 + (1−k2y2
 

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 KJ, il n’a plus de singularité en y=0, et il admet une limite lorsque k → 0, obtenue en remplacant k par 0

(KJ)|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 KJ−ln(4/π), puis J−ln(π/k). Posons

A=sin(y)2+k2 cos(y)2,    B=y2+(1−y2)k2

Majoration de KJln(4/π)
L’intégrand de la différence KJ−ln(4/π) est

     
1
A
 − 
1
B
 − 


1
sin(y)
1
y
 


=
B
A
A
 
B
 −
y−sin(y)
ysin(y)
 
    (48)
 =
BA
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

  KJ−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
 
|BA|
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)
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!
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)) −AyBsin(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 
By2
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

|KJ−ln(
4
π
)|  ≤ k2 


1
6
 ln(k) + 
π3
96
 + 
1
6
 + 
1
30
1
4
 


J est donné en (46).

Majoration de Jln(π/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 à

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 ≤ 2n/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,227)=M1=0.0781441403763. On a, avec une erreur inférieure à 19 × 2−54=1.1× 10−15

M(1,227)=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.

13.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)+(xx0)f′(x0)+O((xx0)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) + (rx0f′(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)
,    |u0r| ≤ ε 
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+1r = un − r − 
f(un)
f′(un)
 = 
(unr)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)+(runf′(un) + (run)2 
f′′(θ)
2
 

donc :

(unr)f′(un)−f(un)= (unr)2 
f′′(θ)
2
 

d’où :

|un+1r| ≤ |unr|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+1r| ≤ |unr|2 
Mm
2
 ≤  
|unr|Mm
2
|unr|,  

On a |unr| ≤ ε, on diminue si nécessaire ε pour avoir ε < 2/(Mm), on a alors :

|un+1r| ≤ k |unr|,    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 |unr|2, plus précisément, on montre par récurrence que

|unr| ≤ |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)=xka 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)(xx0

Soit

g(x)=f(x)−(f(x0)+f′(x0)(xx0)) 

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+1un. Comme la courbe représentative de f est au-dessus de la tangente, on a un+1r (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 lr. À 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 ≤ unr, 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)=(unr)f′(θ) 

comme f(r)=0, on a

unr = 
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 xka 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 
≤ 
unka
ka
  

a
1
k
 
≤ 
unka
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 HEVEA