Introduction à l'Algorithmique et Arithmétique
Introduction à l'Algorithmique et Arithmétique
html#sec27
1 Algorithmique
Dans cette section, on passe en revue les notions de bases en algorithmique au programme (B.2), en
commencant par travailler en ligne de commande (notion de variable, affectation), puis en complexifiant
au fur et à mesure la ligne de commande (test, boucle) et on termine par l’écriture de fonctions. Les
commandes des sections qui suivent peuvent être saisies et exécutées dans une ligne de commande de
Xcas, pour des programmes qui dépassent une ou deux lignes, il est conseillé d’utiliser le menu Prg, et les
assistants Test et Boucle (voir la section 1.3.2).
On pourra trouver d’autres tutoriels introduisant l’algorithmique via la géométrie ou l’arithmétique sur la
page algorithmique seconde de Xcas
[Link]/~parisse/[Link]
La syntaxe sera donnée en Xcas, avec les éléments de syntaxe permettant d’adapter à d’autres languages
utilisables à l’oral (Python, Scilab, Maxima), on ne reprendra par contre pas Free Pascal qui n’a pas
d’interpréteur en mode interactif et se prête donc moins à la démarche proposée ici, ni Carmetal dont la
version 3 permet d’écrire des programmes en javascript mais qui est trop spécialisé en géométrie par
rapport aux thèmes abordés ici (sauf dans la section 1.2.2), ni bien sur les logiciels de géométrie ne
permettant pas de programmer (en-dehors de macro-constructions). Quelques remarques sur ces logiciels
et langages :
Xcas est un logiciel de calcul formel, avec des fonctionnalités de géométrie (2-d et 3-d) et de
tableur. Les utilisateurs de Maple ou de TI peuvent programmer en Xcas en syntaxe compatible avec
Maple ou avec les TI ce qui devrait leur faciliter la prise en main. Attention, Maple ainsi que les
émulateurs TI ne sont plus autorisés à l’agrégation interne depuis la session 2015.
Scilab est un logiciel de calcul scientifique (non formel) utilisé dans l’industrie et l’enseignement
supérieur, il est adapté pour des illustrations et algorithmes reliées à l’algèbre linéaire numérique et
l’analyse numérique, mais beaucoup moins pour tout ce qui touche à l’arithmétique, à commencer
par l’absence de type entier (on est obligé d’utiliser des flottants pour les représenter).
Python est un langage de programmation généraliste interprété, il dispose donc d’une librairie
mathématique de base beaucoup moins fournie, ce qui peut être selon la situation un plus ou un
moins.
Enfin, Maxima est un logiciel de calcul formel de niveau comparable à Xcas, mais sans tableur ni
géométrie, et dont la syntaxe est plus éloignée de Maple que Xcas.
Pour stocker une donnée en mémoire, on utilise une variable. Une variable possède un nom, qui est
composé d’au moins un caractère alphabétique (de A à Z ou de a à z) suivi ou non d’autres caractères
alphanumériques, par exemple a, var, b12. Xcas est sensible à la différence entre majuscules et
minuscules (c’est aussi le cas de Python, Maxima, Scilab). Une variable peut contenir n’importe quel type
de donnée.
on écrit un nom de variable, suivi par l’instruction d’affectation := suivi par la valeur. Par exemple
a := 1.2 (en utilisant = en Python et Scilab, avec : en Maxima).
ou (dans un programme interactif) on utilise l’instruction saisir suivi du nom de variable que l’on
met entre parenthèses. Par exemple saisir(a) ou encore saisir(a,b) ou encore pour faciliter la
saisie
saisir("Entrez votre nom",a,"Entrez votre age",b)
L’équivalent en Python et Scilab est a=input("Entrez une valeur") ,.
Remarque : on évitera d’utiliser saisir/afficher , il vaut presque toujours mieux créer une
fonction qu’un programme interactif
on tape une ligne contenant le nom de la variable et la touche Entrée, la variable sera
automatiquement remplacée par sa valeur. Par exemple si on tape a:=2 puis a+1 on obtient 3. Avec
Xcas et Maxima une variable non affectée n’est pas remplacée et reste symbolique (calcul formel),
en Python et Scilab, cela déclenche une erreur.
on peut aussi afficher la valeur d’une variable au cours de l’exécution d’un programme en utilisant
la commande afficher (avec Maxima, Xcas print("texte",variable) , en Python 2 print
"texte",variable , en Scilab disp(variable)). Cela permet d’afficher un résultat intermédiaire
dans une zone située avant la ligne contenant le résultat du programme. Par exemple
afficher(a+1) affichera 3 en bleu dans cette zone.
les entiers, les fractions, les nombres flottants. La différenciation se fait pour les nombres par la
présence d’un point séparateur décimal par exemple 1, 2/3 , 1.1. On peut utiliser la notation
scientifique mantisse, exposant comme dans 1e-7 (préférable à 0.0000001 ).
les paramètres formels, par exemple x, t, z,
les expressions, par exemple x+1, x^2+y^2,
les fonctions, par exemple f:=x->x^2 ou f(x):=x^2,
les chaines de caractères, par exemple s:="bonjour" . On accède à un caractère d’une chaine en
donnant le nom de la chaine indicié par un entier compris entre 0 et la taille de la chaine moins 1
(même convention qu’en langage C), par exemple s[0] renvoie "b" .
les listes et les vecteurs, par exemple a:=[1,2,3]. On accède à un élément d’une liste en donnant le
nom de la liste indicié par un entier compris entre 0 et la taille de la liste moins 1 (même convention
qu’en langage C), par exemple a[0] renvoie 1.
On peut créer des listes de taille donnée avec une formule de remplissage (par exemple l:=[0$10] ,
l:=[j^2$j=1..10] ou seq(j^2,j,1,10) voir aussi makelist, ranm ). Ce qui permet en particulier
de faire des simulations sans avoir forcément besoin d’écrire un programme.
des objets géométriques ou plus générallement graphiques (point, droite, cercle, polygone, plan,
sphère, courbe représentative d’une fonction, etc.) obtenus par une instruction graphique (cf. section
1.2.2)
Maxima et Python peuvent manipuler des entiers, flottants, chaines de caractères, et listes, avec les mêmes
délimiteurs que Xcas. Pour adresser un élément d’une liste, on utilise le nom de variable suivi de l’indice
entre [], les indices commencent à 0 en Xcas, Scilab, Python et à 1 en Maxima. Attention, Scilab ne
propose pas de type entier (on peut représenter un entier par un flottant sans erreur de représentation s’il
est inférieur à 253).
Il faut être bien conscient du type de données que l’on manipule, par exemple en Python2 7/2 renvoie 3 le
quotient euclidien des deux entiers, alors que 7./2. renvoie 3.5 (le quotient des deux flottants). Attention,
en Python3, 7/2 renvoie 3.5, le quotient en flottant, donc 4/2 est un flottant et pas un entier (il faut utiliser
// pour obtenir le quotient euclidien sur les versions 2 et 3 de Python).
Exercices (Xcas) :
1.2 Instructions
1.2.1 Syntaxe
Une instruction valide dans Xcas doit suivre une syntaxe précise qui ressemble à l’écriture d’une
expression en mathématique. Les différents éléments d’une instruction simple peuvent être des nombres
(entiers, réels, flottants), des noms de variables, des opérateurs (par exemple + ), des appels à des fonctions
(l’argument ou les arguments se trouvant entre les parenthèses séparés par une virgule s’il y a plusieurs
arguments) : par exemple sqrt(3) pour désigner la racine carrée de 3 ou irem(26,3) pour désigner le
reste de la division euclidienne de 26 par 3).
Il faut prendre garde à la priorité entre les différentes opérations. Par exemple dans 1+2*3 l’opération * est
effectué avant + comme en mathématiques. On peut utiliser des parenthèses pour forcer l’ordre des
opérations, par exemple (1+2)*3 .
Exercice : Calculer
5/2/3, 5/(2/3), 5/2*3, 5/(2*3) , 5^2*3 , 5^(2*3),5*2^3, (5*2)^3
Conclure sur les priorités relatives de la multiplication, de la division et de la puissance.
Attention, la multiplication doit toujours être indiquée explicitement contrairement aux mathématiques.
Ainsi l’écriture ab ne désigne pas le produit de 2 variables a et b mais une variable dont le nom est ab.
Lorsqu’on veut exécuter plusieurs instructions à la suite, on termine chaque instruction par le caractère ;
(ou par les caractères :; si on ne souhaite pas afficher le résultat de l’instruction). En Python il suffit de
passer à la ligne, en Scilab, Maxima, on utilise ; (en syntaxe TI on utilise : ).
Cette section est spécifique à Xcas, les autres systèmes n’ayant en général pas d’instruction géométrique
interagissant comme du calcul numérique. Les habitués de Carmetal pourront noter une certaine similarité
dans la programmation géométrique des deux systèmes (les instructions ont en général le même nom, avec
une majuscule dans Carmetal et la syntaxe est très proche du C dans les 2 languages).
Toutes les instructions du menu Geo ont un résultat graphique (à l’exception des instructions du menu
Mesure), par exemple :
Lorsqu’une ligne de commande contient une instruction graphique, le résultat est affiché dans un repère
2-d ou 3-d selon la nature de l’objet généré. On peut controler le repère avec les boutons situés à droite du
graphique, par exemple orthonormaliser avec le bouton ⊥. Si une ligne de commande contient des
instructions graphiques et non graphiques, c’est la nature de la dernière instruction qui décide du type
d’affichage. On peut donner des attributs graphiques aux objets graphiques en ajoutant à la fin de
l’instruction graphique l’argument affichage=..., argument dont la saisie est facilitée par le menu
Graphic->Attributs .
L’instruction A:=point(click()) permet de définir une variable contenant un point du plan que l’on
clique avec la souris (click() renvoie le nombre complexe correspondant). C’est un peu l’analogue
géométrique de l’instruction saisir .
Lorsqu’on veut voir sur un même graphique le résultat de plusieurs lignes de commandes, on crée une
figure avec le menu Geo->Nouvelle figure->graph geo2d , la figure correspond alors aux lignes de
commande situées à gauche. Dans ce mode, on peut créer les objets graphiques en ligne de commande ou
pour certains directement à la souris en sélectionnant un Mode et en cliquant. On peut aussi déplacer un
point en mode Pointeur et observer les modifications des objets géométriques qui en dépendent.
Exemples :
faire cliquer un point puis afficher son symétrique par rapport à l’axe des x.
Faire cliquer deux points A et B à la souris, déterminer un 3ème point C tel que ABC soit rectangle
en A avec AC de longueur 1.
Créer une figure (menu Geo, nouvelle figure, graph geo2d). Créer 3 points (soit avec l’instruction
point , soit en passant en mode point et en cliquant 3 points à la souris). Afficher le centre du cercle
circonscrit du triangle formé par ces 3 points en utilisant uniquement les instruction mediatrice et
inter_unique.
1.2.3 Tests
On peut tester l’égalité de 2 expressions en utilisant l’instruction == , alors que != teste si 2 expressions ne
sont pas égales. On peut aussi tester l’ordre entre 2 expressions avec <, <= , >, >=, il s’agit de l’ordre
habituel sur les réels pour des données numériques ou de l’ordre lexicographique pour les chaines de
caractères. En Python et Scilab, les tests sont identiques, avec Maxima on utilise = pour l’égalité.
Un test renvoie 1 ou true s’il est vrai, 0 ou false s’il est faux. On peut combiner le résultat de deux tests au
moyen des opérateurs logiques && (ou et ou and), || (ou ou ou or ), et on peut calculer la négation logique
d’un résultat de test avec ! (ou not). En Python, on utilise les symboles &&, || ou !. Avec Maxima, Scilab,
and , or et not .
On utilise ensuite souvent la valeur du test pour exécuter une instruction conditionnelle comme
l’instruction si :
si condition alors bloc_vrai sinon bloc_faux fsi;
Un test peut être exécuté directement en ligne de commande, avec la syntaxe indiquée ci-dessous ou avec
l’instruction when (Xcas syntaxe TI). La plupart du temps, on utilise un test dans une fonction ou un
programme. Un test peut aussi servir pour arrêter une boucle en cours d’exécution ou renvoyer la valeur
calculée par une fonction.
En Python, l’alternative s’écrit if(test): passer à la ligne puis mettre le bloc vrai indenté, et else:
passer à la ligne puis mettre le bloc faux indenté.
En Scilab (aussi accepté en Xcas)
if condition then bloc_vrai else bloc_faux end .
Avec Maxima
if condition then (bloc_vrai) else (bloc_faux)
où un bloc est une suite d’instructions séparées par des virgules et délimitée par des parenthèses.
Xcas syntaxe TI, choisir le test dans les menus
Par exemple, on pourrait stocker la valeur absolue d’un réel x dans y par :
Exercices :
1.2.4 Boucles
On peut exécuter des instructions plusieurs fois de suite en utilisant une boucle définie (le nombre
d’exécutions est fixé au début) ou indéfinie (le nombre d’exécutions n’est pas connu). On utilise en
général une variable de controle (indice de boucle ou variable de terminaison).
Boucle définie
pour ... de ... jusque ... faire ... fpour
Exemple, calcul de 10!
f:=1; pour j de 1 jusque 10 faire f:=f*j; fpour;
On peut ajouter un pas s’il est différent de 1, par exemple le produit des nombres pairs de 2 à 10
f:=1; pour j de 2 jusque 10 pas 2 faire f:=f*j; fpour;
Boucle indéfinie
repeter ... jusqu_a ...
Exemple, saisir un nombre entre 1 et 10
repeter saisir("Entrer un nombre entre 1 et 10",a);
jusqu_a a>=1 && a<=10;
Remarques :
de l’évaluation de la boucle). Pour afficher tous les objets graphiques d’une boucle, il faut les
conserver dans une variable au cours de la boucle, en pratique on initialise une séquence res:=NULL
avant la boucle, et on écrit dans la boucle res:=res,objet_graphique . Notez que les objets
graphiques intermédiaires sont de toutes facons affichés dans la fenêtre DispG (menu
Cfg->Montrer).
En Python, la boucle définie se fait sur une liste en général définie par range,
for var in range(start,stop):
on passe à la ligne et on saisit le bloc de la boucle indenté. La boucle indéfinie utilise while
condition: et le bloc indenté. Ce type de syntaxe existe également en Xcas
(for var in list do ... od; )
En Xcas, la syntaxe de la boucle définie de type Maple est
for var from debut to fin do bloc; od;
et la boucle indéfinie
while condition do instructions od; .
Avec Maxima, il y a de nombreuses facons d’écrire une boucle, (voir l’aide en ligne) par exemple
pour une boucle définie
for var:debut thru fin do (bloc)
Xcas Syntaxe TI
:For I,A,B : action : EndFor
Exercices :
1.3 Fonctions
Pour réaliser des taches un peu plus complexes, il devient intéressant de les subdiviser en plusieurs entités
indépendantes appelées fonctions, qui permettent d’étendre les possibilités des instructions du logiciel.
Une fonction peut avoir 0, 1 ou plusieurs arguments (comme la fonction racine carrée sqrt() en a un).
Elle calcule une valeur, appelée valeur de retour. Cette valeur de retour peut être utilisée dans une autre
fonction ou expression algébrique, exactement comme le résultat de la fonction racine carrée.
La définition de fonctions peut parfois se faire directement avec une formule (fonction définie
algébriquement) mais nécessite parfois un algorithme plus complexe. Elle peut calculer des résultats
intermédiaires et les stocker dans des variables locales (afin de ne pas interférer avec les variables que
l’utilisateur pourrait avoir défini en-dehors de la fonction). Par exemple pour calculer les racines d’un
polynôme du second degré, on aura intérêt à calculer le discriminant et le stocker dans une variable locale.
Remarque :
De nombreuses calculatrices (TI non formelles, Casio, HP38/40) ou le logiciel Algobox (non disponibles à
l’agrégation interne) ne permettent pas de définir des fonctions, ainsi de nombreux algorithmes des
programmes du secondaire ne sont pas rédigés comme des fonctions, mais comme des programmes ne
prenant pas d’arguments et saisissant leurs arguments par des instructions saisir ou équivalent et
affichent le résultat au lieu de le renvoyer. Il est alors difficile d’utiliser la valeur calculée (il faut la
stocker dans une variable globale convenue á l’avance...) et l’exécution plusieurs fois d’un même
programme pour le mettre au point devient vite pénible (il faut saisir encore et encore les mêmes valeurs).
Au niveau du concours de l’agrégation interne, on préférera l’écriture d’algorithmes sous forme de
fonctions.
Exercices :
Attention
Il faut faire la différence entre fonction et expression. Par exemple a:=x^2-1 définit une expression alors
que b(x):=x^2-1 définit une fonction. On peut donc écrire b(2) qui renverra 4 mais l’analogue avec a
serait subst(a,x=2). On peut composer des fonctions, par exemple la fonction c=b ∘ b est c:=b@b ,
composer une fonction n fois avec elle-même (c:=b@@n), et construire une fonction à partir d’une
expression avec l’instruction unapply par exemple la fonction b dépendant de la variable x et définie par
l’expression a est b:=unapply(a,x).
La plupart des fonctions ne peuvent pas être définies simplement par une formule algébrique. On doit
souvent calculer des données intermédiaires, faire des tests et des boucles. On peut observer que c’est déjà
ce qui se passe pour des fonctions système comme sum() ou seq qui effectuent une boucle implicite (avec
une variable d’index intermédiaire “muette”). Il faut alors définir la fonction par une suite d’instructions,
délimitées en Xcas par { ... }.
La valeur calculée par la fonction est alors implicitement la valeur calculée par la dernière instruction
exécutée (qui n’est pas forcément la dernière instruction du programme) ou peut être explicitée en utilisant
le mot-clef return suivi de la valeur à renvoyer. Attention, dès que le mot-clef return est rencontré la
valeur qui suit return est évaluée et la fonction se termine. Si on veut renvoyer 2 valeurs a et b, il ne sert
à rien d’écrire return a; return b;, on les renverra plutot dans une liste ou une séquence (return
[a,b];).
Notez que l’exécution de return met un terme à la fonction, même à l’intérieur d’un test ou d’une boucle,
ce qui permet souvent d’améliorer la lisibilité :
au lieu d’écrire si ... alors return a; sinon bloc fsi; on peut écrire si ... alors return
a; fsi; bloc . Ceci évite d’avoir des forêts d’ifs.
au lieu d’ajouter des variables booléennes dans le test d’une boucle tantque, on peut souvent
introduire un test avec return
Pour éviter que les données intermédiaires n’interfèrent avec les variables de la session principale, on
utilise un type spécial de variables, les variables locales, dont la valeur ne peut être modifiée ou accédée
qu’à l’intérieur de la fonction. On utilise à cet effet le mot-clef local suivi par les noms des variables
locales séparés par des virgules (attention, en Python, toute variable intermédiaire d’une fonction est
considérée comme locale, sauf indication contraire avec global ceci peut être source d’erreur si vous
faites une faute de frappe dans un nom de variable).
Comme le texte définissant une telle fonction ne tient en général pas sur une ou deux lignes, il est
commode d’utiliser un éditeur de programmes pour définir une fonction, soit l’éditeur fourni par le
logiciel, soit un éditeur généraliste (comme emacs, vi, ...). Dans Xcas, il est conseillé d’utiliser le menu
Prg->Nouveau programme . Les assistants Fonction, Boucle et Test ou le menu Prg->Ajouter facilitent
la saisie des principales structures et commandes de programmation. Les commandes de Xcas sont
affichées en brun, les mots clef du langage en bleu.
On clique ensuite sur le bouton OK, si tout va bien, le programme pgcd est défini et on peut le tester dans
une ligne de commande par exemple par pgcd(25,15).
On peut exécuter en mode pas à pas un programme et visualiser l’évolution de la valeur des variables avec
l’instruction debug(), ce qui peut servir à comprendre le déroulement d’un algorithme, mais aussi à
corriger un programme erroné (un analogue existe en Scilab et Python, selon l’environnement de
programmation).
Exercice :
Reprendre les énoncés des exercices précédents en créant des fonctions et en déclarant en variables
locales les variables qui servent à effectuer des calculs intermédiaires.
1.3.3 Récursivité
On peut au cours du déroulement d’une fonction faire appel à cette même fonction avec un ou des
arguments “plus simples”, de sorte qu’après un nombre fini d’appels récursifs, l’argument ou les
arguments sont devenus triviaux, et on peut alors renvoyer le résultat. Par exemple, l’algorithme d’Euclide
peut s’énoncer sous la forme
Le PGCD de a et b est a si b est nul et est le PGCD de b et du reste de la division euclidienne de a par b
sinon.
Dans certains cas, la récursivité permet de simplifier grandement la conception d’un algorithme, par
exemple pour le calcul du reste de an par un entier fixé m, en distinguant n pair et n impair et en utilisant
pour n>0 pair :
Attention à bien s’assurer que le programme récursif se termine. En particulier quand on teste un
programme récursif, il est conseillé de commencer par tester le cas où la récursion doit se terminer. Notez
aussi que Xcas limite le nombre de récursions (réglage modifiable dans la configuration du cas).
Attention aussi, un algorithme récursif peut être très inefficace, par exemple si on calcule les termes de la
suite de Fibonacci par la formule
F(n):=si n<2 alors 1; sinon F(n-1)+F(n-2); fsi;
alors le calcul de F5 nécessite le calcul de F4 et F3 mais le calcul de F4 demande lui-même le calcul de F3
et F2, on calcule donc deux fois F3, trois fois F2 , cinq fois F1. (exercice : le nombre total de calcul est
lui-même une suite de Fibonacci!). Il est plus efficace dans ce cas d’écrire une boucle.
2 Arithmétique
Pour cette section, on pourra se référer au manuel de programmation de Xcas. Pour les instructions
prédéfinies, utiliser le menu CAS, Arithmétique ou le menu Cmds, Entier et Cmds, Polynômes.
Écrire un algorithme de PGCD itératif ou/et récursif. Même question pour Bézout. Algorithme itératif
pour a et b :
Adapter pour calculer l’inverse d’un entier modulo un autre entier (on peut diminuer la longueur des listes
de 1).
Applications/exercices possibles :
PGCD: simplification, On peut aussi discuter le nombre d’étapes (maximisé par la suite de
Fibonacci).
PPCM: réduction au même dénominateur, recherche de racines rationnelles dans ℚ[X]. Les
cofacteurs du PPCM apparaissent dans l’algorithme itératif de Bézout à la ligne du reste nul.
Bézout (N.B.: peut servir dans la 306) inverse dans ℤ/pℤ, restes chinois, décomposition en éléments
simples (peu d’intérêt pratique dans ℤ)
Test de primalité par division. Recherche des nombres premiers inférieurs à un entier donné (crible).
On peut aussi aborder l’algorithme de Pollard-rho basé sur le théorème des anniversaires.
Recherche de a (mod ∏pi ) connaissant a (mod pi ). On peut commencer par 2 nombres premiers (et
utiliser Bézout).
On choisit n=pq produit de deux nombres premiers assez grands gardés secrets, de sorte que la
factorisation de n soit trop longue pour pouvoir déterminer p et q connaissant n. L’application de codage
dans ℤ/nℤ consiste à calculer
x → xd (mod n )
Elle est inversible si d admet un inverse e modulo φ(n) où φ(n)=(p−1)(q−1) est l’indicatrice d’Euler de n,
son inverse est identique à l’application de codage en remplacant d par e.
Exercice : écrire des fonctions de chiffrement/déchiffrement par RSA. Instruction Xcas : powmod, inv(d %
n), convert(.,base,.) pour grouper des caractres.
Calcul du quotient et du reste de la division de 2 polynômes dont les coefficients sont donnés dans une
liste. Exemple d’application : élimination de racines (pour trouver toutes les racines d’un polynôme)
P(X) = an Xn + ... + a0
P(X)−b0=(X−α )Q(X)
où :
1. Donner bn en fonction de an puis pour i≤ n−1, bi en fonction de ai et bi+1. Indiquez le détail des
calculs pour P(X)=X3−2X+5 et une valeur de α entière 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,2,0,-1,5]) et la valeur de α et le programme renverra
P(α ). (On pourra aussi renvoyer les coefficients de Q).
3. Quel est le nombre d’opérations effectuées (comparer à ce que donne le calcul en appliquant la
forme développée du polynôme) ?
4. En utilisant cette fonction, écrire une fonction qui calcule le développement de Taylor complet d’un
polynôme en un point.
Se programme comme pour les entiers en utilisant la division euclidienne des polynômes ( quo, rem).
Applications :
Écrire une fonction qui détermine les racines rationnelles d’un polynôme P à coefficients entiers (elles
sont de la forme p/q où q divise le coefficient dominant de P et ± p divise son coefficient de plus bas
degré). Tester avec le polynôme P=12x5+10x4−6x3+11x2−x−6.
N.B.: ce n’est pas un algorithme efficace, cf. le manuel Algorithmes de calcul formel. Les commandes
Xcas correspondantes sont rationalroot, crationalroot .
proot permet d’avoir les racines approchées d’un polynôme à 1 variable. solve, csolve calculent les
racines racines exactes si le calcul a un intérêt, au sens où le résultat peut être raisonnablement manipulé
par le calcul formel.
2.2.6 Autres
3 Codage et cryptographie
Ces thèmes entrent au programme de l’agrégation interne en 2012 (exercices 349), probablement pour
faire suite aux changements dans le programme de spécialité de Terminale S.
3.1 Codes
On désigne sous ce nom la numérisation de données, mais aussi diverses applications de l’algèbre et de
l’arithmétique pour tester qu’une donnée a été transmise correctement en ajoutant une information
supplémentaire. Pour certains codes (codes correcteurs), cette information supplémentaire permet de
corriger un petit nombre d’erreurs de transmission.
On peut citer le code ASCII, qui permet d’associer à tous les caractères américains un entier compris entre
0 et 127 (7 bits). Ainsi A correspond à 65, B à 66, etc. On peut tester la transmission en ajoutant un 8ème
bit de parité (bit de poids fort mis à 0 ou à 1 pour que l’entier transmis soit pair). La prise en compte des
accents et alphabets non latins à conduit à utiliser d’autres codes, les isolatin par exemple ou les pages de
code windows. Ces codes n’étaient pas compatibles entre eux, récemment, ils ont été remplacés par
l’unicode, dont deux variantes sont très populaires: UTF8 (compatible avec ASCII) et UTF16.
Xcas utilise l’UTF8 pour coder des chaines de caractères. Les commandes asc et char permettent de
convertir une chaine de caractères en une liste et réciproquement. On peut travailler sur la liste d’entiers
obtenus, par exemple en considérant qu’il s’agit d’un seul entier écrit en base 256 (instruction convert) ou
en découpant la liste en blocs de taille donnée et en générant des listes d’entiers écrits en base 256.
Pour représenter un nombre à virgule flottante, on utilise par exemple le format “double” composé d’un bit
de signe, 11 bit pour l’exposant et 52 bits pour la mantisse.
3.1.3 Vérification
Les codes de vérification les plus simples appelés clés, consistent à calculer le reste de la division de
l’entier codant la donnée par un entier donné et à ajouter cette information supplémentaire (la clé). Le bit
de parité est l’exemple le plus simple (parité du nombre de 1 dans l’écriture en base 2 d’un nombre). Autre
exemple la clé RIB est le complément à 97 du reste de la division par 97 de l’information. Comme pour la
preuve par 9, si le test de divisibilité est incorrect, on est sur que l’information est incorrecte, mais si le
test est correct on n’est pas sur que l’information est bonne.
Définition : On travaille sur un corps fini (par exemple ℤ/pℤ pour p premier). On représente le message de
longueur k à coder par un polynôme P de degré k−1 dont les coefficients contiennent l’information (par
exemple message). On se donne un polynôme g(x) de degré m=n−k (avec n>k). On multiplie P par xn−k,
on calcule le reste R de la division euclidienne de P xn−k par g. On émet alors P xn−k−R qui est un
polynôme de degré ≤ n−1 divisible par g.
Un des intérêts des codes polynomiaux est que la vérification de bonne transmission de l’information est
très simple : il suffit de tester la divisibilité par g (et on extrait l’information pertinente en ne gardant que
les k premiers coefficients).
En Xcas, on peut travailler avec des polynômes à coefficients dans ℤ/pℤ comme avec les mêmes
instructions que pour des polynômes à coefficients dans ℚ en ajoutant % p . Par exemple
rem((x^10+3x^3+5) % 7,(3x^2-2x+3) %7) . On peut aussi travailler avec un corps fini non premier
(instruction GF, par exemple GF(2,8) permet de travailler sur le corps fini à 256 éléments).
Exercice : écrire de cette facon le codage du bit de parité (divisibilité par x+1 modulo 2 ou évaluation
nulle en 1). Puis une procédure Xcas de codage utilisant g=X7+X3+1 sur le corps ℤ/2ℤ (ce polynôme était
utilisé par le Minitel).
Remarque : les codes polynomiaux sont un cas particulier de codes linéaires mais les espaces vectoriels à
coefficients dans un corps finis ne sont pas au programme de l’agrégation interne, on n’en parlera donc
pas.
Si le polynôme g est de degré pas trop petit, on peut espérer que l’information complémentaire contenue
dans le reste peut permettre de corriger une ou 2 erreurs de transmission.
Définition: On appelle distance (de Hamming) entre 2 polynômes le nombre de coefficients distincts de
ces 2 polynômes (On vérifie qu’il s’agit bien d’une distance).
Définition On appelle distance du code polynomial défini par l’entier k et le polynôme g de degré m=n−k
le minimum de la distance de Hamming entre 2 multiples distincts de g de degré <n (ou ce qui revient au
même d’un multiple non nul de g de degré <n).
Si une information reçue est codée par un polynôme P qui n’est pas multiple de g, il y a erreur de
transmission, on peut chercher à corriger les coefficients mal transmis en remplaçant P par un multiple de
g de degré <n proche de P au sens de la distance de Hamming. Cela fait sens si on peut assurer l’unicité du
multiple de g le plus proche (ceci n’assure pas l’existence d’un tel multiple de g, même si c’est vrai pour
certains codes). Si le nombre de coefficients à corriger est au plus t et si 2t+1 est inférieur ou égal à la
distance du code, alors il y aura unicité (sinon il y aurait deux multiples distincts de g à distance ≤ t de P
donc dont la distance mutuelle serait ≤ 2t, impossible car cette distance serait strictement inférieure à la
distance du code).
On a donc tout intérêt à ce que la distance du code soit la plus grande possible. On observe que la distance
du code est inférieure ou égale au nombre de coefficients non nuls de g puisque g est un multiple non nul
de lui-même, donc à m+1. Dans les cas favorables (choix judicieux de g), la distance du code vaut
exactement m+1 et on pourra alors espérer corriger au plus m/2 erreurs.
Proposition Soit K corps fini de générateur a, on considère un code polynomial tel que n < cardinal(K) et
m
g(x)= ∏ (x−a ) j
j=1
Preuve : soit P un multiple de g de degré <n ayant au plus m coefficients non nuls, alors on peut écrire
m
P(x)= ∑p kj xkj, kj < n
j=1
∑p kj (akj)l = 0, l=1..m
j=1
Mais ce système en les pkj est un système de Cramer m,m, car son déterminant est un déterminant de
Vandermonde engendré par des éléments du corps fini, les akj, j=1..m, qui sont distincts 2 à 2 puisque a est
un générateur du corps.
Exercice : générer un code polynomial sur ℤ/97Z pouvant corriger jusqu’à 2 erreurs. Programmer la
correction au plus proche (on commencera par tester la divisibilité en changeant un coefficient, puis 2).
Exercice : lien avec la loi binomiale. On suppose que la probabilité d’erreur de transmission d’un
coefficient est ε (par exemple ε=0.001=1e−3, et que les erreurs de transmission coefficient par coefficient
sont indépendantes. On transmet n caractères, quelle est la probabilité d’avoir au plus t erreurs de
transmission (et donc de pouvoir corriger avec le code précédent) ?
3.2 Cryptographie
Le principe consiste à utiliser une bijection de ℤ/pℤ dans lui-même pour crypter le message. Le codage de
Jules César peut être vu comme l’addition d’une constante dans ℤ/26ℤ, Vigenère est l’addition des lettres
du message à crypter avec les lettres d’un texte fixé. Le codage affine utilise une application affine
x → ax+b
avec a inversible modulo p (le calcul de l’inverse fait intervenir l’identité de Bézout). Aucune de ces
méthodes n’est résistante à une analyse statistique du message crypté (dans le cas de Vigenére, l’attaque
est plus complexe à mettre en oeuvre).
Le chiffrement de Hill groupe les lettres du message à crypter par paquets de n (n fixé) pour éviter
l’attaque par analyse statistique, on a donc un vecteur v ∈ (ℤ/pℤ)n dont on calcule l’image par un
chiffrement affine
v → Av+b
où A est une matrice inversible sur ℤ/pℤ (donc est à la limite du programme sauf dans des cas comme n=2
où on peut exprimer l’inverse explicitement de manière simple, malheureusement dans ce cas n n’est pas
suffisamment grand pour que ce code soit résistant à une analyse statistique).
De plus toutes ces méthodes supposent que les clés de chiffrement et de déchiffrement sont secretes (en
effet si on connait l’une des clefs on en déduit l’autre), alors que RSA par exemple permet de publier une
des deux clefs.
Exercices : écrire des fonctions de chiffrement/déchiffrement par ces méthodes. Instruction en Xcas : asc,
char, %, inv .
Chaque personne souhaitant coder ou signer un message dispose d’une clef privée, un entier s connu
de lui seul, et d’une clef publique, une paire d’entiers (c,n).
n est le produit de 2 nombres premiers p et q, et s et c sont inverses modulo ϕ(n), où
ϕ(n)=(p−1)(q−1) (le nombre d’entiers de l’intervalle [1,n[ premiers avec n), on a alors (cf. devoir 1)
(ac (mod n ))s (mod n ) = (ac (mod n ))s (mod n ) = a (mod n ) (1)
Pour coder un message à destination d’une personne dont la clef publique est (c,n), on commence
par le transformer en une suite d’entiers, On peut par exemple remplacer chaque caractère par un
entier compris entre 0 et 255, son code ASCII.
Puis on envoie la liste des nombres b=ac (mod n ). En principe, seule la personne destinataire
connait s et peut donc retrouver a à partir de b en calculant bs (mod n ).
On peut aussi authentifier qu’on est l’auteur d’un message en le codant avec sa clef privée, tout le
monde pouvant le décoder avec la clef publique.
récursif : si c==0 on renvoie 1, si c==1 on renvoie a, sinon, si c est pair, on pose b=ac/2 (mod n )
(calculé par appel récursif) et on renvoie b× b (mod n ), et enfin si c est impair, on pose b=a(c−1)/2
(mod n ) (calculé par appel récursif) et on renvoie b× b × a(mod n )
itératif : on initialise A ← a, b ← 1, puis tant que c ≠ 0
si c est impair, b ← A × b (mod n ),
c ← quotient euclidien de c par 2,
A ← A× A (mod n )
et on renvoie b.
Exercice 8: Primalité
Pour créer une paire de clefs, il faut générer des nombres premiers et donc être capable de déterminer si un
nombre est premier ou non. Un test simple consiste à appliquer la contrapposée du petit théorème de
Fermat: si ap ≠ a (mod p ), alors p n’est pas premier. Ecrire une fonction prenant en argument a et p et
renvoyant 0 si p n’est pas premier et 1 si ap =a (mod p ), puis une fonction prenant en argument p et
effectuant le test pour toutes les valeurs de a∈[2,p−1] jusqu’à ce que le test échoue. Si tous le tests
réussissent, p est peut-être premier mais ce n’est pas certain: existe-t-il un nombre non premier pour lequel
tous les tests réussissent ?
On représente un secret par un entier s. On souhaite transmettre ce secret à n personnes. Une première
méthode consiste à découper s en plusieurs parties, par exemple en écrivant s dans une base convenable,
ou bien en donnant la valeur de s modulo plusieurs nombres premiers (reconstruction par le lemme
chinois). Cette méthode est peu résistante, d’une part parce que la connaissance d’une partie des morceaux
peut permettre la reconstruction de s en testant toutes les valeurs possibles des morceaux manquants,
d’autre part parce qu’on ne peut pas se prémunir contre des erreurs (ou un ou deux morceaux manquants).
Une deuxième méthode, plus résistante, consiste si s∈ K=ℤ/pℤ avec p premier (ou K un corps fini non
premier) à choisir aléatoirement n−1 éléments de K, pour construire un polynôme P de degré n−1 ayant s
comme coefficient constant. On calcule ensuite pour chacun des n morceaux la valeur de tk=P(xk) en n
abscisses distinctes 2 à 2 fixées xk, le morceau de secret est alors tk. On peut alors reconstruire P avec les
tk par interpolation de Lagrange et retrouver s=P(0). Si le polynôme P est de degré plus petit, on peut
reconstruire P et donc s avec un nombre plus faible de morceaux du secret (voire éliminer des morceaux
de secrets invalides).
Pour en savoir plus sur toute cette section, cf. par exemple Demazure, Gilles Zémor, le manuel de
programmation de Xcas.
4 Analyse
Référence: manuel algorithmes de Xcas, le livre de Demailly. Exposés : 201, 208, 217, 220, 225, 235, 251,
254, 256, 262
Exercices : 403 (voire 401 à 404), 406, 417, 421, 428, 429, 430, 432, 440, 441, 443, 444
4.1 Dichotomie
Recherche de solutions de f(x)=x par étude de la suite un+1=f(un). Exemple, résolution de l’équation du
temps en mécanique céleste x − e sin(x) = y, e ∈ [0,1[.
Exercice 1
Écrire un programme iter prenant en argument la fonction f, la valeur de u0 , de N et de ε, et qui s’arrête
dès que l’une des conditions suivantes est satisfaite :
|un+1−un|<ε
le nombre d’itérations dépasse N.
Dans le premier cas le programme renverra la valeur de un+1, dans le second cas une séquence composée
de uN et de N.
Tester votre programme avec f(x)=√2+x et f(x)=x2.
On suppose que la fonction f satisfait aux hypothèses du théorème du point fixe. On notera k<1 la
constante de contractance. On peut alors trouver un encadrement de la limite l de la suite (un) en fonction
de un, un−1 et k.
Exercice 2
Écrire un programme iter_k prenant en argument la fonction f, la valeur de u0, la constante k et l’écart
toléré ε, et qui s’arrête dès que | un − l | ≤ ε.
Vérifier les hypothèses du théorème du point fixe pour f(x)=3cos(x/4) sur [0,3] et expliciter une constante
de contractance k. Déterminer une valeur approchée de la limite de (un) à 10−3 près en utilisant la fonction
iter_k.
La convergence de ces suites est en général linéaire, le nombre de décimales exactes augmente de la même
valeur à chaque itération. Par contre lorsqu’on est prêt d’une racine, la méthode de Newton permet en
gros de multiplier par deux le nombre de décimales à chaque itération.
Exercice 3
1. Donner une suite itérative obtenue par la méthode de Newton convergeant vers √5.
Dans certains cas, la fonction f n’est pas contractante, mais on peut réécrire l’équation à résoudre sous
une autre forme avec une fonction contractante, par exemple en utilisant une fonction réciproque.
Exercice 4
Donner un encadrement à 10−6 près d’une racine de l’équation tan(x)=x sur l’intervalle ]5π/2,7π/2[ en
utilisant une méthode de point fixe.
f(un)
un+1=un−
f′(un)
1
dx
∫ 1+x
0
par la méthode des rectangles, du point milieu et des trapèzes en utilisant un pas de 1/10 et de 1/100 (vous
pouvez la fonction plotarea ou utiliser le tableur ou écrire un programme effectuant ce calcul avec
comme arguments la fonction, la borne inférieure, la borne supérieure et le nombre de subdivision).
Observez numériquement la différence entre les valeurs obtenues et la valeur exacte de l’intégrale.
Exercice 2
Calculer le polynôme interpolateur P de Lagrange de f(x)=1/1+x2 aux points d’abscisse j/4 pour j variant
de 0 à 4. Donner un majorant de la différence entre P et f en un point x ∈ [0,1]. Représenter
graphiquement ce majorant. Calculer une majoration de l’erreur entre l’intégrale de f et l’intégrale de P sur
[0,1]. En déduire un encadrement de π/4.
Exercice 3
On reprend le calcul de ∫01 dx/1+x mais en utilisant un polynôme interpolateur de degré 4 sur N
subdivisions de [0,1] (de pas h=1/N). Déterminer une valeur de N telle que la valeur approchée de
l’intégrale ainsi calculée soit proche à 10−8 près de ln(2). En déduire une valeur approchée à 10−8 de ln(2).
Même question pour ∫01 dx/1+x2 et π/4 (pour majorer la dérivée n-ième de 1/1+x2, on pourra utiliser une
décomposition en éléments simples sur ℂ).
Résolution numérique : méthode d’Euler explicite (ou implicite) illustration avec interactive_odeplot
ou/et programmation.
Voir la section 12 du manuel Algorithmes pour des méthodes de résolution exacte d’équations
différentielles, et des exemples venant de la physique (12.3.5, 12.4.2, 12.4.5).
Exercice 1.
Exercice 2. On veut approcher sin(x) à 1e-6 près en utilisant des développements en séries entières.
∑
j=0
réalise cette approximation sur [0,π/4].
2. Écrire une fonction qui calcule une valeur approchée à 1e-6 de sin(x) sur [−100,100] en justifiant et
en effectuant les étapes suivantes:
on retire un multiple entier de π (obtenu par arrondi de x/π) pour se ramener à l’intervalle
[−π/2,π/2] (on discutera sur l’erreur commise)
si x est négatif, on remplace x par −x (que devient sin(x)?)
lorsque x ∈ [0,π/4], on utilise le développement en séries ci-dessus.
lorsque x ∈ [π/4,π/2], on se ramène au développement de l’exercice précédent en appliquant
la formule sin(x)=cos(π/2−x).
3. Afin de tester votre fonction f et d’attraper d’éventuelles erreurs grossières, faites afficher le graphe
de f, disons sur l’intervalle [−10,10], puis le graphe de la différence f−sin où sin est la fonction déjà
implémentée dans Xcas.
Exercice 3
Exercice 4
0
En utilisant le développement de g, écrire I sous la forme d’une série ∑j=0 ∞vj.
3. Soit Rn=∑j=n+1∞vj le reste de cette série. Donner une majoration de |Rn|.
4. En déduire un encadrement de I faisant intervenir ∑j=0n vj. Calculer explicitement cet encadrement
lorsque n=10.
Méthode de Richardson lorsqu’on connait le développement asymptotique d’une suite convergeant vers la
limite. Par exemple pour la constante d’Euler (cf. le manuel de programmation de Xcas)
Autres : méthode du Δ2 d’Aitken, séries alternées (théorie voir le texte 585 de l’option C de l’agrégation
externe, [Link] , cf. la session du menu Exemples, analyse de
Xcas).
5 Algèbre linéaire
Référence: dans Xcas, menu Aide, puis manuel, puis Programmation (pour le pivot de Gauss) ou
Algorithmes de calcul formel section 20.
5.2 Programmation
On rappelle qu’en mode Xcas, les indices commencent à 0 (en mode maple les indices commencent à 1).
Etant donné une matrice M ayant L lignes et C colonnes, on demande de programmer l’algorithme du
pivot de Gauss que l’on rappelle :
Pour calculer l’inverse d’une matrice M carrée de taille n, on peut résoudre simultanément n systèmes
linéaires du type Mxk=yk où yk représente (en colonne) les coordonnées du k-ième vecteur de la base
canonique pour k variant de 1 à n. On écrit donc la matrice M puis les colonnes des coordonnées de ces n
vecteurs, donc la matrice identité de taille n. On réduit complètement la matrice par l’algorithme du pivot
de Gauss. Si M est inversible, les n premières colonnes après réduction doivent être la matrice identité de
taille n, alors que les n colonnes qui suivent sont les coordonnées des xk donc ces n colonnes constituent
M−1. On peut aussi utiliser la factorisation LU de la matrice A et résoudre les n systèmes avec cette
factorisation.
Écrire un programme de calcul d’inverse de matrice par cet algorithme.
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 )
L Mt = U
donc
M Lt = Ut
Les colonnes de Lt correspondant aux colonnes nulles de Ut (ou si on préfère les lignes de L correspondant
aux lignes nulles de U) sont donc dans le noyau de M et réciproquement si Mv=0 alors
Ut (Lt)−1 v =0
donc, comme U est réduite, (Lt)−1 v est une combinaison linéaire des vecteurs de base d’indice les lignes
nulles de U. Finalement, les lignes de L correspondant aux lignes nulles de U forment une base du noyau
de M.
On peut faire le raisonnement ci-dessus à l’identique si M est une matrice à coefficients entiers, en
effectuant des manipulations élémentaires réversibles dans ℤ, grâce à l’idendité de Bézout. Si a est le pivot
en ligne i, b le coefficient en ligne j à annuler, et u, v, d les coefficients de l’identité de Bézout a u + b v =d
on fait les changements :
b a
Li ← uLi +v Lj, Lj ← − Li + Lj
d d
qui est réversible dans ℤ car le déterminant de la sous-matrice élémentaire correspondante est
⎪ u v ⎪
⎪ ⎪= 1
⎪ ⎪
⎪ b a ⎪
−
⎪ d d ⎪
⎪ ⎪
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.
Lorsque les coefficients de la matrice M=(mj,k)0 ≤ j <L, 0 ≤ k < C sont entiers, on peut souhaiter éviter de
faire des calculs dans les rationnels, et préférer utiliser une combinaison linéaire de lignes ne faisant
intervenir que des coefficients entiers. On peut par exemple effectuer l’opération (où l,c désignent la ligne
et colonne du pivot)
Lj ← ml,c Lj − mj,c Ll
Tester la taille des coefficients obtenus pour une matrice carrée aléatoire de taille 5 puis 10. L’idée est-elle
bonne ?
On peut montrer qu’on peut toujours diviser par le pivot utilisé pour réduire la colonne précédente
(initialisé à 1 lors de la réduction de la première colonne)
1
Lj ← (ml,c Lj − mj,c Ll)
pprec
Tester à nouveau sur des matrices carrées de taille 5, 10, vérifier que les calculs sont bien effectués dans ℤ.
Comparer le dernier coefficient en bas à droite avec le déterminant de la matrice (si vous avez vu les
propriétés des déterminants, démontrez ce résultat. Plus difficile: en déduire qu’on peut bien diviser par le
pivot de la colonne précédente en considérant des déterminants de matrices extraites)
5.7 Exercices
Exercice 1
Calcul de la somme de deux sous-espaces vectoriels.
On donne deux sous-espaces vectoriels E1 et E2 de ℝn par deux familles géneratrices (c’est-à-dire une liste
de vecteurs), il s’agit d’écrire un algorithme permettant
On pourra utiliser les fonctions rref ou/et ker de Xcas. Tester avec deux sous-espaces de dimension 2 de
ℝ5. N’oubliez pas de rédiger une justification mathématique de la méthode mise en oeuvre.
Exercice 2
Calcul de l’intersection de deux sous-espaces vectoriels.
On donne deux sous-espaces vectoriels E1 et E2 de ℝn par deux familles géneratrices (c’est-à-dire une liste
de vecteurs), il s’agit d’écrire un algorithme permettant de trouver une base de E1 ∩ E2. On pourra utiliser
les fonctions rref ou/et ker de Xcas. Tester avec 2 sous-espace de dimension 3 de ℝ4. N’oubliez pas de
rédiger une justification mathématique de la méthode mise en oeuvre.
Exercice 3
Mise en oeuvre du théorème de la base incomplète. On donne une famille de vecteurs de ℝn (liste de
vecteurs), il s’agit d’écrire un algorithme permettant d’extraire une base du sous-espace engendré, puis de
compléter par des vecteurs afin de former une base de ℝn tout entier, et enfin d’écrire un vecteur de ℝn
comme combinaison linéaire des vecteurs de la base complétée. On pourra utiliser les fonctions rref ou/et
ker de Xcas. Tester avec une famille de 3 vecteurs de ℝ5. N’oubliez pas de rédiger une justification
mathématique de la méthode mise en oeuvre.
5.8 Déterminants
Calcul par réduction. Autres algorithmes (à la limite du programme) : développement intelligent (2n
opérations), modulaire (si les coefficients sont dans ℤ).
On propose ici quelques algorithmes de calcul du polynôme minimal M et/ou caractéristique P d’une
matrice carrée A de taille n. On peut bien sur calculer le polynôme caractéristique en calculant directement
le déterminant (par exemple avec l’algorithme de Gauss-Bareiss pour éviter les fractions de polynômes),
mais c’est souvent plus couteux que d’utiliser un des deux algorithmes ci-dessous.
On sait que le degré de P est n, il suffit donc de connaitre la valeur de P en n+1 points distincts pour
connaitre P. Par exemple, on calcule P(k) pour k=0,...,n, et en utilisant l’instruction lagrange de Xcas, on
en déduit le polynôme caractéristique. Programmer cet algorithme et testez votre programme en
comparant le résultat de votre programme et de l’instruction charpoly de Xcas sur quelques matrices.
Cet algorithme permet de calculer le polynôme caractéristique C dans presque tous les cas, en recherchant
le polynôme minimal M de A (on note m le degré de M).
On sait que M(A)=0, donc pour tout vecteur v, M(A)v=0. Si M(x)=∑k=0m Mk xk, alors
m
0 = M(A)v= ∑MA k
k v
k=0
On va donc rechercher les relations linéaires qui existent entre les n+1 vecteurs v, ..., An v. Cela revient à
déterminer le noyau K de l’application linéaire dont la matrice a pour colonnes v,...,Anv. On sait que le
vecteur (M0,...,Mm,0,...,0) ∈ ℝn+1 des coefficients de M (complété par des 0 si m<n) appartient à ce noyau
K. Si le noyau K est de dimension 1, alors m=n, et les coefficients de M sont proportionnels aux
coefficients du vecteur de la base du noyau calculé. On en déduit alors le polynôme minimal M et comme
m=n, et aussi le polynôme caractéristique C=M.
Programmer cet algorithme en prenant un vecteur v aléatoire. Attention, pour calculer Akv on formera la
suite récurrente vk=Avk−1, pourquoi?
Si on n’a pas de chances dans le choix de v, on trouvera un noyau de dimension plus grande que 1 bien
que le polynome minimal soit de degré n. On peut alors recommencer avec un autre vecteur. On peut aussi
chercher la relation de degré minimal pour un v donné (elle apparait automatiquement comme premier
vecteur de la base dans l’algorithme de calcul du noyau donné au TP2), prendre le PPCM P des
polynomes pour 2 ou 3 vecteurs aléatoires et conclure s’il est de degré n. Programmer cette variante.
Si le polynome minimal est de degré m<n, on peut tester si le PPCM P est le polynome minimal en
calculant P(A) mais ce calcul est couteux. On peut aussi faire confiance au hasard, supposer que le
polynome minimal est bien M=P et essayer de déterminer C/M par d’autres moyens, par exemple la trace
si n=m+1. On dispose alors d’un moyen de vérification en calculant l’espace caractéristique correspondant
à la valeur propre double. Programmer cette variante.
Si la matrice M possède une seule valeur propre de module maximal, alors la suite vn+1=Mvn se rapproche
de l’espace propre correspondant. En pratique, on normalise vn pour éviter les débordements numériques.
Écrire un programme mettant en oeuvre la méthode de la puissance dans le cas réel (penser à normaliser vn
pour éviter les overflow). Utilisez ce programme pour trouver une valeur approchée de la valeur propre de
norme maximale par la méthode de la puissance de B t B où B est une matrice aléatoire.
5.11 Factorisation QR
La factorisation QR d’une matrice (écriture comme produit d’une matrice orthogonale/unitaire et d’une
matrice triangulaire supérieure) sert à calculer simultanément toutes les valeurs propres (approchées)
d’une matrice, commande Xcas qr. L’idée est de poser A=QR puis A1=RQ et de recommencer, on peut
montrer qu’il y a convergence vers une matrice (presque) diagonale. Pour optimiser les itérations, on
utilise la méthode QR implicite ou algorithme de Francis sur la forme de Hessenberg de la matrice, c’est la
commande schur qui fait ce calcul dans Xcas, P,H:=schur(A) renvoie dans P une matrice orthogonale (ou
Représentation par la liste des images ou par une liste de cycles, chaque cycle étant la liste des éléments
du cycle. Composition, inverse, décomposition en cycles.
En prenant un couple de nombres aléatoires entre -1 et 1, on regarde si le couple est dans le disque de
rayon 1, et on calcule la proportion.
6.4 Fluctuations
Expérience : on tire n fois au hasard une boule dans une urne avec remise, la proportion de boules noires
dans l’urne étant p (proche de 0.5), on compte le nombre de boules noires. On effectue N fois l’expérience.
On compte le nombre de fois où la proportion de boules noires observée est dans un intervalle centré en p
de taille proportionnelle à 1/√n (par exemple [p−1/√n,p+1/√n]). On peut aussi représenter graphiquement
par des segments horizontaux les intervalles proportion de boules observées ± 1/√n et tracer verticalement
la droite d’abscisse p.
Expérience : on ajoute n réels tirés au hasard pris entre 0 et 1 (loi uniforme, ou autre loi), par exemple pour
n=30. On effectue N fois l’expérience (par exemple N=1000), et on trace un histogramme des résultats, et
sur le même graphique on représente la loi normale de moyenne l’espérance de la loi et d’écart-type
l’écart-type de la loi divisé par √n.
Par discrétisation.
Les exercices de cette section présentent chacun un algorithme, ces algorithmes ont été choisis en
raison de leur importance, ils sont donc par nature génériques et plus théoriques que des exercices
standards, puisqu’ils implémentent une partie du cours ou un complément de cours, de ce fait on a
aussi indiqué les leçons qui correspondent aux algorithmes présentés.
On a fait le choix d’algorithmes effectivement implémentables par un candidat pendant le temps de
préparation pour un exercice qu’il choisirait de développer. Un candidat moins à l’aise sur machine
peut très bien décider de présenter un algorithme sans l’implémenter effectivement en écrivant
l’algorithme au tableau et en l’illustrant sur machine par l’instruction intégrée du logiciel. Il est
aussi possible de présenter une implémentation non mise au point, en insistant sur le fait que les
conditions de préparation (temps, stress) ne sont pas des conditions favorables à la mise au point (et
les candidats doivent être particulièrement attentifs à ne pas perdre plus de quelques minutes au
débogage, au risque de paniquer et de ne pas préparer correctement les autres exercices).
Les implémentations sont proposées en syntaxe en français pour Xcas (donc en language
algorithmique mais qui de plus fonctionne) et en syntaxe Xcas compatible Maple V. (Xcas fait partie
des logiciels proposés au concours ce qui n’est plus le cas de Maple. Comme il est largement
compatible avec Maple, il est susceptible d’intéresser les candidats qui maitrisent déjà Maple, pour
plus d’informations cf.
[Link]/~parisse/giac_fr.html )
Énoncé : : le but de l’exercice est de calculer rapidement an modulo p où a,n,p sont 3 entiers avec 0 ≤ a <
p.
1. Soit n un entier et
k
n= ∑ n 2,
j
j nj ∈ { 0,1 }
j=0
sa décomposition en base 2. Écrire un algorithme qui renvoie la liste des nj.
j
2. On calcule aj=a2 modulo p successivement pour j=2..k par
j j−1
aj=a2 (mod p ) = (a2 (mod p ))2 (mod p )
Calculer an (mod p ) en fonction des aj et nj. Quel est le nombre d’opérations à effectuer ? Comparer
avec le nombre d’opérations à effectuer en faisant a × a × ... × a (mod p ).
3. Écrire un algorithme permettant de calculer an modulo p par cet algorithme.
Solution :
1. On observe que n0 est le reste de la division euclidienne de n par 2, n1 s’obtient à partir du quotient
euclidien de n par 2 de la même façon que n0 à partir de n et donc si on remplace n par le quotient
euclidien de n par 2, n1 est alors le reste de la division euclidienne de n par 2 ... D’où l’algorithme
en syntaxe Xcas en français :
base2(n):={
local l;
l:=NULL; // sequence vide
tantque n>0 faire
// ajoute n_0 puis n_1 puis ... en fin de l
l:=l,irem(n,2); // irem: reste euclidien
n:=iquo(n,2);
ftantque;
// renverse l'ordre des elements de l
return revlist(l);
}
N.B. : l’instruction intégrée Xcas permettant de faire la conversion est convert(n,base,2) , elle
renvoie la liste des bits à l’envers.
2. On a
an (mod p ) = a ∑n2 j
j
(mod p )
j=0
k
= ∏a j
nj (mod p )
j=0
= ∏ aj (mod p )
0≤ j ≤ k, nj =1
Il faut effectuer k−1 opérations d’élévation au carré suivi de réduction modulo p pour calculer les aj,
puis effectuer le produit de aj pour les nj=1. Au maximum on fait 2k−1 produits suivi de réduction
modulo p, où k est la partie entière du log en base 2 de n. Ce qui nécessite beaucoup moins
d’opérations que de calculer n−1 produits suivi de réduction modulo p.
Il est essentiel d’effectuer les réductions modulo p après chaque produit et non pas seulement à la
fin, sinon la taille des entiers à multiplier augmenterait considérablement, et donc le temps
nécessaire pour effectuer une multiplication. Ici, toutes les multiplications se font avec des nombres
plus petits que p, en temps constant donc.
3. On pourrait utiliser la fonction base2 précédente, on peut aussi calculer simultanément les nj et an
(mod p ). En syntaxe Xcas en français:
puimod(a,n,p):={
local aj,an_modp;
aj:=irem(a,p); // precaution au cas ou a>=p
an_modp:=1;
tantque n>0 faire
si irem(n,2)==1 alors
an_modp:=irem(an_modp*aj,p);
fsi;
n:=iquo(n,2);
aj:=irem(aj*aj,p);
ftantque;
return an_modp;
Commentaires
L’exercice peut se prolonger par les applications comme le système de cryptographie RSA, voir
aussi l’exercice suivant sur les tests de primalité.
La décomposition en base 2 peut se faire au lycée, la suite également mais il est difficile d’en
justifier l’intérêt (sauf en TS spécialité maths).
Énoncé :
1. Soit p un nombre premier. En utilisant la formule du binôme de Newton, montrer par récurrence que
ap est congru à a modulo p.
2. Écrire un algorithme qui teste pour quelques valeurs de a si ap est congru à a modulo p, on renverra
a si p n’est pas premier, et 0 sinon. Que signifie la valeur 0?
3. Écrire un algorithme qui détermine le premier entier non premier tel que pour tout a, ap est congru à
a modulo p (nombre de Carmichael). On pourra utiliser la fonction isprime pour tester si un entier
est premier.
Solution :
1. On fait une démonstration par récurrence. On a 0p=0 est bien congru à 0 modulo p. La formule du
binôme donne :
p p−1
p p
⎛ ⎞ j ⎛ ⎞
P
(a+1) = ∑ ⎝ ⎠
p
a = 1+a + ∑ ⎝ ⎠
j j
j=0 j=1
Dans la somme les coefficients binomiaux valent
j−1
∏ (p−k)
k=0
j!
et sont donc divisibles par p puisque le numérateur l’est, le dénominateur ne l’est pas et p est
premier. Donc (a+1)P est congru à ap+1 modulo p donc à a+1 modulo p par hypothèse de
récurrence.
2. En syntaxe Xcas (très proche du langage algorithmique)
test(p,nmax):={
local a;
nmax := min(nmax,p-1);
pour a de 2 jusque nmax faire
si powmod(a,p,p)!=a alors retourne a; fsi;
fpour
retourne 0;
}:;
On utilise ici la fonction powmod (puissance modulaire rapide). Le paramètre nmax sert à limiter le
nombre d’essais, ici on essaie les entiers de 2 à nmax, mais on pourrait aussi tirer nmax entiers au
hasard. La boucle sur a se poursuit jusqu’à ce que le test de Fermat échoue, return provoque en
effet l’arrêt prématuré de la fonction (donc de la boucle) ou va à son terme (test réussi, valeur de
retour 0). L’équivalent en syntaxe maple V en utilisant la fonction puimod ci-dessus (aussi utilisable
dans Xcas) :
test:=proc(p,nmax0)
local a,nmax;
nmax := min(nmax0,p-1);
for a from 2 to nmax do
if puimod(a,p,p)<>a then RETURN a; fi;
od;
RETURN 0;
end
Lorsque la réponse du programme est non nulle, on est assuré que le nombre n’est pas premier, la
valeur renvoyée est un certificat de non-primalité (un entier tel que ap ≠ a (mod p )). Par contre, si la
valeur renvoyée est 0, on ne peut pas en déduire que p est premier (il y a seulement des
présomptions).
3. Pour trouver un nombre de Carmichael, on doit tester que ap = a (mod p ) pour tous les entiers
compris entre 2 et p−1 et on doit de plus tester que p n’est pas premier. En syntaxe Xcas :
carmi(nmax):={
local a,p;
pour p de 3 jusque nmax faire
pour a de 2 jusque p-1 faire
si powmod(a,p,p)!=a alors break; fsi;
fpour
// a la sortie de la boucle,
// a vaut p si le test a reussi
// ou est inferieur a p (arret par break)
si a==p et !isprime(p) alors return a; fsi;
fpour;
return "non trouve";
}
On exécute par exemple carmi(100) qui renvoie “non trouvé” (il n’y a pas de nombre de
Carmichael inférieur à 100) alors que carmi(1000) renvoie après quelques secondes 561, le premier
nombre de Carmichael.
Commentaires :
Cet exercice de niveau 1ère ou 2ème année universitaire est à la limite accessible en terminale S
spécialité maths.
On peut le prolonger par le test de pseudo-primalité de Miller-Rabin (cf. le manuel de
programmation de Xcas pour l’algorithme, les justifications nécessitent du candidat plus de bagages
mathématiques dans les corps finis) qui donne une bonne probabilité d’être premier s’il réussit pour
plusieurs entiers contrairement au test de Fermat pour lesquels cet exercice construit des contre-
exemples.
L’intérêt de ces méthodes est de tester rapidement la primalité de grands entiers. On peut en effet
montrer que le nombre d’opérations élémentaires à effectuer pour le test ci-dessus ou le test de
Miller-Rabin est en O(ln(p)3), alors que le test de divisibilité peut atteindre O(√p ln(p)2).
On peut aussi parler de certificats de primalité, comme l’exemple de la documentation de Xcas
pari("isprime",9856989898997789789,1) .
Énoncé : Soient a et b 2 entiers. On pose r0=a,r1=b, et pour n≥ 0 tel que rn+1 ≠ 0, on note qn+2 et rn+2 le
quotient et le reste de la division euclidienne de rn par rn+1. On rappelle qu’il existe un (premier) entier N
tel que rN= 0, et que pgcd(a,b)=rN−1 (dernier reste non nul).
Solution
1. Par récurrence, au rang n=0 et n=1 c’est une conséquence de la définition de r0, r1, u0, u1, v0, v1.
Pour n≥ 2,
2. On remarque que la relation de récurrence définissant rn, un et vn est identique, on utilisera une liste
pour contenir ces 3 valeurs. On exécute une boucle (avec test d’arrêt sur la valeur de rn+1), au cours
de la boucle La liste l0 contiendra les valeurs de rn ,un,vn, l1 les valeurs de rn+1,un+1,vn+1 et l2 les
valeurs de rn+2,un+2,vn+2 , en fin de boucle l’incrémentation de n se traduit par la recopie de l1 dans
l0 et de l2 dans l1.
bez(a,b):={
local l0,l1,l2,q;
l0:=[a,1,0];
l1:=[b,0,1];
tantque l1[0]!=0 faire
q:=iquo(l0[0],l1[0]);
l2:=l0-q*l1;
l0:=l1;
l1:=l2;
ftantque;
// l0 contient les coefficients de Bezout
// l1 contient les cofacteur du PPCM
return l0;
}
Donc
unrn+1 −un+1 rn = (−1)n (u0r1 −u1 r0 ) =(−1)n b
Au rang n=N−1, on a donc uN pgcd(a,b)=(−1)N b. En multipliant par a, on a alors
ab
uN a =(−1)N = (−1)N ppcm(a,b)
pgcd(a,b)
On peut faire de même avec vN ou tout simplement utiliser
auN+bvN=0
Bien entendu, on ne calculera les cofacteurs du PPCM de cette manière que si on doit calculer les
coefficients de Bézout.
Commentaires
Cet exercice peut être traité dès la Terminale S (spécialité maths) (raisonnement par récurrence,
thème abordé) et dans le supérieur.
On peut parler de la méthode de cryptage RSA (le calcul de la clef de décodage en fonction de la
clef de codage fait intervenir les coefficients de Bézout de l’indicatrice d’Euler de l’entier n modulo
lequel on travaille, n étant le produit de 2 grands nombres premiers).
On peut prolonger l’exercice avec le théorème des restes chinois et l’algorithme correspondant.
On peut aussi s’intéresser à la reconstruction d’un rationnel à partir de son image modulo un entier.
L’algorithme de reconstruction est en effet un algorithme de Bézout avec arrêt prématuré. Dans le
cas des polynômes, ce même algorithme avec arrêt prématuré permet de calculer des approximants
de Padé de fonctions. Voir par exemple le manuel Algorithmes de calcul formel de Xcas. La
combinaison des restes chinois et de la reconstruction rationnelle est une brique de base de
nombreux algorithmes efficaces en calcul formel.
Énoncé : Soit A une matrice carrée d’ordre n à coefficients complexes. On se propose de déterminer le
polynôme caractéristique de A en recherchant des relations linéaires entre un vecteur v0 , et ses images
successives par A: vk+1=Avk
1. Montrer que { v0,...,vn} est une famille liée (on pourra donner une combinaison linéaire faisant
intervenir les coefficients du polynôme minimal de A). Déterminer une matrice dont le noyau est le
sous-espace vectoriel des coefficients réalisant une combinaison linéaire nulle entre ces vecteurs.
2. On suppose qu’il existe, à multiplication près, une unique relation linéaire entre ces vecteurs {
v0,...,vn}, en déduire le polynôme minimal et caractéristique de A. Programmer cet algorithme avec
un choix au hasard de v0.
3. On suppose que la matrice A a un polynôme minimal de degré n. Expliquer quelles stratégies
permettraient d’améliorer le programme pour tenir compte de choix malchanceux de v0.
Solution
1. Comme la famille { v0,...,vn} contient n+1 vecteurs dans ℂn elle est forcément liée. On peut
d’ailleurs donner explicitement une combinaison linéaire nulle, si P(x)=∑j=0 n pj xj est le polynôme
caractéristique de A, le théorème de Cayley-Hamilton donne P(A)=0, d’où l’on déduit P(A)v=0 soit
∑ p v =0
j j
j=0
Plus générallement, avoir une combinaison linéaire nulle de coefficients Λ=(λn,...,λ0) revient à dire
que Λ est dans le noyau de la matrice B dont les colonnes sont vn ,...,v0.
2. On a le même type de relation avec le polynôme minimal de A, donc s’il existe une seule
combinaison linéaire à multiplication près, elle est multiple des coefficients du polynôme minimal et
de tout polynôme annulateur de A non nul. Il s’en suit que le degré du polynôme minimal est n, qu’il
est donc égal au polynôme caractéristique et que l’on peut déduire les 2 du calcul du noyau de B (en
multipliant de sorte que le coefficient de vn soit 1 ou (−1)n selon la définition adoptée pour le
polynôme caractéristique).
L’algorithme va donc choisir un vecteur aléatoire v0, calculer les vk (attention pour l’efficacité, il
faut utiliser la récurrence et surtout ne pas calculer les Ak), les mettre en ligne dans une matrice que
l’on transpose pour obtenir B, puis appeler l’instruction ker de calcul du noyau.
polmin(A):={
local k,n,vk,B,noyau;
n:=size(A); // nombre de lignes
vk:=ranm(n); // initialise v0 aleatoire (reel)
B:=[vk]; // initialise B (tranposee)
pour k de 1 jusque n faire
vk:=A*vk;
B[k]:=vk;
fpour;
B:=tran(revlist(B)); // vn ... v0
noyau:=ker(B);
si size(noyau)>1 alors
return "echec de l'algorithme";
fsi;
return noyau[0];
}
On peut le tester avec une matrice aléatoire, par exemple A:=ranm(3,3) . Le même algorithme est
plus délicat à écrire en syntaxe Maple.
3. L’algorithme peut échouer parce que v0 se trouve dans un sous-espace strict de ℂn formé par une
somme de sous-espaces caractéristiques, le polynôme minimal relatif à v0 (obtenu comme premier
élément du noyau de B) est alors un diviseur strict du polynôme minimal. On peut y remédier en
ajoutant une boucle extérieure qui effectue un nombre fini d’essais de choix de v0 (par exemple 3).
On peut même améliorer en prenant le PPCM des polynômes minimaux relatifs aux vecteurs v0
testés.
Commentaires
pivot de Gauss, mais il faut avoir bien conscience qu’il risque d’être difficile à mettre au point
pendant le temps de préparation. On peut par contre implémenter par exemple l’algorithme de la
puissance ou le calcul du polynôme caractéristique par interpolation de Lagrange.
Énoncé :
Soit e∈[0,1[ et t∈[−π,π] On se propose de résoudre l’équation
x=t + e sin(x)
par dichotomie et par la méthode du point fixe et comparer ces deux méthodes. (N.B. e ne désigne pas la
base des logarithmes ici, mais l’excentricité d’une ellipse dont on cherche à résoudre l’équation du temps).
1. Par dichotomie. Soit f(x)=x−t−esin(x). Déterminer le signe de f(−π−e) et de f(π+e), ainsi que le sens
de variations de f, en déduire qu’il existe une unique solution de l’équation. Proposer un algorithme
permettant de trouver une valeur approchée de la solution à 1e-8 près. Combien d’étapes sont-elles
nécessaires ?
2. Par le point fixe. Soit g(x)=t+esin(x). Montrer que g est contractante sur [−π−e,π+e]. En déduire une
suite récurrente convergeant vers l’unique solution de l’équation sur [−π−e,π+e]. Proposer un
algorithme permettant de trouver une valeur approchée de la solution à 1e-8 près. Combien d’étapes
sont-elles nécessaires ?
3. Comparer la vitesse de ces deux méthodes en fonction de e.
Solution
1. f est une fois continument dérivable sur ℝ et sa dérivée est f′(x)=1−ecos(x)>1−e>0 donc f est
strictement croissante. De plus f(−π−e) ≤ −π−e−t+e ≤ 0, f(π +e ) ≥ π+e−t−e ≥ 0 donc f s’annule une
fois et une seule sur l’intervalle [−π−e,π+e].
dicho(f,a,b,eps):={
local m,fa,fb,fm;
// assure une resolution numerique
a:=evalf(a); b:=evalf(b);
fa:=f(a); fb:=f(b);
// teste si a ou b est solution
si fa=0 alors return a; fsi;
si fb=0 alors return b; fsi;
// si fa*fb>=0 pas forcement de solution
si fa*fb>=0 alors return "echec"; fsi;
// debut de la dichotomie
tantque b-a>eps faire
m:=(a+b)/2;
fm:=f(m);
si fm==0 alors return m fsi; // solution trouvee
si fa*fm<0 alors b:=m; sinon a:=m; fsi;
ftantque;
return [a,b]; // intervalle contenant la solution
}
while abs(u1-u0)>eps do
u0:=u1;
u1:=f(u0);
od;
RETURN u0;
end;
g:=x->1+0.1*sin(x); fixe(g,0.0,0.1,1e-8);
Commentaires
La première partie de l’exercice peut être traitée au lycée (dès la seconde en adaptant la fonction,
par exemple avec un polynôme de degré 2 sans paramètre). La deuxième partie est plutôt du niveau
du supérieur. On peut évidemment faire deux énoncés distincts avec cet exercice.
Ces deux méthodes ont une vitesse de convergence linéaire. On pense bien sur à la méthode de
Newton pour avoir une vitesse de convergence quadratique, mais il est souvent plus difficile de
justifier la convergence en pratique (sauf à une variable réelle sous des hypothèses de convexité, par
exemple ici f est convexe ou concave par intervalles).
La méthode du point fixe (et la méthode de Newton) se généralisent en dimension plus grande que
1, ce qui n’est pas le cas en général de la dichotomie. Dans certains cas particuliers, on peut
généraliser la dichotomie, par exemple dans ℂ, en cherchant une solution dans un rectangle que l’on
coupe en 4.
Pour les équations polynomiales, il existe une variété d’algorithmes de résolution : des exactes pour
les degrés 2 à 4 (Cardan, Ferrari) aux approchées (Newton à une variable complexe, Bairstow qui
est une méthode de Newton à 2 variables réelles, les suites de Sturm réelles pour isoler les racines
réelles en basculant sur la dichotomie lorsqu’il ne reste qu’une seule racine dans un intervalle, ou la
diagonalisation numérique de la matrice companion du polynôme).
8 Références
Dans la documentation de Xcas (donc disponible le jour de l’oral 2), aller dans le menu Aide, sous-menu
Manuels, puis Programmation. Vous y trouverez une grande partie des algorithmes ci-dessus. Le manuel
Exercices et le manuel Amusement peuvent aussi contenir des exercices à vocation algorithmique ou
illustrable par Xcas. Enfin, le manuel tableur, statistiques peut servir pour une illustration d’exercices de
proba-stats. Vous pouvez aussi lancer une recherche avec un mot clef (menu Aide, Rechercher un mot, par
exemple Bezout).
En livres :
Guide du calcul avec les logiciels libres XCAS, Scilab, Bc, Gp, GnuPlot, Maxima, MuPAD..., G.
Connan et S. Grognet
Analyse numérique et équations différentielles, Demailly J.-P., Presses Universitaires de Grenoble,
1996 (pour l’analyse)
The Art of Computer Programming, Vol. 2: Seminumerical algorithms, Knuth D., Addison-Wesley,
1998 (pour certains aspects en arithmétique)
A course in computational number theory, Henri Cohen
Mathématiques concrètes, illustrées par la TI-92 et la TI-89. Lemberg H, et Ferrard J.-M., Springer,
1998
Maths et Maple, J.M. Ferrard, Dunod, 1998
Sur le web :
9 Aide-mémoire
Instructions Xcas en français
puissance ^ ** powmod
quotient, reste euclidien iquo irem
affectation a:=2;
entrée expression saisir("a=",a);
entrée chaine saisir_chaine("a=",a);
sortie afficher("a=",a);
valeur retournée retourne(a);
arrêt dans boucle break;
déclaration fonction f(parametres):={ ... }
alternative si <condition> alors <inst> fsi;
si <condition> alors <inst1> sinon <inst2> fsi;
boucle pour pour j de a jusque b faire <inst> fpour;
pour j de a jusque b pas p faire <inst> fpour;
boucle répéter repeter <inst> jusqua <condition>;
boucle tantque tantque <condition> faire <inst> ftantque;
Les indices de tableau commencent à 0 avec la notation [] ou à 1 avec la notation [[]], par exemple
l:=[1,2]; l[0]; l[[1]]
affectation a:=2;
entrée expression input("a=",a);
entrée chaine textinput("a=",a);
sortie print("a=",a);
valeur retournée return(a);
arrêt dans boucle break;
déclaration fonction f(parametres):={ ... }
alternative if (<condition>) {<inst>};
if (<condition>) {<inst1>} else {<inst2>};
boucle pour for (j:= a;j<=b;j++) {<inst>}
for (j:= a;j<=b;j:=j+p) {<inst>}
boucle répéter repeat <inst> until <condition>;
boucle tantque while (<condition>) {<inst>};
Les indices de tableau commencent à 0 avec la notation [] ou à 1 avec la notation [[]], par exemple
l:=[1,2]; l[0]; l[[1]]
Instructions Maxima
puissance ^ ** power_mod
division euclidienne, reste divide mod
affectation a:2;
sortie print("a=",a)
valeur retournée return(a)
déclaration fonction f(parametres):=( ... )
alternative if (<condition>) then <inst>
if (<condition>) then <inst1> else <inst2>
boucle pour for j:1 thru 26 do (inst1,inst2)
for j:2 thru 20 step 2 do (inst,...,inst)
boucle tantque for i:1 while <condition> do (inst,...,inst)
Les indices de tableau commencent à 1 (Xcas syntaxe mode Maple), par exemple l:=[1,2]; l[1];
Instructions Python
puissance ** pow(a,n,m)
quotient, reste euclidien // %
affectation a=2
entrée expression a=input("a=")
sortie print "a=",a
déclaration fonction def f(parametres):
instructions
valeur retournée return a;
arrêt dans boucle break;
alternative if <condition>:
instructions1
else:
instructions2
boucle pour for j in range(debut,fin,pas):
instructions
boucle tant que while condition:
instructions
Les indices de tableau commencent à 0, par exemple l=[1,2]; l[0]; . Attention, le test d’égalité se fait
avec == et non = (affectation).
Instructions Scilab
affectation a=2
entrée expression a=input("a=")
sortie disp("a=",a)
déclaration fonction function nom_var=f(parametres) ... endfunction
valeur retournée nom_var=...;
arrêt dans boucle break;
alternative if <condition> then <inst> end;
if <condition> then <inst1> else <inst2> end;
boucle pour for j=debut:fin do <inst> end;
boucle tantque while <condition> do <inst> end;