Professional Documents
Culture Documents
Pascal Chauvin
Guillaume Connan
Programmation
e n Python p o u r le s
mathmatiques
C o u r s e t e x e r c ic e s
TJ
O
c
2^ dition
rj
tH
O
x:
gi
>-
Q.
O
U
DUNOD
Le pictogramme qui figure ci-contre d'enseignement suprieur, provoquant une
mrite une explication. Son objet est baisse orutale des achats de livres et de
d'alerter le lecteur sur la menace que revues, au point que la possibilitmme pour
reprsente pour l'avenir de l'crit, ___ les auteurs de crer des uvres
particulirement dans le domaine DANGER nouvelles et de les faire diter cor
de l'dition technique et universi rectement est aujourd'hui menace.
taire, le dveloppement massif du Nous rappelons donc que toute
photocopillage. reproduction, partielle ou totale,
Le Code de la proprit intellec de la prsente publication est
tuelle du 1"^juillet 1992 interdit LEPHOTOCOPILLAGE interdite sans autorisation de
en effet expressment la photoco TUE LEU y^ l'auteur, de son diteur ou du
pie usage collectif sans autori Centre franais d'exploitation du
sation des ayants droit. Or, cette pratique droit de copie (CFC, 20, rue des
s'est gnralise dans les tablissements Grands-Augustins, 75006 Paris).
ai
s_
>.
CL
O
U
"
X)
1-
rsj
>.
.
Avant-propos v
2 Modules 51
1 Structure dun module........................................................................................................................... 51
2 Quelques modules Batteries included ..................................................................................... 53
3 Lire et crire dans un fichier ............................................................................................................. 64
4 Manipulation de fichiers C S V ............................................................................................................. 68
a 5 Comment gnrer des graphiques ? ................................................................................................... 70
O 6 Un coup dil vers le module M atpiotlib..................................................................................... 74
c
3 7 Exercices dentranement .................................................................................................................... 75
Cl
tH
O 3 Thmes mathmatiques 77
(N
1 M atrices...................................................................................................................................................... 78
(y)
2 Les nombres : entre analyse et algbre ......................................................................................... 112
ai 3 Le nombre j t ............................................................................................................................................... 149
>- 4 Probabilits................................................................................................................................................ 163
CL
O 5 Relations binaires et graphes............................................................................................................. 170
U
Rcursivit 217
1 Quelques exemples...................................................................................................................................... 217
2 Spirale de pentagones............................................................................................................................... 225
3 Courbe du dragon ...................................................................................................................................... 226
4 Triangle de S i e r p i n s k y ................................................................................................................................. 228
5 Sommes de termes dunesuite gomtrique .....................................................................................232
6 Exercices dentranement .........................................................................................................................233
Classes 236
1 Graphes ...........................................................................................................................................................238
2 Reprsentation des nombres.....................................................................................................................243
3 Listes................................................................................................................................................................. 257
4 Arbres binaires .............................................................................................................................................266
5 Calculateur ....................................................................................................................................................275
6 Polynmes et fractions rationnelles....................................................................................................... 291
7 Exercices dentranement .........................................................................................................................300
Bibliographie 302
TJ
O
c
rj
tJH
D
O
CM
(y)
XI
OJ
>-
Q.
O
U
A v a n t-p ro p o s
Certes, les environnem ents m od ern es de dveloppem ent logiciel (le Rapid Application
D evelopm ent dans la term inologie anglo-saxonne) foisonnent de dispositifs d assistance au
program m eur, dans les outils employs. Mais il y a surtout, depuis quelques annes, la p ro
gram m ation m odulaire et la conception objet, qui p e rm e tte n t de segm enter de gigantesques
projets p o u r u n e ralisation com m une, partage p ar des centaines d individus. Il n en d e
m eure pas m oins que les phases d criture perdurent, qui plus est avec des langages de p ro
gram m ation qui sont en ce d b u t de troisim e m illnaire plus de deux mille, alors que cette
activit a rellem ent pris son essor u n peu avant la Seconde Guerre m ondiale.
Si la program m ation se sert de lalgorithm ique p o u r tre efficace, elle doit aussi tre en
m esure de fournir en plus des program m es la fois lisibles, facilem ent utilisables et m o d i
fiables p a r d autres utilisateurs. D epuis FORTRAN (1956), langage qui laissait lutilisateur trs
proche de la m achine, les langages n e cessent d voluer vers u n plus hau t niveau , savoir,
deviennent toujours plus accessibles.
a
O Par exemple, voici trois routines (la prem ire fonction est exprim e en langage C, la se
c
D
Q conde en langage CaML, la troisim e en langage Python) calculant la factorielle d u n entier
tH naturel n :
O
@ fa c t o r ie lle .c fa c t o r ie lle .m l
x:
DI long f a c t o r ie lle ( lo n g n) { le t rec f a c t o r i e l le = fu n ctio n
>- long r s u lt a t = 1; I 0 -> 1
Q .
O
U unsigned long i ; I n -> n * f a c t o r i e l l e ( n - l ) ; ;
i f (n < 0)
retu rn -1; f a c t o r ie lle .p y
fo r ( i = 1; i < n+1; ++i]
r s u lt a t *= i ; def f a c t o r i e l l e ( n ) :
return r s u lt a t ; i f n > 0: retu rn n * f a c t o r ie lle ( n - l)
} e ls e : retu rn 1
VIII Programmation en Python pour les mathmatiques
H orm is le fait que la version C soit crite dans u n style itratif l o le langage CaML est
redo u tab lem en t efficace en ce qui concerne la rcursivit, quel est le langage de plus h au t
niveau?...
En m athm atiques, les langages de h a u t niveau bass sur u n form alism e logique nous
intressent au plus h a u t p oint car ils on t cette rigueur qui sied notre discipline et so n t en
m m e tem ps m oins parasits par les dtails technologiques des langages trop prs de la m a
chine ou trop lches logiquem ent parlant.
C ependant, les langages com m e le C sont largem ent em ploys (car ils sont lis aux sys
tm es UNIX), to u t com m e la program m ation objet, si prise p o u r la ralisation des interfaces
h o m m e /m a ch in e des program m es industriels.
Cest pou rq u o i nous avons choisi le langage Python. Il a fait ses preuves en ta n t que lan
gage orient objet, to u t en p e rm e tta n t galem ent u n e program m ation im prative et rcursive.
Python p rsente u n e syntaxe claire et reste particulirem ent abordable po u r les dbutants,
to u t en offrant des constructions de h a u t niveau.
Les langages cits ici sont, parm i d autres n o n m oins im portants, largem ent rp an d u s et
dvelopps p ar des quipes la pointe de la recherche inform atique. Ils o n t t penss, am
liors depuis des annes et vitent les cueils de certaines interfaces p r te n d u m en t sim ples
m anipuler m ais qui peuvent cacher de nom breux vices et ne d b o u ch ero n t sur au cu n e utili
sation en dehors du lyce.
Com m e on continue faire des m ath m atiq u es et calculer avec u n papier et u n crayon,
de m m e on prfrera un contexte de program m ation le plus sobre possible, dpouill de to u t
ce qui est inutile et qui n u it la rflexion. Un diteur de texte sim ple (et non u n logiciel de
traitem en t de texte) fait am p lem en t laffaire, accom pagn d u n e console (*N*X de prfrence)
p o u r linterp rtatio n ou la com pilation, puis lexcution d u n program m e. Il sagit vraim ent
de se concentrer sur lessentiel, et nous voyons les lves accepter ce travail, dans la m esure
o la rcom pense est im m diate : soit le program m e fonctionne, soit il ne fonctionne pas,
ou bien il effectue autre chose que ce que son a u teu r prvoyait. A ucune autre rcom pense
nest vise que la satisfaction intellectuelle propre lapprentissage. Or cest l un e priorit de
lcole.
"O
O
c
=3
Q
'JD C o m m e n t u tilis e r c e liv re ?
rH
O
(N
Le p rsen t ouvrage vise deux objectifs : introduire la p ro gram m ation en Python et a p
xz pliquer les notions ainsi acquises aux m athm atiques.
DI Aprs u n prem ier chapitre p r sen ta n t les fon d am en tau x du langage Python, u n deuxim e
>-
Q . chapitre aborde la n o tion de m odule. D u n e part, il est expliqu co m m en t program m er u n
O
U m odule personnel ; d autre part, on p rsen te q uelques-uns des trs nom breux m odules four
nis p ar dfaut avec Python ^ En ce qui concerne les m odules de tierces parties les plus
connus des scientifiques (NumPy et S ciP y p o u r le calcul num rique, M a tp lo tlib p o u r les gra
phiques, SymPy p o u r le calcul formel), nous ne les m en tio n n ero n s que som m airem ent ici ou
1. Nous naborderons pas les modules permettant de manipuler des bases de donnes SQL avec Python. Le lecteur
intress par ce sujet pourra, par exemple, consulter le chapitre 16 de louvrage [SwilO] dont une version lectronique
est librement tlchargeable sur le site de son auteur.
Avant-propos IX
l : en effet, leur p rsen tatio n dtaille dpasse largem ent le cadre de cet ouvrage. En outre,
p o u r le trac des fonctions, nous avons fait le choix de dvelopper, titre pdagogique, un
petit m odule p e rm e tta n t de gnrer u n graphique au form at PostScript partir d u n e liste de
points tracer.
Le chapitre suivant se propose de prsenter une liste varie dalgorithmes mathma
tiques programms le plus simplement possible en Python : sont illustrs plusieurs algo
rithmes darithmtique (algorithme dEuCLiDE, tests de primalit, etc.), de cryptographie (chif
frement de H il l , de V ig en r e , systme RSA, etc.), les problmatiques dapproximation d
cimale (calcul des premires dcimales de par les mthodes de Nicolas de C u es , de John
Mach in , de B ren t et Salam in , etc.), des problmes de probabilits et de thorie des graphes.
Ensuite, sont passes en revue les m thodes classiques d analyse n um rique : rsolution
d quations diverses, d quations diffrentielles ordinaires, de drivation et d intgration n u
m riques.
Les deux derniers chapitres son t davantage to u rn s vers lalgorithm ique. Aprs avoir
trait de la notion de rcursivit, le d ern ier chapitre p ren d com m e fil co n d u cteu r plusieurs
im plm entations d u n p etit calculateur form el : sont abordes quelques structures de d o n
nes classiques (arbres, graphes, piles, queues, etc.) et la co n cep tio n oriente objet, d o n t
un objectif est d obtenir, au m oyen de labstraction, u n e b o n n e m odularit, si utile p o u r les
grands projets.
C ertains program m es u n peu trop longs p o u r figurer sur la version p ap ier so n t d isp o
nibles dans une archive, qui co ntien t en outre lensem ble de ceux du livre, et que lon p eu t
tlcharger sur la page du site www. d u n o d . corn consacre cet ouvrage.
Les notions exposes dans cet ouvrage sont illustres par des exercices rpartis au long
de chaque chapitre. De plus, en fin de chapitre so n t regroups des exercices d e n tran em en t
do n t les corrigs sont disponibles sur le site d u n o d .co m p artir de la page d accueil de lo u
vrage.
O A ucune notion en inform atique n est requise p o u r en trep ren d re la lecture de cet ouvrage.
rs l
(y)
CT C o n v e n tio n s p o u r la p r s e n t a t i o n du code
>.
CL
O
U
Pour lcriture du code, vous rencontrerez plusieurs p rsen tatio n s :
- les instructions prcdes de chevrons dans u n e bote grise sont saisir dans u n e ses
sion interactive ;
> 1 1
2
Programmation en Python pour les mathmatiques
les instructions sans chevrons dans u n e bote grise sont des bouts de code crire
dans u n fichier ;
p r i n t ( ' Bonjour ! ' )
les instructions dans une bote grise avec u n filet som bre gauche et un n o m de fichier
en italique au-dessus de la bote sont des extraits d u n fichier se trouvant dans larchive
tlchargeable sur le site de lditeu r; dans ce cas, si le rsultat de lexcution du script
est p rsente, elle ap p arat im m d iatem en t aprs le script sur fond blanc ;
fic h ie r, p y
# ! /usr/bin/python3
# - * - codi ng: U t f - 8
p r i n t ( 'V o ic i le r s u l t a t .' )
V o ic i le r s u lt a t .
deux traits horizontaux dlim itent u n e session dans u n term inal Unix :
----------------------------------------------------- [ Terminal | ----------------------------------------
$ pythons f ic h ie r .p y
V o ic i le r s u lt a t .
$ pythons
Python S . l . S (rS lS :8 6 8 S 4 , Nov 28 2010, 1 1 :2 8 :1 0 )
[GCC 4 .4 .5 ] on lin u x 2
Type "h e lp ", "c o p y rig h t", " c r e d it s " or " lic e n s e " fo r more in form ation
>1 + 1
2
R e m e rc ie m e n ts
Nous tenons rem ercier vivem ent tous ceux qui o n t relu le m an u scrit de cet ouvrage :
O Alain BUSSER, Stphane G r o g n e t , H ubert H. HUPKES, Grard KUNTZ, Franois P anttgny et
O Aymar DE SAINT-SEINE.
c
=3
Cl Nous rem ercions galem ent nos tu d ian ts et lves p o u r avoir servi de cobayes et
yo
11 propos des am liorations de nos program m es.
O
r\l Enfin, nous rem ercions vivem ent Jean-Pierre D emailly qui a accept de prfacer cet o u
vrage.
03
s_
>.
CL
O
U
I n t r o d u c t i o n a u l a n g a g e P y t h o n
Sommaire
1 Pourquoi Python ? ................................................................................. 1
2 Avant de commencer............................................................................. 2
3 Utiliser Python comme une calculette................................................ 2
4 Variables et affectations...................................................................... 3
5 Fonctions............................................................................................... 6
6 Instructions dcriture et de le ctu re.................................................. 10
7 La structure conditionnelle................................................................... 14
8 Les boucles w h ile ................................................................................. 18
9 Les lis t e s ............................................................................................... 20
10 Les boucles f o r .................................................................................... 28
11 Rcapitulatif sur les principaux t y p e s ................................................ 31
12 Quelques mots sur la rcursivit........................................................ 33
13 Quelques mthodes pour trier unelis te .............................................. 35
14 Quelques primitives usuelles................................................................ 37
14.1 Quelques primitives dun usage c o u r a n t .................................................... 38
14.2 Primitives de conversion de type ................................................................... 38
14.3 It ra te u rs....................................................................................................................... 39
a
O 15 Un mot sur les exceptions................................................................... 40
c
13 16 Complments sur les fonctions........................................................... 41
Q
tJH
D 17 Notions sur les c la sse s......................................................................... 43
O
CM 18 Exercices dentranement...................................................................... 49
(y)
SI
gi
>-
CL
O 1 P o u rq u o i P y th o n ?
U
Le langage de program m ation Python est u n trs b o n choix aussi bien p o u r linitiation la
program m ation que p o u r la program m ation elle-m m e. Cest u n langage de trs h a u t niveau
do n t la syntaxe encourage crire du code clair et de qualit. D ans le dom aine de la gestion de
la m m oire, nom bre de dtails de bas niveau propres aux langages com m e le C disparaissent.
De plus lapprentissage de Python est facilit p ar lexistence d u n e interface interactive. Cela
dit, son intrt ne se rduit pas lapprentissage de la program m ation ou de lalgorithm ique ;
Programmation en Python pour les mathmatiques
2 A vant de c o m m e n c e r ...
Si VOUS navez jam ais program m , le plus sim ple p o u r excuter des instructions P y th o n est
d utiliser len vironnem ent spcialis Idle. Cet en v iro n n em en t se com pose d une fentre a p
pele indiffrem m ent console, shell ou term inal P y th o n .
a
O Linvite de com m ande se com pose de trois chevrons ; il suffit de saisir la suite une instruction
c
3 puis d appuyer sur la touche Entre de votre clavier.
Nous ne drogerons pas la tradition inform atique qui consiste co m m en cer lapprentissage
O d u n langage p ar laffichage^ d une salutation :
rs l
> 2 * 5 + 6- (100 + 3)
-87
>7/2; 7/ 3
3 .5
2.3333333333333335
> 34 / / 5; 34 % 5 # q u o tie n t e t r e s t e de la d i v i s i o n e u c lid ie n n e de 34 par 5
6
4
> 2 ** 7 # pour l'e x p o n e n t ia t io n ( e t non pas 2 ''! !)
128
Au passage, nous avons utilis le sym bole dise # p o u r p lacer des com m entaires dans les
lignes de com m ande ; to u t ce qui se situe droite d u n sym bole # (jusquau ch an g em en t de
ligne) est p u rem en t et sim plem ent ignor p ar linterprteur.
Pour naviguer dans lhistorique des instructions saisies dans la console P y th o n , on p eu t u ti
liser les raccourcis A lt+ p (p com m e previous) et A lt+ n (n com m e next).
4 V a ria b le s e t a fT e c ta tio n s
Que se passe-t-il au juste lorsquon saisit u n n o m b re (par exem ple 128) dans la console P y
th o n ? Eh bien, disons, en prem ire approxim ation, que lin terp rteu r cre u n nouvel objet
(sans prciser po u r lin stan t le sens de ce m ot) et le garde en m m oire.
> 128, id (1 2 8 ), type(128)
(1 , 137182768, < class ' i n f > )
Le m oins que lon puisse dire, cest que lidentifiant ne nous parle gure... D o lin trt des
T3
O affectations. Au lieu de dsigner 128 p a r son identifiant, on va lui d o n n e r un no m com m ode
c
D m anipuler. Au lieu d appeler lobjet M onsieur 137180768 , on lappellera M onsieur A. ,
aprs avoir indiqu lin terp rteu r un e fois p o u r to u te lidentification opre p ar u n m essage
O du type : M onsieur A. M onsieur 137180768 .
]
(S) En pratique, une affectation seffectue laide du sym bole = , com m e ceci :
ai > a = 128
> > a
CL
O
U 128
> a , i d ( a ) , ty p e (a )
(128, 137180768, < cla ss 'in t '> )
> 2 * a
256
Ainsi chaque fois que nous appellerons le n o m bre 128, il nous suffira d invoquer la variable a.
Notez que lobjet dsign p ar a est toujours lobjet 128, rang encore la m m e adresse.
Il faut bien prendre garde au fait que linstruction d affectation = n a pas la m m e signifi
cation que le sym bole d galit = en m a t h m a t i q u e s P a r exemple, le prem ier nest pas
sym trique, alors que le second lest : vouloir changer lordre des lm ents dans u n e in stru c
tion d affectation produira im m an q u ab lem en t u n e erreur dans lin terp rteu r :
> 128 = a
F i l e "< std in> ", lin e 1
S y n ta x E rro r: c a n 't a ssig n to l i t e r a l
Ici se situe un e petite difficult p o u r ceux qui d b u ten t la program m ation. C ontrairem ent ce
que nos habitudes de calcul algbrique p o u rraien t nous laisser penser, linstruction b = a*2
naffecte pas b le double de la valeur a quelle que soit la valeur de a au long de la session
P y th o n . Au contraire, lin struction b = a*2 procde en deux tem ps :
On rem arque que lidentifiant de lobjet auquel renvoie la variable b na plus rien voir avec a.
A utrem ent dit, lobjet nom m b n a plus au cu n e relation avec lobjet n om m a. Ainsi, une
TJ raffectation ultrieure de la variable a nen tran era au cu n ch an g em en t p o u r la variable b.
O
c Avez-vous bien com pris? Alors exercez-vous en lisant les suites d instructions suivantes et
rj
en n o ta n t sur u n papier le co n ten u de chacune des variables chaque tape ; puis excutez
tJH
D
chacune de ces suites d instructions dans la console et vrifiez que ce que vous avez not
O
CM concorde avec ce q u affiche linterprteur.
(y)
xz
OJ > a = 100 > a = 3
>- > b = 17 > b = 4
Q.
O > c = a -b > c = a
U
> a =2 > a = b
> c = b +a > b = c
> a , b, c > a , b,
5. Ceci explique que dans les livres dalgorithme, laffection de expr x se note souvent x exp r.
Introduction au langage Python
Allons u n peu plus loin; il est frquent q u en program m ation, on se serve d u n e variable
com m e d u n co m p teu r et que lon ait donc besoin d in crm en ter (cest--dire augm enter)
ou de dcrm enter (cest--dire dim inuer) la valeur de la variable d u n e certaine q uantit. On
procde alors de la m anire suivante.
> X = 0
> X = X + 1
> X, i d ( x ) , ty p e (x ) # r p .; (1, 137180736, < cla ss ' i n t ' > )
> X = X -I- 1
> X, i d ( x ) , ty p e (x ) # r p .: (2, 137180752, < cla ss ' i n t ' > )
> X = X -I- 1
> X, i d ( x ) , ty p e (x ) # r p .: (3, 137180768, < cla ss ' i n t ' > )
Encore u n e fois, notez bien la diffrence avec le calcul algbrique : alors que lq u atio n x =
X -h 1 n a pas de solution, linstructio n x = x -i- 1 est p arfaitem en t licite, et m m e utilise
co u ram m en t en program m ation.
D taillons la prem ire in struction x = x -i- 1 ci-dessus ; cette instruction procde en deux
tem ps :
- lin terp rteu r value la valeur de x + l lin stan t d o n n ; le rsultat est u n objet de type
entier, de valeur 1, et plac en m m oire avec lidentifiant 137180736.
- ensuite, et seulem ent ensuite, lin terp rteu r affecte au no m qui se trouve gauche de
linstruction d affectation ( savoir x) lobjet o b ten u aprs valuation de lexpression de
droite.
Signalons u n raccourci propre P y th o n trs utile en pratique et qui a lavantage d viter la
confusion avec la m an ip u latio n d quations en algbre.
> X --= 1
1 # remplace x par x+1 > X *= 3 # remplace x par x*3
> X -= 3 # remplace x par x-3 > X /= 2 # remplace x par x/2
Encore u n e fois, il faut bien com prendre q u u n e affectation se droule en deux tem p s : va
luation de lexpression de droite puis cration de lalias avec le n o m du term e de gauche.
Pourriez-vous prvoir le rsultat des deux suites d instructions suivantes ?
Programmation en Python pour les mathmatiques
> X = 19 > X = 19
> x = x + 2 ; y = x * 2 > X, y = x + 2, x * 2
> X, y > X, y
Solution.
5 F o n c tio n s
I
O
Supposons que nous cherchions calculer les im ages de certains nom bres par u n e fonction
(5)
xz
polynom iale donne. Si la fonction en qu estio n est u n peu longue saisir, p ar exemple, / : x
CTI - 6x^ -I- 15x^ -f- 23x^ + X - 9, il est rap id em en t fastidieux de la saisir chaque fois que lon
>-
Q. souhaite calculer lim age d u n nom bre p ar cette fonction.
O
U Une prem ire ide est d utiliser lhistorique de la console p o u r viter de saisir chaque fois la
fonction :
> X= 2
> x**7 - 6*x**6 + 15*x**4 + 23*x**3 + x - 9
161
> X=3
> x**7 - 6*x**6 + 15*x**4 + 23*x**3 + x - 9
Introduction au langage Python
-357
> X = 4
> x**7 - 6*x**6 4- 15*x**4 + 23*x**3 + x - 9
-2885
> f ( 2 ) , f ( 3 ) , f(4)
(None, None, None)
6. Les paramtres figurant entre parenthses dans len-tte dune fonction se nomment paramtres formels, par
opposition aux paramtres fournis lors de lappel de la fonction appels paramtres effectifs.
8 Programmation en Python pour les mathmatiques
Que sest-il pass dans la dernire tentative de dfinition de la fonction f ? Tout sim plem ent,
au cours de lexcution de la fonction f, lexpression x**7-6*x**6+15*x**4+23*x**3+x-9
est calcule, m ais linterprteur, n ayant pas reu linstruction de renvoyer le rsultat, la garde
p o u r lui : il reste m u et et se contente de renvoyer com m e valeur lobjet None.
D aucuns po u rraien t tre tents de rem placer lin stru ctio n r e tu rn p ar la fonction p r i n t que
nous avons entrevue au to u t d b u t de ce chapitre.
> def f ( x ) :
... p rin t(x**7 - 6*x**6 + 15*x**4 + 23*x**3 + x - 9)
> f ( 2 ) , f ( 3 ) , f(4)
19
113
55
(None, None, None)
Voici u n exem ple de calcul qui nous p erm ettra de m ieux com prendre la diffrence fo n d a
m entale entre linstruction r e tu r n et la fonction p r i n t . Supposons que nous cherchions
calculer la som m e des im ages de notre fonction f value en certaines valeurs :
> def f ( x ) :
... return x**7 - 6*x**6 + 15*x**4 + 23*x**3 + x - 9
placer des instructions aprs u n r e tu r n : ces instructions ne seront jam ais lues p ar lin ter
prteur. On parle parfois de code m o rt p o u r dsigner les lignes qui suivent ( lintrieur de la
dfinition d une fonction) linstructio n r e tu r n .
Autre fait notable lorsquon dfinit u n e fonction : les variables dfinies lintrieur d une
fonction ne so n t pas visibles depuis lextrieur de la fonction ; elles corresp o n d en t aux va
riables m uettes en m athm atiques. A ussitt lexcution de la fonction term ine, lin te rp r
teu r efface toute trace des variables internes la fonction. On exprim e cela en disant q u une
telle variable est locale la fonction.
D ans lexem ple suivant, la variable x est u n e variable locale la fonction f : cre au cours de
lexcution de la fonction f , elle est supprim e u n e fois lexcution term ine.
> def f ( y ) :
X = 1
return y
> f(2)
2
> X
Traceback (most recent c a l l l a s t ) :
F il e "< std in> ", lin e 1, i n <module>
NameError: name 'x ' i s not defined
> X = 0
a
O > def f ( y ) :
c
D X = 1
kD return y
O
CM
> f(2)
(y)
2
xz
CTI > X
>- 0
Q.
O
U
D ernier po in t avant de clore cette section : signalons q u u n e fonction p eu t co m p o rter a u tan t
de param tres form els q u on le souhaite (et ventuellem ent aucun) :
6 I n s t r u c t i o n s d c r i t u r e e t de le c tu re
D ception... rien ne saffiche. En fait, le c o m p o rtem en t de lin terp rteu r diffre lgrem ent
suivant que lon travaille dans u n e console P y th o n ou dans u n fichier texte.
En effet, lorsque lin terp rteu r lit u n fichier texte, il effectue les instructions les unes la suite
des autres, m ais il naffiche rien ta n t que cela ne lui est pas d em an d explicitem ent.
D o, dans le fichier prcdent, la ncessit de rajouter la fonction p r i n t si lon souhaite voir
safficher la valeur de la variable x. D u reste, cest p artir du m o m en t o lon crit des scripts
dans des fichiers que ru tilisatio n de la fonction p r i n t p ren d to u t son intrt.
a
O
c
13
Q # !/ u s r / b in / pythons ==== No Subprocess
1I #-*- coding: U tf-8 -* >
O >
X = 2 ** 8 256
p r i n t (x) >
ai
>.
CL
O
U
D ans le fichier prcdent, nous avons plac deux lignes qui, p o u r tre facultatives, nen res
te n t pas m oins nigm atiques p o u r u n d b u tan t : la prem ire, dite ligne de shebang , prcise
o est linterp rteu r^ utiliser p o u r excuter le fichier. Les utilisateurs de systm es d ex
ploitation Linux ou MacOS p o u rro n t alors excuter ce script dans u n Terminal en saisissant :
. / t o t o . p y aussi bien que python3 t o t o .p y
7. Dans un terminal, taper which pythonB pour connatre ladresse absolue de lexcutable.
Introduction au langage Python 11
Parfois, il arrive que souhaite excuter u n script, puis passer dans la foule en m ode in
teractif : il suffit d 'ajo u ter l'op tio n - i :
La deuxim e ligne du fichier source prcise Vencodage, c'est--dire le form at de codage des
caractres utilis dans votre fichier texte. L encore cette ligne est facultative, m ais elle aug
m ente la portabilit de vos program m es d 'u n systm e d'exploitation u n autre. Suivant que
votre systm e d'exploitation utilise p ar dfaut l'encodage L atin-1 ou l'encodage Utf-8 (cette
dernire norm e tan t fortem ent recom m ande), utilisez
D ornavant, p ar souci de gain de place, nous ne m en tio n n ero n s plus ces deux lignes.
M aintenant que nous savons excuter u n e suite d 'in stru ctio n s dans u n fichier, revenons u n
in stan t sur l'in d en tatio n dans la dfinition d 'u n e fonction. crivez dans des fichiers les deux
scripts suivants, et prvoyez le drou lem en t de leur excution, puis vrifiez en les excutant :
def f ( ) : def f ( ) :
p r i n t { ' H e llo ') p r i n t ( 'H e llo ')
p r i n t ( ' B o n jo u r') p r i n t ( ' B o n jo u r')
f() f()
a A rrtons-nous quelques instants sur la fonction d'criture p r i n t . Cette fonction com porte de
O
c nom breuses options qui p e rm e tte n t de personnaliser la p rsen tatio n des donnes :
13
Q
1t X, y = 3, 1000000000 ==== No Subprocess ====
Q
rsi Z = 3.1416 >
p r in t ( x , y , Z, se p = '') 310000000003.1416
p r in t ( x , y , Z, sep= '; ) 3; 1000000000; 3.1416
>. p r in t ( x , y , Z, sep='\n ) 3
CL
O p r i n t ( 'x = ', X, se p = '' , end='; ') 1000000000
U p r i n t ( 'y = ', y , se p = '' , end=' ; ') 3.1416
p r i n t ( ' z = ', Z, se p = '') x=3; y=1000000000; z=3.1416
Bien que n'ayant pas encore parl des chanes de caractres, nous les avons dj em ployes au
dto u r de nos exemples, com m encer p ar le fam eux p r i n t {" h e llo " ). Une chane de carac
tres (c'est--dire u n objet de type s t rin g ) est une succession de caractres typographiques
12 Programmation en Python pour les mathmatiques
de longueur quelconque, dlim ite par de sim ples quotes (apostrophes) ou des doubles
quotes (guillemets). Les triples guillem ets p e rm e tte n t d inclure des retours la ligne lin
trieur de la chane.
p r i n t ( ' - > I c i on peut employer des "g u ille m e ts" ! ' )
p r i n t ( " - > I c i on peut employer des 'apostrophes' !" )
p r i n t ( " " " - > V o i c i un s a u t . . .
de l i g n e . ......)
p r i n t ( " - > On peut a u s s i\n p asser la lig n e a i n s i ." )
Pour disposer sur plusieurs lignes une chane de caractre u n peu longue dans u n fichier de
script, il est dconseill d utiliser un e contre-oblique ; la syntaxe suivante est prfrable^ :
p r i n t ( ' - > Comment couper une lig n e '
'tro p longue dans le f ic h ie r source ? ')
La m thode f o rmat de lobjet s t rin g est u n outil trs p u issan t p e rm e tta n t de crer des chanes
de caractres en rem plaant certains cham ps (entre accolades) p ar des valeurs (passes en ar
g um ent de la fonction f o rmat) aprs conversion de celles-ci. On p e u t prciser lin trieu r de
chaque accolade u n code de conversion, ainsi que le gabarit d affichage. D onnons quelques
exemples.
> X = 1037.123456789
> g } ' . f o r m a t (x ) # c h o i s i t l e f or mat l e p l u s a p p r o p r i
' 1.04e+O3'
> 3 f } ' . f o r m a t (x ) # f i x e l e nombre de dcimales
T3 '1037.123'
O
c > ' { : . 3 e } ' . f o r m a t ! x) # n o t a t i o n s c i e n t i f i q u e
3
' 1.037e+03'
KD > ' {0 :2 0 .3 f > ' . f o r m a t ( x ) # p r c i s e l a longueur de l a chane
tH
O ' 1037.123'
CM
(y) > ' { 0 :> 2 0 .3 f } ' . f o r m a t ( x ) # j u s t i f i d r o i t e
xz ' 1037.123'
CTI
> ' {0 :< 2 0 .3 f> ' . f o r m a t ( x ) # j u s t i f i gauche
>-
Q. '1037.123
O
U > ' {0 :''2 0 .3 f> ' . f o r m a t ( x ) ^ c e n t r
' 1037.123
> '{0 :+ .3 f> ; { l :+ .3 f > ' . f o r m a t ( x , - x ) # a f f i c h e t o u j o u r s l e sig ne
'+1037.123 ; -1037.123'
> ' { 0 : .3f> ; {1 : .3 f> ' . f o r m a t ( x , - x ) # a f f i c h e un espace s i x>0
8. Pour plus de dtails, cf. la dernire section de http : //d o e s. python. o rg / re le a s e / 3 . 1 . 3/howto/doanddont.
html
Introduction au langage Python 13
D ception, notre tentative choue : on rem arq u e que la valeur 3 a p o u rta n t bel et bien t
rcupre p ar le program m e et que la variable x sem ble co n ten ir lentier 3. Or il n en est rien.
Ce que contient la variable x, cest la chane de caractres "3". Et u n e chane de caractre ne
peu t tre leve au carr.
Do la ncessit de parler t t ou tard du type d u n objet... Sans trop entrer dans les dtails
du fo n ctionnem ent d u n ordinateur, rappelons que to u te inform ation, et en particulier le
con ten u d une variable, doivent tre cods en binaire. Mais le dictionnaire p o u r coder ou
dcoder le co n ten u d u n e variable ne sera pas le m m e suivant que lon a affaire u n e n
tier, u n nom bre en no tatio n scientifique ou u n e chane de caractres. Dans ces conditions,
la connaissance du co n ten u binaire d u n e variable ne suffit pas p o u r d term in er linform a
tion correspondante. Il est ncessaire de savoir, en outre, co m m en t la valeur qui sy trouve est
T3
O code. Cette distinction correspond la no tio n de type.
c
3
Pour connatre le type d u n objet, nous avons dj vu q u on disposait de la fonction ty p e :
Un peu dans le m m e ordre d ides, citons la fonction exec qui p erm et d excuter u n e in s
tru ctio n reprsente p ar une chane de caractres.
D onnons u n p etit exem ple sans le dtailler (pour se m ettre en apptit, il fait apparatre le m o
dule math qui p erm et d 'im p o rte r les fonctions m ath m atiq u es usuelles, ainsi que certaines
constantes usuelles com m e le nom bre tt).
from math i m p o r t *
X = e v a l( in p u t( ' x= ?' ) )
fo n ctio n = in p u t( 'f = ? ')
code = ("d e f f ( x )
" return { } " .fo rm a t(fo n ctio n ))
exec(code)
p r i n t ( ' { : . 6 f } ' . f o r m a t ( f ( x ) ))
x= ?pi/4
f= ? s in (x )
0.707107
Pour term iner cette section, o nous avons appris crire de petits scripts dans des fichiers,
signalons q u il est bon de prendre to u t de suite lh ab itu d e de bien p rsen ter son code en Py
thon selon les conventions suivantes :
# Dconseill # C onseill
def f ( x ) : def f ( x ) :
return 1 return 1
a
O
c
13 x= l ; y= 2;z = 3 x = l ; y = 2 ; z = 3
x, y ,z X, y, Z
tH f (Z) f(z)
O
(N
XI P o u r p lu s d e p r c is io n s . o n se r e p o r t e r a a u lie n s u iv a n t : h t t p : / / d o e s
> t u t o r i a l / c o n t r o l f l o w .h t m l # i n t e r m e z z o - c o d in g - s t y l e
Q.
O
U
7 La s tru c tu re c o n d itio n n e lle
X si X > 0
S u p p o s o n s q u e n o u s s o u h a it io n s d f in ir la f o n c t io n v a le u r a b s o lu e : |x | = ,
1 - x si X < 0
N o u s d e v o n s a lo r s u t ilis e r u n e in s t r u c t io n q u i o p re u n e d is jo n c t io n d e c a s.
En P y th o n , i l s a g it d e l in s t r u c t io n d e c h o ix in t r o d u it e p a r le m o t -c l i f . L a s y n ta x e e s t a lo r s
la s u iv a n t e :
Introduction au langage Python 15
f(2)=2
f(-2)= 2
> 2 >= 0 # rp
> b = 2 >= 0
> b, i d ( b ) , t y p e (b) # rp
La condition 2 >= 0 est d u n type que nous navons pas encore rencontr, savoir le type
boolen^. U ne variable boolenne ne p eu t prendre que deux valeurs : True [vrai) ou F a ls e
[faux).
La condition de choix est vrifie q u an d lvaluation de cette condition renvoie le boolen
T rue et lin terp rteu r excute alors la suite d instructions qui se trouve dans le prem ier bloc
d instructions. D ans le cas contraire lin terp rteu r saute au bloc d instructions situ aprs le
m ot-cl e l s e et dlim it p ar lindentation.
11 faut bien n oter le rle essentiel de V indentation qui p erm et de dlim iter chaque bloc d in s
tructions et la prsence des deux points aprs la condition du choix et aprs le m ot cl e ls e .
A ttardons-nous quelques instants sur les boolens. Pour ob ten ir u n e variable boolenne, on
utilise en gnral, com m e d ans lexem ple prcdent, u n ou plusieurs oprateurs de com parai
son. Ces oprateurs sont au nom bre de h u it :
X == y X est gal y
X != y X est diffrent de y
X > y X est strictem en t su p rieu r y
"O X < y X est strictem en t infrieur y
o
c
n X >= y X est su p rieu r ou gal y
(S)
X in y X ap p artien t y (voir le type l i s t )
> X = -1
> (x > -2) and (x**2 < 5) # rp. True
> (x <= -2) or (x**2 > 5) # rp. False
> not(x >= -2) # rp. False
> -2 < X <= 0 # rp. ; True
Les oprateurs non boolens sont prioritaires sur les oprateurs de comparaison, qui sont
prioritaires sur les oprateurs logiques. Cependant, pour amliorer la lisibilit du code, il est
prfrable dutiliser des parenthses lorsquon crit des conditions complexes.
Il est parfois utile de dfinir d es fo n c tio n s boolennes, cest--dire qui renvoient toujours une
valeur boolenne, pour effectuer un test complexe.
Voici deux versions dune fonction boolenne qui prend en argument trois nombres et renvoie
le boolen T rue sils sont rangs par ordre croissant :
Notons que lorsque les conditions et les instructions dune structure conditionnelle sont as
sez brves, on peut les crire sur une seule ligne :
def valeur_absolue(x):
return X i f X >=0 e l s e -x
En algorithmique, il est assez frquent que lon ait enchaner des disjonctions de cas. Au
lieu dutiliser des choix imbriqus, on peut prsenter cet enchanement en une succession de
choix, cette deuxime rdaction reprsentant alors une alternative syntaxique plus agrable.
Notons une fois de plus combien Python offre des facilits de syntaxe qui en font un langage
pertinent pour lapprentissage de la programmation.
Illustrons ces deux possibilits pour dfinir une fonction qui prend en argument trois nombres
a, b et c et qui affiche une phrase indiquant le nombre de solutions relles de lquation du
TJ second degr a x^ + b x + c = 0.
O
c
rj def nbre_solutions(a, b, c ):
if a == 0:
tH
O printC'L'quation est du premier degr.")
else:
delta = b**2 - 4*a*c
xz
OJ i f delta > 0:
>- printC'L'quation possde deux solutions r e lle s ." )
Q.
O else:
U
if delta == 0:
printC'L'quation possde une solution r e lle ." )
else:
printC'L'quation ne possde pas de solution r e lle ." )
def nbre_solutions(a, b, c ):
delta = b**2 - 4*a*c
Introduction au langage Python 17
if a == 0:
printC'L'quation est du premier degr.")
e l i f delta > 0:
printC'L'quation possde deux solutions r e lle s ." )
e l i f delta == 0:
printC'L'quation possde une solution r e lle ." )
else:
printC'L'quation ne possde pas de solution r e lle ." )
Exercice 1. crire une fonction max2 qui renvoie le plus grand des deux nombres x et y.
Construire une fonction max3 qui calcule le maximum de 3 nombres.
Solution.
a) crire une fonction boolenne b i s s e x t i l e ! n) qui permet de tester si une anne est
bissextile. On rappelle que les annes bissextiles reviennent tous les 4 ans, sauf les an
nes sculaires, si celles-ci ne sont pas multiples de 400. Ainsi, 1900 ntait pas une an
ne bissextile, alors que 2000 ltait.
b) crire la mme fonction en utilisant uniquement des oprateurs logiques (sans bran
chement conditionnel).
a
O Solution.
c
D
def b is s e x t ile (n ):
kD
O if n % 4 != 0:
rs] r e t u r n False
e l i f n % 100 != 0:
CTI r e t u r n True
lu.
>- e lif n % 400 != 0:
Q.
O r e t u r n False
U
else:
return True
def b is s e x tile 2 (n ):
r e t u r n ((n % 4 == 0) and (n % 100 != 0)) o r (n % 400 == 0)
8 L es b o u c le s w h ile
Aprs avoir introduit les structures de choix, nous nous intressons aux structures de rp
tition : ces structures permettent dexcuter plusieurs reprises un bloc dinstructions. Ces
rptitions se classent en deux catgories :
- les rptitions conditionnelles : le bloc dinstructions est rpter autant de fois quune
condition est vrifie.
- les rptitions inconditionnelles : le bloc dinstructions est rpt un nombre donn de
fois.
Commenons par les rptitions conditionnelles. Une telle rptition est introduite par le
mot-cl w h ile suivi de la condition ponctue dun deux-points, puis vient le bloc dinstruc
tions rpter, ce dernier tant dlimit par lindentation.
Par exemple, soit crire une fonction prenant en argument un entier N et renvoyant (sans
recourir la fonction logarithme) le plus petit entier n tel que 2 est suprieur lentier N.
def e s s a i ( N ) :
n = 0
w h i l e 2**n <= N:
n += 1
return n
- on teste la condition ;
- si la condition est vrifie, cest--dire si lvaluation de lexpression boolenne renvoie
la valeur T rue. Python effectue les instructions et on revient au dbut de la boucle ;
- si elle nest pas vrifie, cest--dire si lvaluation de lexpression boolenne renvoie la
valeur False, on sort de la boucle.
Si la condition mentionne ne devient jamais fausse, le bloc dinstructions est rpt indfi
niment et le programme ne se termine pas. Quand on crit une boucle, il faut imprativement
TJ
O sassurer quelle va rellement sarrter (dans les conditions normales dutilisation).
c
rj Notons que la fonction de lexemple prcdent peut tre programme diffremment :
Q
'JD
def e s s a i ( N ) :
O n = 0
(N
w hile True:
i f 2**n > N:
OJ
s_ return n
>.
CL n += 1
O
U
videmment, lapparence de cette boucle est paradoxale car la condition de la boucle w hile
ne varie jamais, et on pourrait avoir limpression quelle ne va jamais se terminer; mais cest
sans compter sur la possibilit de sortir en force des boucles par renvoi du rsultat dune
fonction (grce au mot-cl return).
10. Pour interrompre un programme (mal conu) qui ne se termine pas, on utilise la combinaison de touches
C trl- C .
Introduction au langage Python 19
Exercice 3.
a) crire une fonction somme ( n ) qui renvoie la somme des carrs des n premiers entiers.
b) crire une fonction dpass(M) qui, pour tout entier M, renvoie le plus petit entier n
tel que 1^ + 2^ + + > M.
Solution.
Algorithme dEuclide
a
O
c
13
yo
O
rM
(5)
"s_
>.
CL
O
U
20 Programmation en Python pour les mathmatiques
Solution.
Remarquons que dans les affectations parallles a, b = b, reste (a, b ), les affectations
sont sim u lta n es et non successives.
Avant de nous intresser aux rptitions inconditionnelles, nous aurons besoin dintroduire
la notion de liste.
9 L e s lis te s
xz
Comme on le voit dans lexemple prcdent, une liste est une squence dlments, rangs
OJ dans un certain ordre ; de plus, en Python, une liste nest pas ncessairement homogne :
>-
Q. elle peut contenir des objets de types diffrents les uns des autres.
O
U La premire manipulation que lon a besoin deffectuer sur une liste, cest den extraire un
lment : la syntaxe est alors l i s t e [ i n d i c e ] . Par exemple, cherchons extraire un lment
de notre liste :
> lis te = [12, 11, 18, 7, 15, 3]; liste [2 ] # r p . : 18
Le rsultat peut surprendre : on aurait peut-tre attendu comme rponse 11 au lieu de 18. En
fait, les lments dune liste sont indexs p a rtir d e 0 et non de 1.
Introduction au langage Python 21
> l i s t e = [ 1 2 , 1 1 , 1 8 , 7 , 1 5 , 3]
> lis te [0 ], lis t e [ l] , lis te [2 ], lis te [3 ], lis te [4 ], liste [5 ]
( 1 2 , 1 1 , 1 8 , 7 , 1 5 , 3)
> liste [6 ]
T r a c e b a c k (most r e c e n t c a l l l a s t ) :
F i l e " < s t d i n > " , l i n e 1 , i n <module>
I n d e x E r r o r : l i s t i n d e x out o f r an ge
Encore une fois, le rsultat nest peut-tre pas tout fait celui que lon attendait. En fait, pour
bien comprendre les techniques de saucissonnage, il faut penser les indices comme rep
rant non pas les tranches de saucisson, mais les coups dopinel qui ont permis de couper les
tranches (en partant videmment de 0 pour lentame).
0 1 2 3 4 5 6
T ? T T T T
12 1 11 18 7 15
A A A A
-6 -5 -4 -3 -2 -1
Remarquez que lon peut mme se servir dindices ngatifs. prsent, les rsultats suivants
doivent devenir limpides :
tH
O
[12, 11] []
> liste [0 :le n (liste ) ] > l i s t e [ -4 : -2]
[ 1 2 , 1 1 , 1 8 , 7 , 1 5 , 3] [18, 7]
Je
> l i s t e [ : ] # l e mme en mieux > l i s t e [ l e n ( l i s t e ) -1]
>- [ 1 2 , 1 1 , 1 8 , 7 , 1 5 , 3] 3
Q.
O > lis te [2 :5 ] > lis t e [-1] # l e mme
(J
[18, 7, 15] 3
Pour extraire le dernier lment dune liste, linstruction l i s t e [ -1] remplace avantageuse
ment linstruction l i s t e [l e n ( l i s t e ) -1 ] !
noter que lorsquon utilise des tranches, les dpassements dindices sont licites.
prsent, examinons o sont rangs les lments dune liste.
22 Programmation en Python pour les mathmatiques
On constate donc quune liste fonctionne comme un carnet dadresses qui contient les em
placements en mmoire des diffrents lments de la liste.
a En Python, les listes sont des objets m o d ifia b les^^, cest--dire quon peut modifier un ou
O plusieurs lments de la liste.
c:
=3
Q
tH > lis te [l] = 2**8
O
(N > lis t e , id ( lis t e ) , typ e (liste )
( [ 1 2 , 256, 3 . 1 4 ] , 3073241260, < c l a s s ' l i s t ' > )
> l i s t e [ 0 ] , i d ( l i s t e [ 0 ] ), t y p e ( l i s t e [ 0 ] )
03
s_ (12, 137180912, < c la s s ' in t '> )
>-
CL > l i s t e [ l ] , i d ( l i s t e [ l ] ), t y p e ( l i s t e [ l ] )
O
U (256, 1 3 7 18 4 8 16 , < c l a s s ' i n t ' > )
> l i s t e [ 2 ] , i d ( l i s t e [ 2 ] ), t y p e ( l i s t e [2])
(3.14 , 164411812, < cla ss 'flo a t'> )
11. On parle aussi dobjet m u ta b le : un tel objet peut changer de valeur sans changer didentifiant !
Introduction au langage Python 23
Remarquez bien que la liste na pas chang didentifiant. Autrement dit, la liste l i s t e est le
mme objet que prcdemment, on en a seulement modifi la valeur]
Les techniques de saucissonnage peuvent tre utilises pour les modifications de listes, comme
le montrent les exemples suivants.
> l i s t e = [12 , 1 1 , 18, 7, 1 5 , 3]
> lis t e [ 2 :5 ] = [ 'a ', 'b', 'c']
> lis te
[ 1 2 , 1 1 , ' a ' , - b ' , - C , 3]
> l i s t e = [ 1 2 , 1 1 , 18, 7, 1 5 , 3]
> lis t e [ 2 :5 ] = [ 'a ', 'b', 'c']
> lis te
[ 1 2 , 1 1 , ' a - , - b ' , ' C , 3]
> l i s t e [ 2 : 5 ] = [ 1 0 0 , 200]
> lis te
[ 1 2 , 1 1 , 1 0 0 , 2 00 , 3]
> lis t e [ 2 :4 ] = ['u n', 'deux', 'tro is', 'quatre']
> lis te
TJ [12, 1 1 , 'un', 'deux', 'tro is', 'quatre', 3]
O
c
D Il est assez frquent de copier des listes. Mais l encore. Python nous rserve quelques sur
tH prises...
O
(N
> l i s t e = [12, 'un', 3.14]
> copie = l i s t e
OJ > l i s t e [ 0 ] = 100 # m o d i f i c a t i o n de l ' o b j e t lis te
s_ > lis te , copie
>-
CL
O ( [ 1 0 0 , ' u n ' , 3 . 1 4 ] , [100, ' u n ' , 3 . 1 4 ] )
U
> c o p i e [ 1 ] = 'ah ? ' # m o d i f i c a t i o n de l ' o b j e t copi e
> lis te , copie
([100, ' ah ? ' , 3 . 1 4 ] , [100, ' ah ? ' , 3.14])
Pour bien comprendre ce qui sest pass, examinons une fois de plus les identifiants :
> lis t e , id ( lis t e ) , typ e (liste )
( [ 1 2 , 'u n ', 3 . 1 4 ] , 3071856812, < c la s s 'lis t'> )
24 Programmation en Python pour les mathmatiques
En fait, nous avons cr un nouvel alias nomm cop ie pour notre liste. Autrement dit, les
variables l i s t e et cop ie pointent vers le mme objet. Ainsi, lorsqu'on modifie la valeur de
lobjet, la modification sera visible depuis les deux alias ! Ce mcanisme a t implment par
les dveloppeurs de Python dans un souci vident doptimisation de la mmoire.
Mais alors, cela signifie-t-il quon ne pourra pas copier une liste en obtenant un objet distinct
et indpendant de la liste copie pour, par exemple, modifier la nouvelle liste tout en gardant
en mmoire une copie de la version de dpart ?
videmment, cette possibilit existe, mais il faut alors extraire de la liste la sous-liste en entier,
avant de la raffecter une autre variable. Comme on la vu, extraire toute la liste dune liste
se fait avec lcriture l i s t e [ : ] et on crira alors :
copie = l i s t e [ : j # q u i v a u t en f a i t l ' i n s t r u c t i o n : > c opi e = l i s t ( l i s t e )
Dans ce cas. Python effectue une copie superficielle de la liste (en anglais, sh a llo w copy). En
fait, ce ne sont pas les objets eux-mmes qui sont copis, mais les pointeurs vers les objets
copis. Do le nom de copie d e rfrences (ou copie d e pointeurs) encore donn ce type de
copie.
> copie = l i s t e [ : ]
> l i s t e [ 0 ] = 100
> l i s t e , copie
([100, 'u n ', 3 .1 4 ] , [12, 'u n ', 3.14])
> c o p i e [ 1 ] = 'ah ? '
> l i s t e , copie
([100, 'un', 3 .1 4 ] , [12, 'ah ? ' , 3.14])
> lis t e , id ( lis t e ) , typ e (liste)
([10 0 , 'u n ', 3 . 1 4 ] , 3071843148, < c la s s ' l i s t ' > )
> copie, id ( c o p ie ) , type(copie)
( [ 1 2 , ' ah ? ' , 3 . 1 4 ] , 3 0 7 1 8 5 9 8 8 4 , < c l a s s ' l i s t ' > )
kD
O
rs]
ai
>
CL
O
U
Introduction au langage Python 25
Cette notion de copie superficielle rserve quelques surprises. En effet, lorsque la liste contient
des objets modifiables (comme des listes), ce sont bien les rfrences de ces listes qui sont co
pies, et non les objets eux-mmes. Ce qui permet de comprendre les rsultats suivants :
> X = [ 'a ', 'b ' , [4, 5 , 6] ]
> y = X # c r a tio n d'un a l i a s
> Z = x[:] # copi e s u p e r f i c i e l l e
> x[0] = 'c ' # a f f e c t e x e t y mais pas z
> z [ 2 ] [ 2 ] = 365 # a f f e c t e x, y e t z !
> x; y; z
[ C, - b ' , [4, 5, 365]]
[ C, ' b ' , [4, 5, 365]]
[ a', - b - , [4, 5 , 3 6 5 ] ]
Pour effectuer une copie vraiment indpendante dune liste (ou dun objet en gnral), on
peut utiliser la fonction deepcopy du module copy : cette fonction permet de copier rcur
sivement tous les objets dune liste ; do le nom de copie p ro fo n d e ou de copie rcursive (en
anglais, deep copy).
> i m p o r t copy
> X = [ 'a' , ' b ' , [ 4, 5, 6] ]
> y = X # c r a tio n d'un a l i a s
> z = X[ : ] # c opi e s u p e r f i c i e l l e
> w = copy . d e e p co p y (x) # c opi e prof on de
> X[0] = ' c ' # a f f e c t e x e t y mais n i z, n i w
> z [ 2 ] [2] = 365 # a f f e c t e x, y e t z mais pas w
> x; y; z; w
[ C, ' b C [4, 5 , 3 6 5 ] ]
[ c', ' b ' , [ 4, 5 , 3 6 5 ] ]
['a ', - b - , [4, 5, 365]]
['a ', ' b , [4, 5 , 6 ] ]
x:
gi i d ( x ) = 3072672108 i d ( z ) = 3071786220
>- i d ( c ) = 3073232288 i d ( a ) = 3072939136
CL
O i d ( b ) = 30 73 28 56 96 i d ( b ) = 30 73 28 56 96
U
i d ( [ 4 , 5, 365]) = 3071864268 i d ( [ 4 , 5 , 3 6 5 ] ) = 30 71 8 6 4 26 8
i d ( y ) = 3072672108 id(w) = 3072672172
i d ( c ) = 3073232288 i d ( a ) = 3072939136
i d (b) = 30 73 28 56 96 i d (b) = 30 73 28 56 96
i d ( [ 4 , 5, 365]) = 3071864268 id {[4 , 5, 6 ] ) = 30 7 18 6 47 48
26 Programmation en Python pour les mathmatiques
Nous avons vu trois sortes de copies de listes. Autre opration trs courante : la concatnation
de deux listes laide de loprateur + :
> [1, 2] + [4, 7, 9] # r p. : [1, 2, 4, 7, 9]
Autre modification trs courante : rajouter un lment en fin de liste. La premire mthode
qui vient lesprit est la suivante :
> l i s t e = [12, 11, 18, 7, 15, 3]
> lis t e , id ( lis t e ) , typ e (liste)
( [ 1 2 , 1 1 , 18, 7, 15, 3 ] , 3071843148, < c la s s 'lis t'> )
> l i s t e = l i s t e + [5]
> lis t e , id ( lis t e ) , typ e (liste)
( [ 1 2 , 1 1 , 18, 7, 1 5 , 3, 5 ] , 3071858764, < c l a s s lis f> )
Linconvnient de cette mthode est quelle est coteuse du point de vue de la gestion de la
mmoire : en fait, linterprteur a effectu une copie profonde de la premire liste, y a ajout
llment 5 et a raffect la variable l i s t e . Pour viter davoir copier implicitement lob
jet l i s t e , on peut employer la syntaxe suivante, qui ne fait que modifier la valeur de lobjet
lis te :
> l i s t e = [ 1 2 , 1 1 , 1 8 , 7 , 1 5 , 3]
> lis t e , id ( lis t e ) , typ e (liste)
( [ 1 2 , 1 1 , 18, 7, 15, 3 ] , 3071843148, <class lis f> )
> l i s t e += [5]
> lis t e , id ( lis t e ) , typ e (liste)
( [ 1 2 , 1 1 , 18, 7, 1 5 , 3, 5 ] , 30 7184 314 8, < c l a s s lis f> )
Une troisime possibilit nous est donne par la m th o d e append ( ). Nous avons dj em
ploy couramment le mot objet sans pour autant le dfinir prcisment; cependant, nous
avons dit quun objet possde toujours une valeur, un identifiant et un type. Certains objets
Python possdent en outre un certain nombre de fonctions qui ne sappliquent qu un type
donn dobjets; on parle alors de m th o d e associe un objet. Parmi les nombreuses m
thodes que possde une liste, il y en a une qui permet dajouter un lment en fin de liste,
cest la mthode append ( ). Voici comment lutiliser :
a > l i s t e = [ 1 2 , 1 1 , 1 8 , 7 , 1 5 , 3]
O
c
13 > lis t e , id ( lis t e ) , typ e (liste )
Q ( [ 1 2 , 1 1 , 18, 7, 1 5 , 3 ] , 3071858764, < c l a s s U sf>)
1I > liste .ap p end (5)
O
> lis te , id (lis te ), typ e (liste )
([12, 11, 18, 7, 15, 3, 5], 3071858764, < c l a s s 'U st'> )
ai Remarquons cette syntaxe qui peut surprendre la premire fois quon la rencontre ; il sagit
>.
CL de la notation point : linstruction l i s t e . append(5) signifie que lon modifie la valeur de
O
U lobjet l i s t e en lui appliquant la mthode append ( ) avec comme paramtre effectif 5. De
plus, tant donn que la mthode append ( ) renvoie comme valeur lobjet None, ce serait une
erreur de rajouter une opration daffectation.
Parmi les trois mthodes que lon vient de citer pour ajouter un lment une liste, cest
lutilisation de la mthode append ( ) qui est la plus efficace du point de vue de lutilisation de
la mmoire ; elle est donc privilgier.
Enfin, parmi les mthodes associes aux listes, mentionnons les plus utiles :
Introduction au langage Python 27
Avant daborder la structure de choix inconditionnelle, introduisons une primitive qui nous
sera trs utile pour la suite, savoir la fonction l e n (du mot anglais length) qui renvoie la
longeur dune liste. Notons de plus que la suppression dun lment peut seffectuer laide
de la fonction d e l (du mot anglais delete).
> lis t e = ['a ', 'b', 'c ', 'd', 'e', 'f , 'g']
> le n (liste ) # rp.: 7
> d e l l i s t e [4]
> lis t e , le n (liste )
( [ ' a ' , 'b', 'c ', 'd', 'f , *g'], 6)
TJ
O Exercice 5. crire une fonction boolenne qui cherche si un lment existe dans une liste.
c
D Solution.
kD videmment, pour une bonne programmation, le balayage de la liste doit sarrter la pre
O mire occurrence de x ventuellement trouve.
rs]
(y) def e x is t e ( x , l i s t e ) :
sz
OJ for y in lis t e :
>- i f X == y : r e t u r n T r u e
Q.
O return False
U
12. Une fonction primitive dsigne une fonction de base fournie par le langage, cf. section 14 page 37.
28 Programmation en Python pour les mathmatiques
10 L es b o u c le s f o r
Pour effectuer une telle rptition, on dispose dune structure de rptition nous conomisant
dune part linitialisation du compteur (i = 0), et dautre part son incrmentation (i += 1) :
cest la structure introduite par le mot-cl f o r :
Nous voyons apparatre ici pour la premire fois la fonction range. Cette fonction cre un
itrateur, cest--dire en quelque sorte un distributeur dentiers conscutifs Au lieu de crer
et garder en mmoire une liste dentiers, cette fonction gnre les entiers au fur et mesure
des besoins, toujours dans un souci doptimisation de la mmoire.
Avec un argument, range ( n ) renvoie un itrateur parcourant lintervalle [O, - l] ; avec deux
arguments, range {n, p ) parcourt lintervalle {n, p - l] ; enfin employe avec trois arguments,
a range ( n, p , k) parcourt lintervalle {n, p - l] avec un pas gal k.
O
c Signalons que la fonction range peut servir crer des listes dentiers, moyennant une conver
13
Q sion de type opre par la fonction l i s t . Examinons quelques exemples.
1I
O
> l i s t ( r an g e ( 10 ) ) [ 0, -1, -2, -3, -4, -5 ]
[0, 1 , 2 , 3 , 4, 5 , 6, 7 , 8, 9]
ai > lis t(ra n g e (l, 11))
> l i s t ( r a n g e (0) ) , l i s t ( r an g e( 1 , 0))
>. [ 1 , 2 , 3 , 4 , 5 , 6, 7 , 8, 9, 10]
CL [] []
O > l i s t ( range(0, 30, 5))
(J
[0, 5 , 1 0 , 1 5 , 2 0 , 25]
> lis t ( r a n g e ( 0 , 10, 3)) > l i s t ( r a n g e ( 9, 0, - 1 ) )
[0, 3 , 6, 9] [9, 8, 7 , 6, 5 , 4, 3 , 2 , 1]
> list(ran g e (0 , -6, -1))
13. Plus prcisment, un itrateur est un objet possdant une mthode i t e r ( ) qui renvoie les lments dune
collection un par un et qui provoque une exception du type S to p ite ra tio n lorsquil ny a plus dlments.
Introduction au langage Python 29
Autre point important, on peut aussi utiliser comme itrateur dans une boucle fo r une liste
ou une chane de caractre
for i in [10, 'a', 1.414]:
p r i n t ( i , end= -> ')
f o r i i n ' mot':
p rin t(i, end=' -> ')
Exercice 6. crire deux fonctions somme et maximum qui renvoient respectivement la somme
et le maximum dune liste dentiers. Vrifiez votre rsultat en vous servant des primitives sum
et max.
Solution.
# Les t e s t s :
from random i m p o r t sampl e
l i s t e = s a m p l e ! r a n g e ( 1 0 0 ) , 30)
p r i n t ( l i s t e , som m e(liste), s u m ( lis te ), m axim um (liste), m a x ( lis te ))
Exercice?. Programmer la main des fonctions qui imitent les mthodes remove, pop,
index, count et reverse des listes.
Essayez les fonctions en effectuant les tests suivants :
TJ > l i s t e = [1, 2, 3, 2, 5, 3, 7, 8, 10, 11, 3]
O
c > i n d e x ( l i s t e , 3) # rp.: 2
> r e m o v e ( l i s t e , 3)
JD > lis te # r p . : [ 1, 2, 2, 4, 5, 3, 7, 8, 10, 11, 3 ]
tH
O
CM > p o p (lis te , 9), l i s t e # r p . : 11 [ 1, 2, 2, 4, 5, 3, 7, 8, 10, 3 ]
(y) > c o u n t ( l i s t e , 3) # rp.: 2
4-1
XI > re v e rse (liste )
OJ
> lis te # rp. : [3, 10, 8, 7, 3, 5, 4, 2, 2, 1]
>-
Q.
O
U
On prendra soin de vrifier
fonctions remove, pop, reverse. On prcise que si au cours de lexcution dune fonction,
une variable nest pas trouve dans la table des variables locales la fonction, linterprteur
consulte la table des variables globales.
Solution.
14. Plus gnralement, le mot-cl fo r peut tre utilis avec nimporte quel objet i t r a b le ; un objet itrable tant un
objet possdant soit une mthode__ i t e r __ ( ) soit une mthode___getitem __ ( ).
30 Programmation en Python pour les mathmatiques
Pour crer des listes, Python fournit une facilit syntaxique particulirement agrable, sa
voir les listes (dfinies) par comprhension (en anglais, list-com prehensions). Elles p e im e tie n t
de gnrer des listes dune manire trs concise, sans avoir utiliser de boucles
La syntaxe pour dfinir une liste par comprhension est proche de celle utilise en mathma
tiques pour dfinir un ensemble par comprhension :
{ f M I X }
[ f(x ) fo r X in lis te ]
15. Les listes dfinies par comprhension remplacent simultanment un mappage et un filtrage comme il y
en a dans tous les langages fonctionnels.
Introduction au langage Python 31
Pour concatner les lments dune liste de listes, on peut imbriquer deux boucles for dans
la dfinition dune liste par comprhension :
> x ll = [[1, 2, 3], [4, 5], [6, 7, 8]]
> [x f o r x l i n x l l f o r X i n x l ]
[1, 2 , 3 , 4 , 5 , 6, 7 , 8]
Pour obtenir les diviseurs dun entier n, on peut galement utiliser une liste par comprhen
sion :
> n = 100; [d f o r d i n r a n g e ( l , n+1) if n % d == 0] # les d i v i s e u r s de 100
[1, 2, 4, 5, 1 0 , 2 0 , 2 5 , 5 0 , 100]
11 R c a p itu la tif s u r le s p r in c ip a u x ty p e s
Passons en revue les types de variables que nous avons rencontrs au long de ce premier
chapitre, et mentionnons quelques nouveaux types.
- une plage dexposants limite, pouvant donner lieux des overflows (lorsque
le rsultat dune opration est plus grand que la plus grande valeur reprsen
table) et des underflows (lorsquun rsultat est plus petit, en valeur absolue,
que le plus petit flottant normalis positif), puis des rsultats nayant plus
aucun sens.
Nous reviendrons sur ces objets la section 1 du chapitre 4 ;
32 Programmation en Python pour les mathmatiques
tH
O
rsj
Exercice 8.
crire une fonction t rouve ( mot, l e t t re ) qui renvoie lindice de la premire occurrence de
XI
OJ l e t t re dans la chane de caractres mot et renvoie -1 si l e t t re napparat pas dans mot.
>-
CL
O Solution. La boucle sarrte ds que le premier retu rn est rencontr.
U
def trouve(mot, le ttre ):
in d ice = 0
w hile in d ic e < len(mot):
i f m o t [ i n d i c e ] == l e t t r e :
return in d ic e
i n d i c e += 1
return - 1
Introduction au langage Python 33
Remarquons que les objets de type squentiel ont en commun les oprations rsumes dans
le tableau suivant o s et t dsignent deux squences du mme type et i, j , k des entiers :
12 Q u e l q u e s m o t s s u r la r c u r s i v i t
Une fonction mathmatique dfinie par une relation de rcurrence (et une condition initiale,
bien entendu), peut de faon naturelle tre programme de manire rcursive.
Par exemple, pour un rel x fix, x" peut se dfinir, comme fonction de n, par rcurrence
partir des relations :
Xo = 1 et x = X x " ^ si 72 > 1
a Le programme en Python scrit :
O
c
D def p u i s s a n c e ( x , n ) :
kD i f n == 0: r e t u r n 1
O else: return x * puissance(x, n - 1)
rs]
puissance(2,5)
34 Programmation en Python pour les mathmatiques
....................... > a p p e l de p u i s s a n c e ( 2 , 4 )
.................. > a p p e l de p u i s s a n c e ( 2 , 3 )
............. > a p p e l de p u i s s a n c e ( 2 , 2 )
-------- > a p p e l de p u i s s a n c e ( 2 , 1 )
- - > a p p e l de p u i s s a n c e ( 2 , 0 )
- - > s o r t i e de p u i s s a n c e ( 2 , 0 )
-------- > s o r t i e de p u i s s a n c e ( 2 , 1 )
............. > s o r t i e de p u i s s a n c e ( 2 , 2 )
.................. > s o r t i e de p u i s s a n c e ( 2 , 3 )
....................... > s o r t i e de p u i s s a n c e ( 2 , 4 )
La machine applique la rgle : p u issa n ce{x, n) = x * p u issa n ce(x , n-1) tant que lex
posant est diffrent de 0, ce qui introduit des calculs intermdiaires jusqu aboutir au cas de
base : p u iss a n c e (x ,0) = 1. Les calculs en suspens sont alors achevs dans lordre inverse
jusqu obtenir le rsultat final.
Pour lever un nombre la puissance n, il existe un algorithme bien plus performant que
la mthode nave consistant multiplier ce nombre {n - 1) fois par lui-mme : il sagit de la
mthode dite d exponentiation rapide^^. tant donns un rel positif a et un entier n, on
remarque que :
\a ^ j si n est pair,
=< /7 -1
a a 2 si n est impair.
d e f e x p o ( a , n)
i f n == 0: r e t u r n 1
else:
i f n%2 == 0: r e t u r n e x p o ( a , n / / 2 ) * * 2
e ls e : return a*(expo(a, ( n - l ) / / 2 ) * * 2 )
Exercice 9. crire une version itrative, puis une version rcursive pour calculer la factorielle
a
dun entier :
O 1 si 77 = 0
c n\ -
=3
Q (/7- 1)! X 77 si 77 > 1
tH
O Solution.
fM
4-1 def f a c t l t e r ( n ) : def f a c t R e c ( n ) :
XI
gi P = 1 i f n == 0:
s_
>- fo r i in range(2, n+1): r e t u r n (1)
Q.
O P *= i else :
U
return P return(n * f a c t R e c ( n -l) )
16. En fait, cest lalgorithme dexponentiation rapide qui est la base de limplmentation de loprateur puissance
en Python. Avec cette mthode, on effectue log2 (n) lvations au carr et, au plus, log2 (n) multiplications, contre
n -1 multiplications dans le cas de la mthode nave ! Pour diverses variantes, cf. http : / / e n . w ik ip e d ia . o rg /w ik i/
Exponentia tio n _ b y _ squaring
Introduction au langage Python 35
y k e l O , n - l j , bjc = k + bjc+ixo
Voici une programmation rcursive de lalgorithme de H orner (le polynme p tant repr
sent par la liste de ses coefficients [<, , <]) :
h o m e r.
Si vous avez test les fonctions rcursives prcdentes avec des paramtres ncessitant un
trs grand nombre dappels de la fonction, vous aurez sans doute remarqu que, par dfaut.
Python limite le nombre dappels 1000. Si lon souhaite augmenter la taille limite de la pile
dappels rcursifs, il suffit dutiliser les instructions suivantes :
a
O import sys
c
13 s y s . s e t r e c u r s i o n l i m i t (100000)
Q
13 Q u e lq u e s m th o d e s p o u r trie r u n e lis te
ai
'i Dans cette section, on sintresse un problme trs courant en informatique, savoir celui
>
CL
O de trier une liste. On donne ici trois algorithmes de tri. Pour tester chacun de ces algorithmes,
U
on pourra utiliser des listes gnres alatoirement en important le module random (cf. sec
tion 2.2 du chapitre 2) :
from random i m p o r t rand r ange
n = 2 0 ; l i s t e = [ r a n d r a n g e ( 1 00) f o r i in range(n)]
d) crire une fonction maxi {l , n ) qui prend en argument une liste l et un nombre n et
qui retourne le maximum et son indice parmi les n premiers lments de l.
b) En utilisant la fonction maxi, crire une fonction t r i_ s e le c qui trie une liste selon la
mthode de tri par slection.
Solution.
tr i.p y tr i.p y
a) crire une fonction i n s e r t i o n ( l , n) qui prend en argument une liste l dont on sup
pose que les n premiers lments sont tris et qui insre llment l [ n ] sa place parmi
les n premiers lments de l.
Introduction au langage Python 37
Solution.
tr i.p y tr i.p y
def i n s e r t i o n ( l , n ) : def t r i _ i n s e r t ( 1 ) :
w h i l e l [ n ] < l [ n - l ] and n > 0: n = le n (l)
l [ n - l ] , l[n] = l[ n ] , l [ n - l ] fo r i in range(1, n):
n -= 1 I = in se rtio n (l, i;
return I return I
Tri rapide
Le tri rapide (ou q u ickso rt ) est une des mthodes de tri les plus rapides. Lide est de
prendre un lment au hasard (par exemple le premier) que lon appelle p iv o t et de le mettre
sa place dfinitive en plaant tous les lments qui sont plus petits sa gauche et tous ceux
qui sont plus grands sa droite. On recommence ensuite le tri sur les deux sous-listes obte
nues jusqu ce que la liste soit trie. Par exemple :
crire un algorithme rcu rsif t r i_ rap id e (l ) triant une liste en utilisant lalgorithme.
Solution.
tr i.p y
TJ def t r i _ r a p i d e ( l ) :
c
3 i f l == [ ] : r e t u r n []
CT
>
CL
O 14 Q u e lq u e s p rim itiv e s u s u e lle s
U
Dans cette section, on prsente les primitives (ou b u ilt-in fu n c tio n s en anglais) les plus
usuelles du langage. Nous avons dj rencontr les primitives id, type, len, eval, exec, input,
p rin t, format, range, etc. La liste complte et la description des primitives fournies par Py
thon se trouve la page : http: //d o e s . python. o r g /p y 3 k /lib r a r y /f u n c tio n s. html
La primitive la plus utile pour connatre les autres est la fonction help, qui permet daccder
dans linterprteur la documentation dune fonction :
38 Programmation en Python pour les mathmatiques
> help(divmod)
H e l p on b u i l t - i n f u n c t i o n divmod i n module b u i l t i n s :
divmod( . . . )
d i v m o d ( x , y) -> (d iv, mod)
Return the t u p l e ((x-x%y)/y, x % y ). Invarian t: d i v * y -i- mod == x.
a Exercice 10.
O
c
D En utilisant la primitive s tr , crire une fonction qui renvoie le nombre de chiffres dun nombre
y1
>I entier naturel dans son criture dcimale.
O Combien lentier crit en base 10, possde-t-il de chiffres?
r\i
Solution.
CT On peut utilise la primitive s t r pour convertir un entier en chane de caractres, puis en cal
s_ culer la longueur.
>.
CL
O
U def n b r e _ c h i f f r e s ( n ) :
return l e n ( s t r ( n ) )
302
introduction au langage Python 39
Exercice 11.
En utilisant la primitive in t, crire une fonction qui renvoie le la partie entire [x\ dun nombre
dcimal x. On rappelle que [-3.1 J = - 4 (et non pas -3).
Solution.
def E ( x ) :
return in t( x ) if x>=0 e l s e i n t ( x ) - l
3 0-4
14.3 Itrateurs
Nous avons dj rencontr un itrateur lorsque nous avons abord la fonction range. Les
gnrateurs sont des objets qui permettent de parcourir une squence sans avoir stocker
la squence complte en mmoire. Le principe est quivalent un curseur de donnes plac
sur la premire donne et qui dcouvre les lments au fur et mesure de lavance dans la
squence.
Noter que lon peut convertir facilement un itrateur en liste laide de la fonction l i s t :
> list(ra n g e (2 , 15, 3))
La fonction enumerate cre partir dune squence un itrateur qui renvoie chaque tape
le i-uplet form de llment de la squence prcd de son indice de position :
L = [ 1 , 5, 3, - a - ]
for i in ran g e (le n (L )): p r i n t { " L [ { 0 } ] = { 1 } " . f o r m a t ( i , L [ i ] ))
# V a r i a n t e p l u s p y t h o ni q u e :
for i , X in enum erated): p r in t ( " L [ { 0 } ] = { l} " .fo rm at(i, x))
Cette primitive nous permet, par exemple, dcrire simplement une fonction qui renvoie la
liste des positions o apparat un lment dans une liste :
a
O
c def occurences(x, lis te ):
13
Q return [ i for i , y in en um erate(liste) if x == y]
11
O La fonction reversed cre un itrateur invers :
def h o rn e r(p , x) :
somme = 0
fo r c in re v e rse d (p):
somme = c + x*somme
r e t u r n somme
40 Programmation en Python pour les mathmatiques
Lorsque souhaite crire une boucle f en parcourant les couples forms par les lments
de deux (ou plusieurs) squences, on utilise la fonction zip :
> l i s t ( z i p ( [ 1 , 2 , 3 , 4, 5 ] , [ ' a ' , 'b', 'c']))
[ ( 1 , ' a ' ) , (2, ' b ' ) , (3, ' c ' ) ]
Noter que dans le cas o les deux squences nont pas la mme taille, la fonction zip utilise
une version tronque de la plus longue liste.
Lorsquon reprsente des vecteurs par des listes (ici et v), il est alors trs simple de les addi
tionner composante par composante :
> [x[0] + x[0] f o r X i n z i p ( u , v) ] # a d d it io n v e c t o r i e l l e
> [x + y f o r X , y i n z i p ( u , v ) ] # addition v e c to rie lle
On peut mme transposer une matrice trs simplement en la dpaquetant grce lopra
teur * :
> matrice = [ [ 1 , 2, 3], [6, 5, 4]]
> p r i n t ( l i s t ( z i p ( * m a t r i c e ) )) # transposition m a tric ie lle
[(1, 6), (2, 5), ( 3, 4)]
Il existe encore dautre moyens de crer des itrateurs : soit en utilisant la primitive i t e r ou
des fonctions du module i t e r t o o l (que nous ne dtaillerons pas ici), soit en utilisant un g
nrateur d'expression (en anglais generate expression). Les gnrateurs dexpression sont
aux itrateurs ce que les listes par comprhensions sont aux listes.
> (i**2 fo r i in range(10)) # gnrateur d'expression
Par exemple, on peut programmer la mthode nave dvaluation dun polynme avec un
gnrateur dexpression :
def e v a lu a t io n _ n a v e ( p , x ) :
r e t u r n sum(c * x * * i f o r i , c in enumerate(p))
Les gnrateurs dexpression nous fournissent un moyen trs efficace de calculer le produit
scalaire de deux vecteurs reprsents par des listes :
> sum(x * y f o r X, y in zip (u, v)) # p r o d u i t s c a l a i r e de e t v
a
O
c
=3
Enfin signalons les primitives a i l et any qui prennent en argument un objet itrable : la pre
Q mire renvoie True si tous les lments de litrable sont vrais et la seconde renvoie True si
tH au moins un des lments est vrai. Voici une fonction qui teste si les lments dune liste sont
O
(N tris dans lordre croissant :
def e s t _ t r i e e ( l i s t e ) :
03 r e t u r n a l l ( x <= y f o r x , y in z ip ( lis t e , lis te [l:]))
>.
CL
O
U
15 U n m o t s u r le s e x c e p tio n s
Lorsquune erreur se produit dans le droulement dun programme (par exemple une divi
sion par 0), linterprteur stoppe alors lexcution du programme et affiche la nature de ler
reur. Les types derreurs sont classs suivant une certaine hirarchie consultable ici : http:
/ / d o e s . python. o r g /p y 3 k /lib r a r y /e x c e p tio n s . html
introduction au langage Python 41
Il est possible de produire une erreur personnalise dans un programme grce linstruction
r a ise suivie de lune des exceptions intgres Python.
Supposons par exemple que lon souhaite crire une fonction qui renvoie le produit sca
laire de deux vecteurs si les deux vecteurs ont mme taille, et lve une exception dans le cas
contraire :
d o tp ro d , p y
def dotprod(u, v ) :
i f l e n ( u ) != l e n ( v ) :
r a i s e I n d e x E r r o r ( " L e s v e c t e u r s n ' o n t pas l a mme t a i l l e ! " )
r e t u r n s um( x*y f o r x , y i n z i p ( u , v ) )
p r i n t ( d o t p r o d ( [ 3 , 9 ] , [ 5 , - 1 ] ) ) ; p r i n t ( d o t p r o d ( [ 3 , 9, 0 ] , [ 5 , - 1 ] ) )
T r a c e b a c k (most r e c e n t c a l l l a s t ) :
F i l e " < s t d i n > " , l i n e 7 , i n <module>
F i l e " < s t d i n > " , l i n e 3 , i n d o t pr o d
I n d e x E r r o r : Les v e c t e u r s n ' o n t pas l a mme t a i l l e !
cette pratique est dconseiller absolument. En effet, il se pourrait alors quon masque ainsi
tH
O une exception qui ne corresponde pas celle que lon attendait, ce qui pourrait entraner une
rs l
erreur inextricable.
Signalons que le bloc try supporte lutilisation dun bloc e ls e aprs le dernier bloc except
CT et dun bloc f in a l l y :
>
CL
O - le bloc e l s e est excut si aucune exception na t intercepte dans le bloc t ry ;
U
- le bloc f in a l l y est excut dans tous les cas.
16 C o m p l m e n ts s u r le s f o n c tio n s
Pour dfinir la liste des paramtres formels dune fonction. Python offre une syntaxe trs
riche qui permet dconomiser souvent linclusion dinstructions conditionnelles au sein du
42 Programmation en Python pour les mathmatiques
programme.
Tout dabord, on peut prciser des valeurs p a r d fa u t pour les paramtres formels :
def z e ta(p , N=100):
return su m (l/i**p fo r i in range(l, N))
p rin t(ze ta (2 )) # p, N = 2 , 100
p r in t ( z e t a ( 2 , 10**5)) # p, N = 2, 100000
p rin t(zeta(3)) # p, N = 3, 100
11 est galement possible dutiliser des p aram tres im plicites, ce qui permet lutilisateur de
fournir autant de paramtres quil souhaite. Linterprteur place alors les valeurs des para
mtres dans un dictionnaire :
def a ffic h e ( * * a r g u m e n ts ) :
fo r c l , v a le u r in arguments. it e m s ():
p r i n t ( "arguments[ {} ] = { } " .f o r m a t ( c l , valeur), end=' )
p r i n t ( ' \ n a r g u m e n t s = ' , a r g u me n ts )
a f f i c h e ( a r g l = ' m o t l ' , a r g 2 = ' 1 0 ' , x = 2)
Enfin, il est possible dutiliser des p aram tres arbitraires. Ces paramtres sont semblables aux
paramtres implicites ; la diffrence tient au fait quils ne sont pas nomms. Linterprteur les
place dans un i-uplet.
def p r o d u i t ( * f a c t e u r s ) :
P = 1
f o r i i n f a c t e u r s : p *= i
p r i n t C ' L e p r o d u i t des f a c t e u r s { } e s t { } . " . f o r m a t ( f a c t e u r s , p) )
p r o d u i t ( 2 , 3 , 4 , 5)
Le p r o d u i t des f a c t e u r s (2, 3, 4, 5) e s t 1 2 0 .
Lorsquon combine des paramtres avec des valeurs par dfaut, des paramtres implicites et
arbitraires, on doit respecter scrupuleusement lordre suivant :
TJ
O def fo n c tio n (x , y, z, *args, **keywords, a = l, b=2, c=3)
c
rj Signalons quil est possible de dfinir des fonctions anonymes laide de la directive lambda.
tH
Voici par exemple une fonction com position qui prend en argument deux fonctions / et g et
O qui renvoie \di fo n c tio n compose / g :
]
c o m p o s itio n , p y
def c o m p o s it io n ( f , g):
...... Renvoie l a compose de deux f o n c t i o n s f e t g.
r e t u r n lambda x: f(g(x))
if name__ == .main__
import doctest
d o c te s t . testmod()
Pour lancer les tests, on excute le script avec loption - v (mode bavard ) :
$ pythonB m a f o n c t i o n . py - v
17 N o tio n s s u r le s c la s s e s
En Python, tous les objets manipuls sont des objets au sens de la p ro g ra m m a tio n oriente
objet, cest--dire des entits regroupant :
Par exemple, les entiers, les flottants, les listes, les i-uplets, les chanes de caractres sont des
a objets. Parmi les attributs dun objet de la classe liste, on peut citer ses lments; parmi ses
O
c mthodes, on peut citer les fonctions append ( ), extend ( ), etc.
Seules les mthodes sont habilites manipuler les donnes dun objet, ce que lon traduit en
tH
O disant que les donnes de lobjet sont encapsules dans lobjet.
Pour connatre la liste des attributs et mthodes dun objet, on invoque la primitive d i r avec
XI
comme argument le nom de lobjet.
CTI Une classe est une description donnant naissance diffrents objets disposant tous de la
>-
Q. mme structure de donnes et des mmes mthodes. En un sens, on pourrait dire que les
O
U mots classe et type sont synonymes.
ct des nombreuses classes dfinies par dfaut par Python (par exemple in t, f lo a t , l i s t ,
tu p le, St r,...), il est possible de dfinir de nouvelles classes. Dans cette section, nous prsen
tons quelques bauches de classes pour programmer quelques objets mathmatiques. Nous
verrons dans les chapitres suivants des exemples plus dvelopps de dfinition de classes.
Enfin le chapitre 6 donnera un exemple de projet abouti utilisant de manire intensive les
principes de la programmation oriente objet.
44 Programmation en Python pour les mathmatiques
Nous allons partir dun exemple concret, savoir la notion de polynme. La manire la plus
naturelle de reprsenter un polynme p = ao + a\X-\ + est dutiliser une liste conte
nant ses coefficients [ao, Si lon dispose alors de deux listes p l et p2 reprsentant
deux polynmes, on souhaiterait pouvoir les additionner en utilisant loprateur +. Mais en
ltat, la liste renvoye serait le rsultat de la concatnation des deux listes. De plus, on sou
haiterait pouvoir afficher le polynme de manire conventionnelle. Cest ici que la dfinition
dune classe nous permettra de dfinir de nouvelles fonctions (les mthodes) propres aux po
lynmes.
Pour crer une classe, on utilise le mot-cl c la s s :
c la s s Polynom e(object):
Ensuite, il faut dfinir le co n stru cteu r de la classe, cest--dire la mthode qui nous permettra
de crer (ou d'instancier) un objet de la classe polynme. Le constructeur a toujours pour
n o m __i n i t __( ) et prend en argument au moins un paramtre appel s e l f . Ce paramtre
s e l f fera toujours rfrence lobjet instanci ( savoir ici un polynme).
P o ly n m e s .p y
c l a s s Polynme(o b j e c t ):
d e f __i n i t __ ( s e l f , c o e f f i c i e n t s ) :
s e lf.c o e ffs = co e ffic ie n ts
Pour crer un objet de la classe polynme, il nous suffira alors dutiliser la syntaxe suivante :
> P = Polynome([3, -2, 1]) # r e pr s e n t e l e polynme 3-2.X+X'^2
On va munir prsent les objets Polynme dune mthode renvoyant le degr du polynme :
P o ly n m e s , p y
def d e g ( s e l f ):
n = l e n ( s e l f . coeffs)
f o r i , c i n e n u m e r a t e !r e v e r s e d !s e l f . c o e f f s ) ):
i f c ! = 0:
return n - l - i
return - 1
O On souhaiterait prsent dfinir laddition de deux polynmes. Une premire faon de faire
rs]
(S) consisterait dfinir une mthode a j o u te ! ). Pour ajouter deux polynmes, on crirait alors
p l . aj oute ( p2 ). Lidal serait de pouvoir crire plus simplement pl+p2. Pour cela, on va re
ai
dfinir (ou plus exactement surcharger) la m thode__add__dfinie par dfaut chaque dfi
>
CL
O nition de classe (mais dont la dfinition par dfaut ne rend pas cette mthode oprationnelle
U
en gnral).
P o ly n m e s , p y
d e f __add__ ( s e l f , o t h e r ) :
i f s e lf .d e g O < o th e r .deg():
s e l f , other = other, s e l f
tmp = o t h e r . c o e f f s + [ 0 ] * ( s e l f . de g( ) - o t h e r . d e g O )
r e t u r n Poly nme![x+y f o r x, y in z ip (s e lf.c o e ffs , tmp)])
Introduction au langage Python 45
Le rsultat semble dcevant et ce, mme si on utilise la syntaxe print (pl+p2). En fait, au
moment de la dfinition de la classe chaque objet possde par dfaut non seulement une
m thode__add__ ( ), mais aussi une m thode__ s t r__ ( ) qui est surcharger par la suite
pour personnaliser le type daffichage dun objet de la classe, ce que nous pourrions faire
ainsi :
P o ly n m e s , p y
d e f __s t r __ ( s e l f ) :
c h a i n e = ' + ' . j o i n ( s e l f . s t r _ m o n o m e ( i , c)
for i , c in enum erate(self.coeffs) if c ! =0)
c h a i n e = c h a i n e . r e p l a c e ] ' 1 . ' , ' ')
r e t u r n c h a i n e i f c h a i n e ! = ' ' e l s e 'O'
Pour amliorer laffichage dun polynme, on a dfini une fonction s t r_monome ( ) qui affiche
un monme (par exemple, sous la forme ( - 2 ). X^^3) en rajoutant des parenthses autour des
coefficients ngatifs. Bien que cette fonction nutilise pas le paramtre s e l f , il est impratif
que ce paramtre figure (et figure en premier) dans la liste des paramtres formels de la fonc
tion s t r_monome ( ). Cest ce qui permettra dappeler cette fonction dans une autre mthode
de la classe, savoir ici, la m thode__s t r__( ).
> p r i n t (Polynme] [ 3 , -2, 1])) # r p . ; 3 + ( - 2 ) . X + X'"2
19. La liste des mthodes fournies par dfaut au moment de la dfinition dune classe se trouve ici : http : //d o e s.
python.org/py3k/reference/datam odel. html
46 Programmation en Python pour les mathmatiques
P o ly n m e s , p y
d e f __mul__ ( s e l f , o t h e r ) :
tmp = P o l y n o m e ( [ 0 ] )
for i , c in enum erate(other.coeffs):
tmp += s e l f . m u l _ m o n o m e ( i , c)
r e t u r n tmp
Lencapsulation reprsente un intrt certain de la notion de classe, mais ce nest pas le seul.
Le principal avantage de la notion de classe, est que lon peut dfinir des classes drives
dune classe qui hriteront des mthodes de la classe parente. Ceci permet dviter de rpter
des portions de code semblables. Pour dfinir une classe drive dune classe parente, on
utilise la syntaxe :
cla ss D rive(Parente):
Considrons un exemple. Pour reprsenter une fraction rationnelle, on pourrait dfinir une
classe partir de rien et programmer des mthodes similaires celles dfinies pour les po
lynmes. Mais il est bien plus avantageux de se servir des mthodes programmes dans la
classe des polynmes pour les utiliser au sein de la classe des fractions rationnelles. Nous
allons donc dfinir la classe des fractions rationnelles en la faisant driver de la classe des
polynmes.
P o ly n m e s , p y
c la s s FracRationnelle(Polynom e):
d e f __i n i t __ ( s e l f , n u m r a t e u r , dnom in ateur):
s e lf .n u m e r = numrateur
se lf.de no m = dnominateur
def d e g ( s e l f ):
return se lf.n u m e r.d e g () - self.denom .deg()
TJ d e f __c a l l __ ( s e l f , x) :
O
c r e t u r n s e l f . n u m e r ___c a l l __ (x) / s e l f . d e n o m ___ c a l l __ (x)
rj
tJH
D def str (se lf):
O return ("({}) / ( { } ) " .form at(self.num er, self.denom))
CM
d e f __add__ ( s e l f , o t h e r ) :
ai numer = s e l f . n u m e r * o t h e r . denom + s e l f . d e n o m * o t h e r . numer
> denom = s e l f . d e n o m * o t h e r . denom
CL
O
U r e t u r n F r a c R a t i o n n e l l e ( n u m e r , denom)
p l , p2, p3 = P o l y n m e ( [ 1 ] ) , P o l y n o m e ( [ - 1 , 1 ] ) , P o l y n o m e ( [ l , 1])
r i , r 2 = F r a c R a t i o n n e l l e ( p l , p 2 ) , F r a c R a t i o n n e l l e ( p l , p3)
p r i n t ( r i , r 2 , r i + r 2 , r i * r 2 , s e p = ' ; ')
p rin t(rl(-1.3 ))
d e f __s t r ___ ( s e l f ) :
return ( "({ } ) / ( { } ) " .form at(self.num er, self.denom))
d e f __add___ ( s e l f , o t h e r ) :
denom = s e l f . d e n o m * o t h e r . denom
numer = s e l f . n u m e r * o t h e r . denom + o t h e r . numer * s e l f . d e n o m
r e t u r n R a t i o n n e l ( n u m e r , denom)
d e f __mul___( s e l f , o t h e r ) :
numer = s e l f . n u m e r * o t h e r . numer
denom = s e l f . d e n o m * o t h e r . denom
r e t u r n R a t i o n n e l ( n u m e r , denom)
c l a s s F r a c R a t i o n n e l l e ( R a t i o n n e l , Polynme):
def in it ( s e l f , numrateur, dnom in ateur):
s e lf .n u m e r = numrateur
se lf.de no m = dnominateur
TJ
O d e f d e g ( s e l f ):
c
rj return se lf.n u m e r.d e g () - self.denom .deg()
tJH
D
O d e f __c a l l ___ ( s e l f , x ) :
(N
r e t u r n s e l f . n u m e r ___c a l l __ (x) / s e l f . d e n o m c a l l (x)
x:
DJ d e f __add___( s e l f , o t h e r ) :
>- tmp = ( R a t i o n n e l ( s e l f . numer, s e l f . d e n o m )
Q.
O + R a t i o n n e l ( o t h e r . numer, o t h e r . denom) )
U
r e t u r n F r a c R a t i o n n e l l e ( t m p . n u m e r , tmp.denom)
d e f __mul___( s e l f , o t h e r ) :
tmp = ( R a t i o n n e l ( s e l f . n u m e r , s e l f . d e n o m )
* R a t i o n n e l ( o t h e r . n u m e r , o t h e r . denom) )
r e t u r n F r a c R a t i o n n e l l e ( t m p . n u m e r , tmp.denom)
48 Programmation en Python pour les mathmatiques
On rem arque dans ce cas q u il est inutile de redfinir u n e m th o d e __s t r__ {) p o u r la classe
F racRationnelle, et que lcriture des m th o d e s __add__ {) e t __ mul__ {) se trouve sim pli
fie.
Ces program m ations de classes de polynm es, de nom bres rationnels et de fractions ra tio n
nelles ne sont que des esquisses et sont loin d tre acheves. Le b u t dans cette section tait
sim plem ent d illustrer les notions de classe, de m thode, de surcharge des oprateurs, d h ri
tage. Le chapitre 6 prsen tera des classes p lein em en t oprationnelles p o u r les polynm es, les
rationnels et les fractions rationnelles. Avant cela, d autres exem ples de leur utilisation seront
abords. Cest au fil des exem ples que leur m an ip u latio n deviendra de plus en plus naturelle.
En guise de conclusion, rassem blons quelques rem arques au vu des m thodes program m es
p rcdem m ent.
c la s s Polynome:
def __ i n i t __ ( s e l f , c o e ffic ie n ts )
- Le param tre s e l f est toujours le prem ier p aram tre form el d u n e m thode (de la classe)
au m o m en t de sa dfinition. En revanche, il n ap p arat plus dans la liste des param tres
d une m th o d e (de la classe) au m o m en t de son appel. En effet, il est alors prfix au
n o m de la m thode appele.
a
O
c
D
(S)
ai def monome ( s e lf
>
CL
O
U
def __ s t r ___ ( s e lf
18 E x e r c i c e s d e n t r a n e m e n t
Les corrigs sont disponibles sur le site dunod.com partir de la page d'accueil de louvrage.
Exercice 12.
D onner au m oins trois faons d crire u n e fonction p e rm e tta n t de tester si u n e chane de
caractres est un palindrom e.
Exercice 13.
La constante de C ham pernow ne est u n no m bre rel de partie entire nulle et d o n t le dvelop
p e m en t dcim al est ob ten u en crivant les uns la suite des autres tous les entiers naturels :
0 .1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 ...
Il a t dm ontr que ce nom bre est tran scen d an t, norm al et universel.
crire une procdure qui renvoie les n prem ires dcim ales de ce nom bre.
Exercice 14.
a) On note le nom bre de chiffres qui in terv ien n en t dans lcriture dcim ale de le n
tier n. Afficher les 8 prem ires valeurs de la som m e partielle de la srie L >i
b) Si n e N* ne co ntient pas de 9 dans son criture en base 10, on pose Un = sinon
on pose Un = 0. D onner une fonction qui approche les som m es partielles de la srie
X/i>l Un-
Solution.
d) On p e u t par exem ple utiliser la prim itive s t r p o u r convertir u n entier en chane de carac
tres, puis en calculer la longueur.
def s(n ) :
re tu rn s u m ( le n ( s t r ( k ) ) /( k * ( k + l) ) f o r k in r a n g e ( l, n))
fo r i i n r a n g e d , 8) :
p r i n t (s(10**i), end=', ')
a 0 .9 , 1 .0 8 , 1 .1 0 7 , 1 .1 1 0 6 , 1 .1 1 1 0 5 , 1 .1 1 1 1 0 4 , 1 .1 1 1 1 1 0 3 ,
O
c
D
On conjecture donc que la srie converge et que sa som m e vaut ce qui p e u t se d m o n trer
y
JD
A par une som m ation par paquets.
O b) M m e principe :
CM
(y)
def s ( n ) :
xz
CTI r e t u r n s u m ( l/k * * 2 f o r k i n r a n g e ( l, n) i f '9 ' not in str(k ))
>-
Q. On conjecture donc que la srie converge et que sa som m e est p roche de 1.6239249
O
U
a) crire u n e fonction qui p ren d en arg u m en t u n en tier n et qui renvoie la liste (sans d o u
blon) des tous les triplets pythagoriciens d o n t les com posantes sont strictem ent inf
rieures n.
b) C om bien y a-t-il de triplets pythagoriciens ju sq u 100 ?
Exercice 17.
C hercher dans la docu m en tatio n de Python lutilit de la fonction jo in . laide de cette
fonction, crer des chanes de caractres de longueur arbitraire. C om m ent afficher les galits
suivantes p o rta n t sur la som m e des carrs des prem iers entiers ?
= 1
1^2 + 2''2 = 5
1^2 + 2^2 + 3'"2 14
+ 2^2 + 3^2 4 2 30
l'^2 + 2-2 + 3^2 4-2 S'^2 55
1^2 + 2-2 + 3^2 4-2 5^2 6 2 91
1^2 + 2-2 + 3^"2 4-2 5^2 6^2 7^2 140
1^2 + 2-2 + 3'^2 4-2 5^2 6^2 7^2 8'^2 204
1^2 + 2-2 + 3'^2 4-2 5-2 6^2 7^2 S'^2 9'"2 285
1^2 + 2-2 + 3^"2 4-2 5^2 6^2 7-2 S'^2 9-2 10^^2 = 385
l'"2 + 2-2 + 3^2 4-2 5-2 6''2 l''2 8^2 9-2 10^2 + 11^2 = 506
TJ
Exercice 18. (Nom bres parfaits)
O Un nom bre est dit parfait lorsque il est gal la som m e de ses diviseurs propres. Un diviseur
c
rj
propre est u n diviseur autre que le nom bre lui-m m e. Le prem ier n o m bre parfait est 6. En
'i
H effet 1, 2 et 3 sont les diviseurs propres d e 6 e t6 = l- i- 2 - i- 3 .
O
(N
a) crire u n e fonction boolenne p a r f a i t ( n ) qui teste si u n en tier est parfait.
XI b) crire u n e fonction l i s t e _ p a r f a i t s ( n ) qui renvoie la liste des nom bres parfaits stric
OJ
tem en t infrieurs n. Quels sont les nom bres parfaits infrieurs 10 000 ?
>.
CL
O c) crire une fonction somme ( n ) qui, si n est u n n o m bre parfait, affiche lgalit justifiant
U
cette proprit. Par exemple, somme(6) devra afficher 6 = 1 + 2 + 3.
Sommaire
1 Structure d'un module......................................................................... 51
2 Quelques modules Batteries included ........................................... 53
2 .1 Le m odule m a t h .................................................................................................... 53
2 .2 Le m odule random ............................................................................................ 53
2 .3 Le m odule t u r t l e ............................................................................................ 56
2 .4 Le m odule t i m e .................................................................................................... 60
2 .5 Le m odule d e c i m a l ............................................................................................ 60
2.6 Le m odule f r a c t i o n s ......................................................................................... 63
2 .7 Le m odule s y s ....................................................................................................... 63
3 Lire et crire dans un fichier................................................................ 64
4 Manipulation de fichiers C S V .............................................................. 68
5 Comment gnrer des graphiques ? .................................................. 70
6 Un coup dil vers le module Matpiotlib........................................... 74
7 Exercices dentranement...................................................................... 75
1 S tru c tu re d 'u n m o d u le
TJ
O
c
rj En program m ation, il est frquent de sauvegarder dans u n fichier du code p o u r pouvoir le
Q rutiliser dans des contextes varis. Un tel fichier est appel u n m odule. On d o n n e gnrale
d e f I p r i n t ( l i s t e , la r g e u r , fo rm e ):
n = le n ( lis t e )
1. Noter q uune fonction sem blable est fournie avec le m odule p p r in t de la lib rairie standard : h t t p :/ / d o c s .
p y th o n . o r g / p y 3 k / lib r a r y / p p r in t . html
52 Programmation en Python pour les mathmatiques
li g n e s = i n t ( n / la r g e u r )
p r i n t ( [ , e n d = ' ')
fo r i in ra n g e (n ):
s = ' { : ' + form e + ' } '
i f i != n - 1 :
p r in t ( s .f o r m a t (l i s t e [ i ] ) , e n d = ', ' )
e ls e :
p r in t ( s . f o r m a t ( l is t e [ i] ) , end=' ] ')
if i != 0 and i % la r g e u r == la r g e u r - 1 :
p r in t ( '\n ', e n d = ' ')
p r i n t ()
Un problm e se prsente lorsquon a crit u n m odule que lon souhaite utiliser dans des r
pertoires autres sans avoir le copier en plusieurs endroits. En effet, si lon im porte u n m odule
Modules 53
personnel qui nest pas dans le rpertoire o se trouve le fichier excuter, u n m essage d er
reur est renvoy disant que ce m odule est inconnu. D ans ce cas, le plus sim ple est de m odifier
la variable sys . path qui c o n tient la liste des chem ins o lin terp rteu r recherche les m odules,
en crivant au d b u t du fichier dans lequel on souhaite im p o rter le m odule :
im p o rt s y s
s y s . p a t h . a p p e n d ( ' /h o m e /u s e r /p r o g r a m m a t io n /p y t h o n /m e s _ m o d u le s /')
2 Q u e lq u e s m o d u le s B a tte r ie s in c lu d e d
Le langage Python offre par dfaut u n e bibliothque de plus de deux cents m odules ^ qui vite
d avoir rinventer la roue ds que lon souhaite crire u n program m e. Ces m odules couvrent
des dom aines trs divers : m ath m atiq u es (fonctions m ath m atiq u es usuelles, calculs sur les
rels), adm inistration systme, program m ation rseau, m an ip u latio n de fichiers, etc. Nous
en p rsenterons ici seulem ent quelques-uns, savoir ceux d o n t n ous nous servirons dans la
suite de notre ouvrage.
(S)
2.2 Le module random
ai Le m odule random propose diverses fonctions p e rm e tta n t de gnrer des nom bres (pseu
> do-) alatoires qui suivent diffrentes d istributions m athm atiques.
CL
O Il apparat assez difficile d crire u n algorithm e qui soit rellem ent no n -d term in iste (cest-
U
-dire qui produise u n rsultat to talem en t im prvisible). Il existe cep en d an t des techniques
m athm atiques p e rm e tta n t de sim uler plus ou m oins bien leffet du hasard.
Voici quelques fonctions fournies par ce m odule :
2. La liste complte des m odules de la bibliothque standard est accessible ladresse : http : //d o e s . python.
o rg /p y 3 k /lib r a r y /in d e x .h t m l. c e la sajoute les 16627 m odules dvelopps ( ce jour) p a rla com m unaut P y
thon : h t t p ://p y p i.p y t h o n .o r g /p y p i
54 Programmation en Python pour les mathmatiques
o i *Xi dsigne u n e variable alatoire suivant la loi uniform e sur lintervalle [a, b].
crire u n e fonction renvoyant une approxim ation du nom bre
Tl = 4 - t^ d t
e n u t ilis a n t la m t h o d e d e M o n t e - C a r l o .
Solution.
m o n t e c a r lo .p y
im p o r t random, math
d e f m o n t e c a r lo ( f , a , b , n ) :
somme = 0
f o r i in ra n g e (n ):
X = ran d o m .u n if o r m ( a , b)
somme += f ( x )
TJ
O r e t u r n somme * ( b -a ) / n
c
rj
tJHD def f ( x ) :
O re tu rn m a t h .s q r t ( l - x**2)
CM
(y)
p r in t ( '-'* 6 3 )
XI
OJ p r i n t ( ' { 0 : > 1 0 s } I { l : " 1 2 s } | { 2 :' " 1 4 s } | { 3 : ^ 1 5 s } | ' . f o r m a t ( ' n ' ,
>- ' a p p r o x im a t io n ', ' e r r e u r a b s o lu e ' , ' e r r e u r r e l a t i v e ' ) )
CL
O p r in t ( '-'* 6 3 )
U
f o r i in ra n g e (0 , 10 , 2):
n = I0 * * i
a p p ro x = 4 * m o n t e c a r lo ( f , 0 , 1, n)
e r r e u r = m a t h .p i - ap p ro x
p r in t ( '{ 0 :1 0 d } I { 1 : 1 2 .1 0 f } | { 2 : 1 4 .1 0 f } | { 3 : 1 5 . 1 0 f } |'
.f o r m a t ( n , a p p ro x , e r r e u r , a b s ( e r r e u r / m a t h .p i) ) )
p r in t ( '-'* 6 3 )
Modules 55
n I a p p r o x im a t io n | e r r e u r a b s o lu e | e rre u r r e la t iv e |
1 3 .2 0 7 3 2 3 5 5 6 1 -0 .0 6 5 7 3 0 9 0 2 5 0 .0 2 0 9 2 2 7 9 6 1
100 3 .1 5 5 3 2 0 8 5 3 2 -0 .0 2 3 7 2 8 1 9 9 6 0 .0 0 7 5 5 2 9 2 0 5
10000 3 .1 4 6 3 0 1 2 5 6 8 -0 .0 0 4 7 0 8 5 0 3 2 0 .0 0 14 9 8 7 9 4 9
1000000 3 .1 4 1 4 6 9 1 5 5 9 0 .0 0 0 12 3 4 9 7 7 0 .0 0 0 0 3 9 3 10 5
100000000 3 .1 4 1 8 4 8 9 3 3 7 -0 .0 0 0 2 5 6 2 8 0 1 0 .0 0 0 0 8 15 7 6 5
Cette m thode de calcul approch d intgrale se rvle assez p eu efficace (et pas seulem ent
sur cet exemple) en dim ension 1 ; il faut u n grand no m b re de points po u r o b ten ir quelques
dcim ales significatives. Il est possible de prouver q u avec la m th o d e d approxim ation de
M onte Carlo, lerreur est dom ine p ar alors que dans la m th o d e des trapzes lerreur est
dom ine p ar On com parera les rsultats o b ten u s avec ceux o b ten u s la section 3.
Pour un e version vectorise de lalgorithm e de M onte Carlo, on p o u rra consulter [Lan09].
1= JJ^f(x,y)dxdy
Pour estim er I, on com m ence p ar choisir u n rectangle R qui co n tien t D. On a alors
TJ
Soit D = I (x, y) e -h I 2 - f I et F, F' les foyers de lellipse frontire.
O
c
rj crire u n e procdure p e rm e tta n t de calculer n u m riq u em en t lintgrale
JD
tH
I(fl, ) = ^ (M F-i-M F')dxdy o M (x ,y )e D
O
fN
Solution. Un calcul exact d o nne com m e valeur l{a,b) = ^ [2,a^ - b^), ce qui va nous p e r
m ettre de tester la qualit de lapproxim ation. Pour les calculs, on utilise la fonction hypot du
ai
> m odule math qui calcule la norm e euclidienne d u n couple ( x , y ).
CL
O m o n te c a r lo 2 .p y
U
im p o r t random
from math im p o rt s q r t , h y p o t, pi
def f( x , y, a, b ) :
c = s q r t ( a * * 2 -b * * 2 )
r e t u r n h y p o t ( x -c , y ) + hyp o t(x --c, y)
56 Programmation en Python pour les mathmatiques
d e f m o n t e c a r lo 2 ( a , b, n ) :
xrandom = [ r a n d o m .u n ifo rm ( - a , a) f o r i in ra n g e (n )]
yrandom = [ ran d o m .u n if o r m ( -b , b) f o r i in ra n g e (n )]
somme = s u m ( f ( x , y , a, b) f o r x i n xrandom
fo r y in yrandom i f h y p o t ( x /a , y /b ) < = 1 )
r e t u r n somme * (4 * a * b) / n**2
p r in t ( '-'* 6 3 )
p r i n t ( { 0 : > 7 s } I { l : ^ 1 5 s } | { 2 : ' " 1 5 s } | { 3 : ' " 1 5 s } | ' .f o r m a t ( ' n ' ,
' a p p r o x im a t io n ', ' e r r e u r a b s o lu e ' , ' e r r e u r r e l a t i v e ' ) )
p r in t ( '-'* 6 3 )
fo r i in ra n g e (1 , 5 ) :
a , b, n = 2 , 1 , 10 * * i
ap p ro x = m o n t e c a r lo 2 ( a , b, n)
e x a c t e = 2 * p i* b * ( 3 * a * * 2 -b * * 2 ) /3
e r r e u r = e x a c t e - ap p ro x
p r i n t ( ' { 0 : 7 d } I { 1 : 1 5 . 1 0 f } | {2:'^ 1 5 . 3 e } | { 3 : ^ 1 5 . 3 e } | '
.f o r m a t ( n , a p p ro x , e r r e u r , a b s ( e r r e u r / e x a c t e ) ) )
p r in t ( '-'* 6 3 )
n 1 a p p r o x im a t io n | e r r e u r a b s o lu e | e rre u r r e la t iv e |
10 1 2 1 .2 9 7 8 7 4 7 0 4 1 | 1 .7 4 0 e + 0 0 1 7 .5 5 5 e -0 2 |
100 1 2 2 .6 1 4 5 6 9 7 9 5 6 | 4 .2 3 8 e - 0 1 1 1 .8 3 9 e -0 2 1
1000 1 2 2 .9 4 6 7 1 9 0 1 1 1 1 9 .1 6 3 e -0 2 1 3 .9 7 7 e -0 3 1
10000 1 2 3 .2 0 4 2 7 4 2 5 0 8 | -1 .6 5 9 e -0 1 1 7 .2 0 2 e -0 3 1
"O
O
c
=3
Q 2.3 Le module t u r t le
'JD
Exercice 2 2 . ( F lo c o n d e V O N K o c H )
L a lg o r it h m e d e v o N K o c h c o n s is t e , p a r t ir d u n s e g m e n t
d o n n , le d iv is e r e n 3 s e g m e n t s d e m m e lo n g u e u r et
r e m p la c e r le s e g m e n t c e n t r a l p a r le s 2 c t s d u n t r i
a n g le q u ila t r a l c o n s t r u it e x t r ie u r e m e n t p a r t ir d e ce
s e g m e n t c e n t r a l.
L e f lo c o n d e v o N K o c h e st o b t e n u e n a p p liq u a n t c e t a l
g o r it h m e a u x c t s d u n t r ia n g le q u ila t r a l.
a) crire une fonction rcursive von.koch { l , n ) qui applique n fois l algorithme de von
K o ch un segment de longueur donne; cette fonction excutera donc la suite dins
tructions suivantes :
b) c r ir e u n e f o n c t io n f l o c o n ( l , n ) q u i d e s s in e u n f lo c o n d e v o n K o c h .
Solution.
v o n K o c h .p y
im p o rt t u r t l e
t u r t l e . p e n (sp e e d = 0) # v i t e s s e maximale
d e f v o n _ k o c h (lo n g u e u r, n ) :
i f n == 1 :
t u r t l e . f o r w a r d ( lo n g u e u r )
T3
O e ls e :
c
13 d = lo n g u e u r / 3 .
v o n _ k o c h (d , n - 1 ) t u r t l e . le f t ( 6 0 )
O v o n _ k o c h (d , n - 1 ) t u r t l e . r i g h t ( 12 0 )
rsl
v o n _ k o c h (d , n - 1 ) t u r t l e . le f t ( 6 0 )
(y)
v o n _ k o c h (d , n - 1 )
ai
>. d e f f lo c o n ( lo n g u e u r , n ) :
CL
O t u r t le .u p ()
U
t u r t l e . g o t o ( - lo n g u e u r / 2 , lo n g u e u r / 3) # on se p l a c e en haut, gauche
t u r t le .d o w n ( )
fo r i in r a n g e ( 3 ) :
v o n _ k o c h (lo n g u e u r, n ); t u r t l e . r ig h t ( 1 2 0 )
f lo c o n ( 3 0 0 , 5)
58 Programmation en Python pour les mathmatiques
L a m a c h in e d e G a l i o n e s t u n o u t il p e r m e t t a n t d e s im u le r u n e lo i b in o m ia le , et a in s i o b s e r v e r
s a c o n v e r g e n c e v e r s u n e lo i n o r m a le .
S o lu t io n .
g a lio n , p y
from random im p o rt *
T35
O from t u r t l e im p o rt *
c
D
kD d e f c h u t e ( n iv e a u x ) :
O c - ""
rs]
f o r n in r a n g e ( n iv e a u x ) :
(S)
if ra n d o m !) < 0 . 5 :
ai c = c + 'G '
> e ls e :
CL
O c = c + 'D '
U
re tu rn c
d ef t ir a g e !n iv e a u x ) :
c i b l e s = [n f o r n i n r a n g e ( n iv e a u x + 1 ) ]
c = c h u t e ( n iv e a u x )
f o r n in c:
if n == ' G ' :
Modules 59
c i b l e s . p o p ()
e ls e :
c i b l e s . pop(O)
r e t u r n c ib l e s [ 0 ]
d e f s i m u l a t i o n ( b i l l e s , n iv e a u x ) :
p r i n t ( " s im u la t io n d e " , b i l l e s , 's u r un c r i b l e de", n iv e a u x , " n iv e a u x :" )
t a s = [0] * ( n iv e a u x + 1 )
fo r b in r a n g e ( b il l e s ) :
t a s [ t i r a g e ( n i v e a u x ) ] += 1
p r in t ( t a s )
p r i n t ()
d e f r e c t a n g le ( la r g e u r , h a u t e u r ) :
c o u le u r = ( ra n d o m O , ra n d o m O , ran d o m O )
c o lo r ( c o u le u r )
b e g in _ f ill( )
fo r n in r a n g e ( 2 ) :
f o r w a r d ( la r g e u r ) ; l e f t ( 9 0 )
fo rw a rd ( h a u te u r ) ; le f t ( 9 0 )
e n d _ f ill( )
d e f d ia g r a m m e ( b ille s , n iv e a u x ) :
### simulation ###
t a s = [0] * ( n iv e a u x + 1 )
f o r b in r a n g e ( b ille s ) :
t a s [ t i r a g e ( n i v e a u x ) ] += 1
p r in t (ta s)
# # # d essi n # # #
la r g e u r = 50
h a u teu r_ m ax = 0
b ille s _ m a x = 0
f o r n in t a s :
i f n > h a u te u r_ m a x :
a h a u teu r_ m ax = n
O
c
D b ille s _ m a x = n
# # # c ent rage e t mise l ' c h e l l e # # #
VD
O up( )
rs]
g o to ( - l a r g e u r * ( n iv e a u x + l ) / 2 , - f l o a t ( b i l l e s _ m a x ) / b i l l e s * h a u te u r_ m a x /2 )
d o w n()
CTI sp e e d (" f a s t e s t " )
>-
Q.
O fo r n in ta s:
U
r e c t a n g le d a r g e u r , f lo a t ( n ) /b ille s * h a u te u r_ m ax )
f o r w a r d ( la r g e u r )
up( )
from tim e im p o rt c lo c k
from math im p o r t s i n
def f l( n ) :
l i s t e = []
f o r i in ra n g e (n ):
l i s t e += [ s i n ( i ) ]
re tu rn lis t e
def f2 ( n ) :
l i s t e = []
fo r i in ra n g e (n ):
l i s t e . a p p e n d !s in ( i) )
re tu rn lis t e
def f3 (n ) :
re tu rn [ s in ( i) fo r i in ra n g e (n )]
d e f d u r e e ( f o n c t io n , n = lO 0 0 0 0 0 0 ):
d eb u t = c l o c k ! )
f o n c t io n ( n )
f in = c lo c k !)
r e t u r n f i n - d eb u t
"O
O
c p r in t !' { -< 2 5 } > { :f } s ' . fo rm a t! ' u t ilis a t io n de + = ' , d u r e e ( f l ) ) )
n
p r in t !' { -< 2 5 } > { :f } s ' . fo rm a t! ' u t ilis a t io n de a p p e n d ', d u r e e ( f 2 ) ) )
tJHD p r in t !' { -< 2 5 } > { :f } s ' . f o r m a t ! ' lis t - c o m p r e h e n s io n ' , d u re e (f3 )))
O
CM
(y) u t i l i s a t i o n de += ...............> 6 .4 8 0 0 0 0 s
xz u t i l i s a t i o n de append > 4 .6 0 0 0 0 0 s
CTI
>- l i s t - c o m p r e h e n s i o n ............ > 3 .5 5 0 0 0 0 s
Q.
O
U On en conclut que lutilisation des list-com prehension est privilgier. R em arquer gale
m e n t que lutilisation de la m thode append est plus efficace que lin stru ctio n l i s t e -i-= [x]
On rem arque que le con ten u de y sem ble lgrem ent diffrent du x de dpart. Que sest-il
pass ? Tout sim plem ent les calculs effectus ne so n t pas exacts et so n t entachs d erreurs
d arrondis.
Autres exem ples encore plus surp ren an ts :
> 1.1 + 2.2
3.3000000000000003
> 0.1 + 0.1 + 0.1 - 0.3
5.5511151231257836-17
On rappelle que to u t nom bre rel possde u n dveloppem ent dcim al soit fini soit illim it ;
et cette rem arque fournit en fait u n m oyen efficace de dfinir lensem ble des nom bres rels
com m e lensem ble des nom bres p o ssd an t u n dveloppem ent dcim al fini ou illim it (on
pourra se reporter au chapitre 38 de [CBPIO] p o u r u n e approche, lm entaire et accessible
u n collgien, de cette dfinition).
Parm i les nom bres rels, on p eu t alors distinguer les rationnels (dont le dveloppem ent dci
m al est soit fini, soit illim it et priodique p artir d u n certain rang) des irrationnels (dont le
dveloppem ent dcim al est illim it et n o n priodique).
Il est ais de concevoir q u il n est pas possible p o u r u n o rd in ateu r de reprsenter de m anire
exacte u n dveloppem ent dcim al illimit. Mais m m e la rep rsen tatio n des dveloppem ents
dcim aux finis n est pas toujours possible. En effet, u n ord in ateu r stocke les nom bres n o n pas
en base 10, m ais en base 2. Or u n no m b re rationnel p e u t to u t fait possder u n dveloppe
m en t dcim al fini et u n dveloppem ent binaire illim it! Cest le cas des dcim aux 1.1 et 2.2
m is en jeu dans lexem ple p rcd en t :
base 10 base 2
a 1.1 01.0001100110011001100110011...
O
c 2.2 10.0011001100110011001100110...
D
3.3 11.0100110011001100110011001...
O
] C ontrairem ent au cas des nom bres entiers qui so n t reprsents en Python de m anire exacte
(S) les nom bres rels sont reprsents de m anire ap p ro ch e p ar des nom bres dcim aux, co m
ai p o rta n t 15 chiffres significatifs.
> Si lon souhaite travailler avec des nom bres flottants en m odifiant le nom bre de chiffres si
CL
O gnificatifs, on p eu t utiliser le m odule decimal. Un objet du type Decimal est cr en utilisant
U
la fonction decimal. Decimal ( ). Cette fonction p e u t prendre en argum ent u n entier ou une
chane de caractres m ais pas u n objet du type flo a t puisque ceux-ci sont reprsents en
m m oire de m anire approche, con trairem en t aux objets du type Decimal.
R eprenons les deux derniers calculs en im p o rtan t ce m odule :
3. En P yth o n 3, les types in t et lo ng ont t fusionns et donc la taille d u n entier nest lim ite que par la m m oire
alloue par lordinateur linterprteur Pytho n.
62 Programmation en Python pour les mathmatiques
P a r d fa u t , le m o d u le decimal t r a v a ille a v e c u n e p r c is io n d e 2 8 d c im a le s ; m a is i l e st p o s
s ib le d e m o d if ie r c e tte p r c is io n :
> getcontextO
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999,
Emax=999999999, c a p ita ls= l, fla g s= [],
traps=[0verflow, DivisionByZero, InvalidO peration])
> getcontext( ) . prec = 318 # F ix e r une n o u v e lle p r c is io n
I llu s t r o n s d e n o u v e a u le s p r o b l m e s d a r r o n d is e n p a r t a n t d e l id e n t it r e m a r q u a b le s u iv a n t e ,
q u e l o n t ro u v e n o n c e (e n t e r m e d a ir e s d e re c t a n g le ) d a n s la p r o p o s it io n 5 d u liv r e I I d e s
l m e n t s d E u c L iD E :
X + y\^ ( X - y \2
xy =
2 TJ - ( ^V 2
D a n s le p r o g r a m m e s u iv a n t , o n c o m p a r e le s d e u x m e m b r e s d e c e tte g a lit p o u r d e s n o m b r e s
X et y d e v e n a n t d e p lu s e n p lu s g r a n d s .
e u c lid e .p y
from decimal im p o rt *
a, b = U, a + 1
c, d = w, c + 1
03 p r in t ! '-'*5 3 )
>.
CL
O a = 6553.99
U
b=a + 1
typ e f lo a t t y p e D e c im a l
0 1 0 .0 0 0 0
-0 .0 5 8 5 9 3 8 1 0 6 -1 0
1.66707e--06 1 0 .0 0 0 0 0 5 7 3
-4 .7 9 8 2 6 6 -1-2 1 1 6.7825406-1-9
1.046656-1-44 1 3.35 74 6 5 5 30 5 8 6 -1-33
1.4 0 4 376-1-8 0 1 2 . 17 7 3 5 5 9 3 0 2 2 8 6 5 6 5 4 2 6 -T 7 1
********>)c:)c**** g e t c o n t e x t ( ) . p re c = 12 8 * * * * * * * * * * * * * *
typ e f lo a t 1 t y p e D e c im a l
0 1 0 .0 0 0 0
-0 .0 5 8 5 9 3 8 1 0 6 -1 0
1.6 670 76-1-0 6 1 0 6 -1 4
-4 .7 9 8 2 6 6 -H 2 1 1 0 6 -2 2
1.046656-1-44 1 0 6 -3 4
1.4 0 4 376-1-8 0 1 1.8 4 2 0 18 9 5 4 6 9 9 6 -3 0
im p o rt s y s
p r in t ( s y s .a r g v )
64 Programmation en Python pour les mathmatiques
[ Terminal
$ p y th o n s a r g u m e n t s . py v o i c i un exem p le 1 2 3
[ ' a r g u m e n t s .p y ', ' v o i c i ' , ' u n ' , 'e x e m p le ', ' 1 ' , '2 ', '3 ']
P a r e x e m p le , o n p e u t c r ir e u n p e t it p r o g r a m m e q u i s u t ilis e e n lig n e d e c o m m a n d e et c a lc u le
la m o y e n n e a r it h m t iq u e d e s n o m b r e s p a s s s e n a r g u m e n t s d u p r o g r a m m e .
m oyenne, p y
I im p o rt s y s
p r i n t ( s u m ( e v a l( x ) f o r x in s y s . a r g v [ l : ]) / l e n ( s y s . a r g v [ l : ] ) )
[ Terminal]
$ chmod u+x m o yenn e.p y
$ ./m o y e n n e .p y 4 0 .2 - 3 8 -5
0 .8 4
En Python, l a c c s u n f ic h ie r e st a s s u r p a r l in t e r m d ia ir e d u n o b je t p a r t ic u lie r a p p e l
o b je t -f ic h ie r et c r l a id e d e la p r im it iv e open ( nom, mode ) c o m m e c e c i :
U n e f o is l o b je t -f ic h ie r c r , i l e st d o t d e m t h o d e s s p c if iq u e s , q u i p e r m e t t e n t n o t a m m e n t
d e lir e et c r ir e d a n s le f ic h ie r , s u iv a n t le m o d e d o u v e r t u r e q u i a t p r c is e d a n s le p a r a
m tr e m ode. C e p a r a m t r e d e t y p e c h a n e d e c a r a c t r e s p e u t p r e n d r e p lu s ie u r s v a le u r s :
- r : o u v e r t u r e p o u r le c t u r e s e u le ;
- w : o u v e r t u r e p o u r c r it u r e : s i le f ic h ie r n e x is te p a s , i l e st c r , s in o n s o n c o n t e n u est
c ra s ;
- a : o u v e r t u r e p o u r a jo u t : s i le f ic h ie r n e x is te p a s , i l e st c r , s in o n l c r it u r e s e ffe c tu e
la s u it e d u c o n t e n u d j e x is t a n t ;
TJ
O - + : o u v e r t u r e p o u r le c t u r e et c r it u r e .
c
rj
U n e f o is la le c t u r e o u l c r it u r e d a n s le f ic h ie r t e r m in e , o n r e fe rm e le f ic h ie r l a id e d e l in s
VD
t r u c t io n c l o s e .
O
rs] V o ic i u n e x e m p le d o u v e r t u r e d e f ic h ie r a v e c a ffic h a g e d u n m e s s a g e d e r r e u r s i le f ic h ie r
(S) n e x is te p a s .
ai nom = ' m o n _ f ic h ie r . t x t '
> o b je t = o p e n (nom, ' r ' )
CL
O
U if o b je t :
o b je t . c lo s e ( )
e ls e :
p r in t ( "E rre u r le f ic h ie r { } n 'e x is t e p a s " .f o r m a t ( n o m ) )
P o u r c r ir e d a n s u n f ic h ie r , o n p e u t u t ilis e r l in s t r u c t io n write q u i c r it u n e c h a n e d e c a r a c
t re s o u l in s t r u c t io n w r it e lin e s q u i c r it u n e lis t e d e c h a n e s d e c a r a c t r e s e n le s c o n c a t -
n a n t.
Modules 65
# C r a t i o n d ' u n nouveau f i c h i e r e t c r i t u r e
nom = ' m o n _ f ic h ie r . t x t '
f i c h i e r = open(nom , 'w ')
fo r i in ra n g e (1 , 4 ) :
f i c h i e r . w r i t e ( ' C e c i e s t la lig n e { } \ n f o r m a t ( i ) )
f ic h ie r .c lo s e ( )
# Lecture
f i c h i e r = open(nom , ' r ' )
l is t e = f ic h ie r .r e a d ( )
p r in t ( lis t e )
f ic h ie r .c lo s e ( )
# A j o u t en f i n de f i c h i e r
f i c h i e r = open(nom , ' a ' )
fo r i in ra n g e (4 , 6 ):
f ic h ie r . w r it e ( ' C e c i e st la lig n e { } \ n ' . f o r m a t ( i) )
f ic h ie r .c lo s e ( )
# V a r i a n t e p ou r l a l e c t u r e
f i c h i e r = open(nom , ' r ' )
lis t e = f ic h ie r .r e a d lin e s ( )
p r in t ( lis t e )
f ic h ie r .c lo s e ( )
# V a r i a n t e p ou r l a l e c t u r e
f i c h i e r = open(nom , ' r ' )
f o r lig n e in f ic h ie r :
-a p r in t d ig n e , e n d = '' )
O
c f ic h ie r .c lo s e ( )
L e x c u t io n d u s c r ip t p r c d e n t d o n n e c e c i :
O
rs]
C e c i e st la lig n e 1
@
C e c i e st la lig n e 2
DI C e c i e st la lig n e 3
>-
CL
O [ 'C e c i e s t la lig n e l \ n ' , 'C e c i e s t la lig n e 2 \ n ' , 'C e c i e s t la l ig n e 3 \ n ' , 'C e c i
U
e s t la lig n e 4 \ n ', 'C e c i e s t la lig n e 5 \n ']
C e c i e s t la lig n e 1
C e c i e s t la lig n e 2
C e c i e s t la lig n e 3
C e c i e s t la lig n e 4
C e c i e s t la lig n e 5
66 Programmation en Python pour les mathmatiques
L o r s q u o n m a n ip u le u n f ic h ie r , il e st r e c o m m a n d d u t ilis e r le m o t -c l w it h q u i a l a v a n ta g e
d e f e r m e r p r o p r e m e n t le f ic h ie r u n e f o is le b lo c d in s t r u c t io n s c o r r e s p o n d a n t e x c u t , et c e la
m m e s i u n e e x c e p t io n a t a t t e in t e d a n s ce d e r n ie r . D e p lu s , i l p e r m e t u n e s y n ta x e p lu s
c o n c is e :
E x e r c ic e 2 4 . c r ir e u n e f o n c t io n q u i r e n v o ie le n o m b r e d e lig n e s d u n fic h ie r .
S o lu t io n .
d e f n b r e _ lig n e s ( n o m ) :
w it h open(nom , ' r ' ) a s f :
n = l e n ( f . r e a d l i n e s ( ))
re tu rn n
S o lu t io n .
d e f e x t r a c t io n ( n o m ) :
l i s t e = []
w it h open(nom , ' r ' ) a s f :
f o r lig n e in f :
f o r mot i n l i g n e . s p l i t 0 :
lis t e .a p p e n d ( m o t )
r e t u r n ( lis t e )
S ig n a lo n s q u e Python d is p o s e d e tr s n o m b r e u x m o d u le s p e r m e t t a n t d a p p e le r le s y s t m e
d e x p lo it a t io n p o u r m a n ip u le r le s f ic h ie r s et r p e r t o ir e s , n o t a m m e n t le m o d u le o s , d o n t la
TJ
O p r s e n t a t io n d p a s s e le c a d r e d e c e t o u v r a g e ^ .
c
rj
> from o s . p a th im p o r t *
JD
tH > p r in t ( e x is t s ( 'm o n _ f ic h ie r .t x t ') )
O T rue
CM
4. Pour une introduction concise et rapide aux com m andes usuelles du bash, on pourra consulter [Gra6].
Modules 67
E x e r c ic e 2 6 . L e x t e n s io n t i k z d u la n g a g e d e c o m p o s it io n E T ^ n e p e r m e t t a n t p a s p o u r l in s
t a n t u n t ra c a is d e s c o u r b e s e n p o la ir e s , c r ir e u n s c r ip t q u i e ffe c tu e le s o p r a t io n s s u iv a n t s :
/2 0 -0
- c a lc u l d e s p o in t s d e la c o u r b e d q u a t io n p o la ir e p = 1 -h - c o s
19
- c r it u r e d e c e s p o in t s d a n s u n f ic h ie r (e sc la v e ) d e x t e n s io n . t a b l e ;
- c r it u r e d u n f ic h ie r ( m a tre ) E T ] ^ c o n t e n a n t le p r a m b u le et l e n v ir o n n e m e n t t i k z et
a p p e la n t le f ic h ie r e s c la v e ;
- c o m p ila t io n d u d o c u m e n t m a t r e l a id e d u p r o g r a m m e r u b b e r
S o lu t io n .
c o u r b e t ik z . p y
from math im p o rt *
N, a , b = 50 0 , 0 , 1 + f lo o r ( 3 8 * p i)
def rh o (th e ta ):
re tu rn 1 + c o s ( th e t a * 2 0 /1 9 ) / 3
d e f e c h e l l e ( t , x m in = a , xm ax=b, n u m p o in ts = N ):
r e t u r n xm in + t /n u m p o in t s * (xmax - xm in)
s = ( " \ \ d o c u m e n t c l a s s { a r t ic l e } \ n \ n "
" \ \ u s e p a c k a g e [ m a t h le t t e r s ] { u c s } \ n "
" \ \ u s e p a c k a g e [ u t f 8 x ] { in p u t e n c } \ n "
" \ \ u s e p a c k a g e [ T l] { f o n t e n c } \ n "
" \ \ u s e p a c k a g e { x c o lo r } \ n "
" \ \ u s e p a c k a g e { t ik z } \ n \ n "
" \\b e g in { d o c u m e n t } \n "
" W b e g i n f t ik z p ic t u r e } [ s c a le = 2 ] \ n "
" W c l i p ( - 1 . 7 , - 1 . 7 ) r e c t a n g le ( 1 . 7 , 1 . 7 ) ; \n "
" \ \ d r a w [ - > ] ( - 1 . 5 , 0 ) - - ( 1 . 5 , 0 ) n o d e [ r ig h t ] { $ x $ } ; \ n "
" \ \ d r a w [ - > ] ( 0 , - 1 . 5 ) - - ( 0 , 1 . 5 ) n o d e [ab o ve ] { $ y $ } ; \ n "
" \ \ d r a w [ c o lo r = b lu e ] p l o t [sm ooth] f i l e { c o u r b e . t a b l e } ; \ n "
T3 " \\ e n d { t ik z p ic t u r e } \n "
O
c " \\ e n d { d o c u m e n t } \n " )
3
im p o r t os
o s .s y s t e m !" r u b b e r -d { 0 } . t e x && e v in c e { 0 } . p d f & " . f o r m a t ! ' c o u r b e ' ))
4 M a n ip u la tio n d e fic h ie rs C S V
L e f o r m a t C o m m a -s e p a r a t e d v a lu e s ( C S V ) e st u n f o r m a t in f o r m a t iq u e o u v e r t r e p r s e n t a n t
d e s d o n n e s t a b u la ir e s s o u s f o r m e d e v a le u r s s p a r e s p a r d e s v ir g u le s ; c e st le f o r m a t le
p lu s c o u r a m m e n t u t ilis p o u r im p o r t e r o u e x p o rt e r d e s d o n n e s d u n e f e u ille d e c a lc u l d u n
t a b le u r .
U n f ic h ie r C S V e st u n f ic h ie r texte , d a n s le q u e l c h a q u e lig n e c o r r e s p o n d u n e r a n g e d u t a
b le a u ; le s c e llu le s d u n e m m e r a n g e s o n t s p a r e s p a r u n e v ir g u le .
p a r t ir d u n t a b le u r , i l s u f f it d e s a u v e g a r d e r u n e f e u ille d e c a lc u l e n p r c is a n t le f o r m a t C S V
p o u r f a b r iq u e r u n te l f ic h ie r .
P o u r v it e r le s d s a g r m e n t s li s l a b s e n c e d e s t a n d a r d is a t io n d u s p a r a t e u r d c im a l, il
e st fo r t e m e n t c o n s e ill d e p a r a m t r e r s o n t a b le u r p o u r c h o is ir le p o in t (et n o n la v ir g u le )
c o m m e s p a r a t e u r d c im a l. S i v o u s u t ilis e z OpenOffice.org Cale o u LibreO ffice Cale,
a lle z d a n s le m e n u O u t ils > O p t io n s > P a r a m tr e s lin g u is t iq u e s > Langue > P a r a m tr e
lin g u is t iq u e et c h o is is s e z u n e c o m b in a is o n la n g u e /p a y s u t ilis a n t le p o in t c o m m e s p a r a t e u r
d c im a l : a n g la is (to u s p a y s ) o u m ie u x f r a n a is (S u is s e ) .
L a f ig u r e s u iv a n t e m o n t r e u n e x e m p le d e f e u ille d e c a lc u l o u v e r te d a n s O p e n O f f i c e :
TJ
O
c
rj
JD
tH
O
CM
(y) L e f ic h ie r C S V c o r r e s p o n d a n t s e ra
XI
OJ "Nom s", " m a th s " , " p h y s iq u e " , " c h im ie "
>- " A c h ille " ,1 2 ,1 4 ,1 5
Q.
O " A ja x " ,1 7 ,ll,9
U
" A lc e s t e " ,1 5 ,1 5 ,1 6
" A lc ib ia d e " ,1 1 , 1 3 , 1 2
" A s p a s ie " ,1 9 ,1 5 ,1 8
" B e r e n ic e " , 1 4 , 1 7 , 1 7
P o u r o u v r ir u n f ic h ie r C S V a v e c Python, o n im p o r t e le m o d u le c s v et o n u t ilis e la s y n ta x e
s u iv a n t e :
Modules 69
H re C S V .p y
im p o r t CSV
w it h o p e n ( ' t e s t . C S V ' , n e w lin e = ' ') as f
l i r e = C S V .r e a d e r ( f )
f o r lig n e in l i r e :
p r in t ( lig n e )
im p o r t CSV
w it h o p e n ( ' t e s t . C S V ' , 'w ', n e w lin e = ' ') as f :
c r ir e = c s v .w r it e r ( f )
f o r l i g n e i n t a b le :
e c r i r e . w r it e r o w ( l ig n e )
TJ II fa u t b ie n p r e n d r e g a rd e a u fa it q u a v e c l o p t io n ' w ', la m t h o d e w r i t e r c ra s e le f ic h ie r s i l
o
c e x is te d j .
13
Q c r iv o n s p r s e n t u n s c r ip t q u i a jo u t e a u f ic h ie r t e s t . e s v le s m o y e n n e s d e c h a q u e l v e et
I le s m o y e n n e s d e la c la s s e p o u r c h a q u e m a t i r e .
o
r\i m o y e n n e s C S V .p y
im p o rt CSV
w it h o p e n ( ' t e s t . C S V ' , n e w lin e = ' ' ) a s f :
s_
>- l ig n e s = [ l ig n e f o r l i g n e i n c s v . r e a d e r ( f )]
CL
o
U
d e f moy( l i s t e ) :
l i s t e = [ e v a l( x ) f o r x i n l i s t e ]
re tu rn s t r ( r o u n d ( s u m ( lis t e ) /le n ( lis t e ) , 1 ) )
L e r s u lt a t e st a lo r s le s u iv a n t :
5 C o m m e n t g n re r d e s g ra p h iq u e s ?
TJ
O
c
D R e p r s e n t e r d e s f o n c t io n s o u d e s c o u r b e s p a r a m t r e s e st u n b e s o in c o n s t a n t e n m a t h m a
t iq u e s . P o u r c e fa ire , p lu s ie u r s m t h o d e s se p r s e n t e n t n o u s . P a r m i le s m o d u le s f o u r n is
O p a r d fa u t d a n s Python, o n p o u r r a it u t ilis e r t u r t le o u Tkinter. L e p r e m ie r a l in c o n v
]
n ie n t d tre a s s e z r u d im e n t a ir e et le s e c o n d p e u t d e m a n d e r b e a u c o u p d e ffo rts p o u r u n r
(S)
s u lt a t c o r re c t . P a r m i le s m o d u le s d e t ie r c e s p a r t ie s , c e lu i q u i e st c e r t a in e m e n t le p lu s a d a p t
ai e st matplotlib, d o n t n o u s p a r le r o n s b r i v e m e n t d a n s la p r o c h a in e s e c t io n . N a n m o in s s a
>- g r a n d e p u is s a n c e a u n r e v e rs : s a p r is e e n m a in n e st p a s c h o s e a is e .
Q.
O
U t itre p d a g o g iq u e , n o u s p r o p o s o n s d o n c ic i u n e a u tr e a p p r o c h e . Python est c o n n u p o u r
tre u n e b o n n e c o lle e n tre d if f re n t s la n g a g e s o u lo g ic ie ls or, a u jo u r d h u i, u n e b o n n e m a
t r is e d e l o u t il in f o r m a t iq u e n c e s s it e d e p o u v o ir fa ire in t e r a g ir d iff r e n t s la n g a g e s o u lo g ic ie ls
e n tre e u x . N o u s a llo n s d o n c m o n t r e r i c i c o m m e n t g n r e r d e s g r a p h iq u e s d a n s le la n g a g e d e
d e s c r ip t io n d e p a g e P o s t S c r i p t . U n in t r t v id e n t d e c e tte m t h o d e e st q u il n o u s p e r m e t
t r a n o n s e u le m e n t d e v is u a lis e r u n e c o u r b e , m a is b ie n p lu s , le t ra c e n s e r a o b t e n u a u f o r m a t
P o s t S c r ip t e n c a p s u l . L a c o n v e r s io n a u f o r m a t P D F p e u t se fa ir e e n s u it e , p a r e x e m p le , a v e c
Modules 71
le lo g ic ie l p a y a n t A c r o b a t D is t ille r , o u b ie n a v e c le lo g ic ie l g r a t u it g h o s t s c r ip t (v ia T u t ilit a ir e
e p s 2 p d f ) . S o u s T u n d e c e s d e u x fo rm a t s , il s e r a f a c ile d in t g r e r c e t ra c d a n s u n d o c u m e n t
BT e K p a r e x e m p le .
V o ic i u n m o d u le s im p le p o u r c r e r u n f ic h ie r E P S p a r t ir d u n e lis t e d e p o in t s tra c e r.
P o stS crip tO .p y
d e f n ra n g e (a , b, n u m p o in ts ):
" " "R e n v o i e une s u b d i v i s i o n de [ a, b ] N+1 p o i n t s . " " "
pas = (b - a) / n u m p o in ts
r e t u r n (a + i * pas f o r i i n ra n g e (n u m p o in ts + 1 ) )
d e f p r e a m b u le ( n o m F ic h ie r , b o it e , zoom, d e l t a ) :
...... c r i t l e prambule du f i c h i e r EPS. ......
c a d re = [x * zoom * d e lt a f o r x i n b o it e ]
s_ d e b u t = r % ! P S - A d o b e - 2 . 0 E P S F -2 .0 \n "
"% % B o u n d in g B o x : { O [ 0 ] : . l f } { 0 [ l ] : . l f } { 0 [ 2 ] : . l f } { 0 [ 3 ] :.If}\n "
" { 1 } { 1 } s c a le X n " ) . f o r m a t ( c a d r e , zoom)
w it h o p e n ( n o m F ic h ie r + " . e p s " , 'w ') a s f :
f .w r it e ( s _ d e b u t )
d e f f in ( n o m F ic h ie r ) :
""" C l t u r e l e f i c h i e r EPS. ......
s _ f in = "\n sh o w p a g e \n "
w it h o p e n ( n o m F ic h ie r + " . e p s " , 'a ') as f :
f .w r it e ( s _ f in )
d e f a jo u t e C o u r b e ( n o m F ic h ie r , l i s t e , b o it e , zoom, e p a i s s e u r i r a i t , rg b ):
" " " A j o u t e une courbe donne sous forme de l i s t e . ......
w it h o p e n ( n o m F ic h ie r + " . e p s " , 'a ') as f :
a
O f . w r i t e ( " \n n e w p a t h \n " )
c
D f o r i , p o in t i n e n u m e r a t e ( lis t e ) :
kD if i == 0:
11
O f . w r it e r { 0 [0 1: .4 f } { 0 [ l j : .4 f } " .f o r m a t ( p o in t ))
rs]
f .w r it e ( " m o v e t o X n " )
(S)
e l i f ( b o it e [ 0 ] <= p o in t [0] <= b o it e [ 2 ]
ai and b o i t e [ l ] <= p o i n t [ l ] <= b o i t e [ 3 j ) :
>- f . w r it e r { 0 [ 0 j: .4 f } { 0 [ l j : .4 f } " .f o r m a t ( p o in t ))
CL
O f .w r it e ( " lin e t o \n " )
U
f . w r i t e ( " { l } { 0 } d iv s e t lin e w id t h X n "
" { 2 [ 0 j } { 2 [ l j } { 2 [ 2 ] > s e t r g b c o lo r X n "
" s t r o k e X n " .f o r m a t ( z o o m , e p a i s s e u r i r a i t , r g b ))
d e f a f f i c h e ( n o m F ic h ie r ) :
......A f f i c h e l e graph iq ue v i a g h o s t v i e w . " " "
o s . s y s t e m (" g v { 0 } .e p s & " .f o r m a t ( n o m F ic h ie r ) )
72 Programmation en Python pour les mathmatiques
i f __name__ == "___ m a in __
from math im p o rt p i , c o s , s in , f lo o r
N, a , b = 10 0 0 , 0 , 1 + f lo o r ( 3 8 * p i)
n o m F ic h ie r = " p o la r "
zoom, p a i s s e u r ! r a i t , rgb = 1 0 0 , 0 . 4 , (0 , 0 , 1 )
b o it e = [ - 1 . 5 , - 1 . 5 , 1 . 5 , 1 . 5 ] # xmin , ymin, xmax, ymax
# F o n c t i o n d f i n i s s a n t l a courbe p o l a i r e
def f (th e t a ) :
re tu rn 1 + c o s (th e t a * 2 0 /1 9 ) / 3
# L i s t e de p o i n t s de l a courbe
lis t e = ( [ f (th e ta ) * c o s (th e ta ), f(th e t a ) * s in ( t h e t a ) ]
f o r t h e t a i n n r a n g e ( a , b, N ))
# C r a t i o n du f i c h i e r EPS
p r e a m b u le ( n o m F ic h ie r , b o it e , zoom, 1 . 1 )
a jo u t e C o u r b e ( n o m F ic h ie r , lis t e , b o it e , zoom, p a i s s e u r ! r a i t , rgb)
f in ( n o m F ic h ie r )
a f f ic h e ( n o m F ic h ie r )
L e x e m p le p r s e n t e n f in d e m o d u le r e p r e n d le p r o
b l m e d u t ra c d e la c o u r b e d q u a t io n p o la ir e :
1 ^20-0
P = 1 -F - COS
^ 3
JD
tH
O
rs]
P o stS crip tO .p y
x:
ai from math im p o rt *
>- im p o r t P o s t S c r ip t 0 a s ps
Q.
O
U
N, a , b = 10 0 0 , 0 , 1 + f lo o r ( 3 8 * p i)
n o m F ic h ie r , zoom, e p a i s s e u r ! r a i t , rgb = " p o la r " , 10 0 , 0 .4 , (0 , 0 , 1)
b o it e = [ - 1 . 5 , - 1 . 5 , 1 . 5 , 1 . 5 ] # xmin , ymin, xmax, ymax
# F o nc t i o n d f i n i s s a n t l a courbe p o l a i r e
d e f f ( t h e t a ) : r e t u r n 1 + c o s ( t h e t a * 2 0 /1 9 ) / 3
Modules 73
# L i s t e de p o i n t s de l a courbe
l i s t e = ( [ f ( t h e t a ) * c o s (th e ta ), f (th e ta ) * s in ( t h e t a ) ]
f o r t h e t a i n p s .n r a n g e ( a , b , N ))
# C r a t i o n du f i c h i e r EPS
p s . p r e a m b u le ( n o m F ic h ie r , b o it e , zoom, 1 . 1 )
p s .a jo u t e C o u r b e ( n o m F ic h ie r , l i s t e , b o it e , zoom, e p a i s s e u r T r a i t , rgb)
p s . f in ( n o m F ic h ie r )
p s . a f f ic h e ( n o m F ic h ie r )
D a n s l a r c h iv e d is p o n ib le s u r la T o ile , le le c t e u r t r o u v e r a u n m o d u le P o s t S c r i p t . p y a m lio r
q u i l s u f f ir a d im p o r t e r p o u r p o u v o ir o b t e n ir le s g r a p h iq u e s p r s e n t s d a n s c e t o u v ra g e .
plot q u i p r e n d e n a r
P o u r u n e u t ilis a t io n s im p lif i e , o n p e u t u t ilis e r d ir e c t e m e n t la f o n c t io n
g u m e n t le n o m d u f ic h ie r P o s t S c r ip t g n re r, u n e lis t e boite=[xMin, yMin, xMax, yMax],
le f a c t e u r d a g r a n d is s e m e n t zoom , la lis t e d e s c o u r b e s tra c e r, c h a q u e c o u r b e t a n t d o n n e
s o u s f o r m e d u n e lis t e c o n t e n a n t la lis t e d e s p o in t s , la c o u le u r et v e n t u e lle m e n t l p a is s e u r
d e tra it . D u te x te p e u t g a le m e n t tre p la c s u r le g r a p h iq u e . E n f in , d e s a r g u m e n t s o p t io n n e ls
p e r m e t t e n t d e m o d if ie r le p a r a m t r a g e p a r d fa u t, n o t a m m e n t d u t ra c d e s a x e s.
V o ic i u n e x e m p le d u t ilis a t io n :
P o stS c rip t, p y
from math im p o rt *
from P o s t S c r ip t im p o rt p lo t , n ra n g e
# Paramtres f i x e r
n u m p o in ts , a , b, b o it e = 10 0 , - 1 . 4 , 2 * p i , [ - 1 . 7 , - 1 . 7 , 6 . 4 , 1 . 7 ]
n o m F ic h ie r , zoom, ro u g e , b le u = " s in _ c o s " , 10 0 , ( 1 , 0 , 0 ) , (0 , 0, 1 )
# L i s t e de p o i n t s de l a courbe
lis t e _ s = [ [x , s in ( x ) ] f o r x in n ra n g e (a , b, n u m p o in ts )]
lis t e _ c = [[x , c o s(x )] f o r x in n ra n g e (a , b, n u m p o in ts )]
p lo t ( n o m F ic h ie r , b o it e , zoom,
[ [ l i s t e _ s , b le u ] , [ l i s t e _ c , r o u g e ] ] ,
a [ ' s i n ' , [6 , - 0 . 5 ] , b le u ] , [ ' c o s ' , [6 , 1 .1 ] , ro u g e ])
O
c
13
Q
y1
>1
O
r\i
@
ai
s_
>.
CL
O
U
74 Programmation en Python pour les mathmatiques
> im p o r t numpy a s np
> X = n p .a r r a y ( [ 0 , 1 , 4, 9 ] , f lo a t )
> X # rp.: a r r a y ( [ 0., 1., 4., 9 .])
> ty p e (x ) # r p . : < c l a s s ' n um py . n d a r r a y ' >
P o u r c r e r d e s t a b le a u x d u t y p e array, le m o d u le numpy p o s s d e p lu s ie u r s p r im it iv e s , d o n t
linspace. C e t te d e r n i r e p e r m e t d e s t o c k e r d a n s u n t a b le a u le s p o in t s d u n e s u b d iv is io n r
g u li r e d in t e r v a lle . V o ic i, p a r e x e m p le , u n e s u b d iv is io n d e l in t e r v a lle [ - 1 , 1 ] c o m p r e n a n t 5
p o in t s :
JD M a is il y a b ie n p lu s s im p le : e n effet, le s o b je t s d e t y p e array s u p p o r t e n t la v e c t o r is a t io n .
1H
O I l e x is te d a n s le m o d u le numpy d e s p r im it iv e s p e r m e t t a n t d a p p liq u e r e n u n c l in d il u n e
(N
f o n c t io n m a t h m a t iq u e u s u e lle t o u s le s l m e n t s d u n t a b le a u !
xz > X = n p .lin s p a c e ( - 1 , 1, 4) # l e s a bsci sses
DJ
> > y = n p . s in ( x ) / X # l es ordonnes
Q. > y
O
U
a rra yU 0 .8 4 1 4 7 0 9 8 , 0 .9 8 15 8 4 0 9 , 0 .9 8 15 8 4 0 9 , 0 .8 4 1 4 7 0 9 8 ] )
p r s e n t , to u t e st e n p la c e p o u r u t ilis e r m a tp io tlib . O n c o m m e n c e p a r s a is ir la c o m m a n d e
import m a t p io tlib . pyplot q u i im p o r t e u n e c o lle c t io n d e p r im it iv e s p e r m e t t a n t d u t ilis e r
m a tp io tlib a v e c u n e s y n t a x e p r o c h e d e c e lle d e m a t la b . O n c r e e n s u it e l o b je t g r a p h iq u e
c o r r e s p o n d a n t a u g r a p h e d e n o t re f o n c t io n et i l n e n o u s re s te p lu s q u l e x h ib e r :
sin u sc .p y
im p o rt m a t p l o t l i b . p y p lo t a s p i t
im p o rt numpy a s np
X = n p .lin s p a c e ( - 1 5 , 15 , 15 0 )
y = n p . s in ( x ) / X
p lt .p lo t ( x , y)
p i t . sh o w ()
7 E x e r c i c e s d e n t r a n e m e n t
Les corrigs so n t disponibles sur le site d u n od.com p a rtir d e la page d accueil de louvrage.
E x e r c ic e 2 7 . E n u t ilis a n t la p r im it iv e w a lk d u m o d u le o s et la m t h o d e e n d s w it h s a p p l i
q u a n t u n e c h a n e d e c a ra c t r e s , c r ir e u n p r o g r a m m e q u i p a r c o u r t l a r b o r e s c e n c e d u n r
p e r t o ir e et a f f ic h e le n o m d e t o u s le s s c r ip t s Python r e n c o n t r s , p r c d d u c h e m in a b s o lu .
S i a u c u n r p e r t o ir e n e st f o u r n i e n a r g u m e n t , le p r o g r a m m e e x p lo r e r a le r p e r t o ir e c o u r a n t .
E x e r c ic e 2 8 . (A rb re d e P y th a g o re )
L a c o n s t r u c t io n d e l a r b r e d e P y t h a g o r e d b u t e a v e c u n s im p le c a rr . O n tra c e a lo r s le s c t s
d u n t r ia n g le r e c t a n g le a y a n t p o u r h y p o t n u s e le c t s u p r ie u r d u c a rr . S u r le s b o r d s d e c e
t r ia n g le , o n c o n s t r u it d e u x c a rr s . S u r le s c t s s u p r ie u r s d e c e s c a rr s , o n c o n s t r u it d e u x
n o u v e a u x t r ia n g le s h o m o t h t iq u e s a u p r e m ie r . L a p r o c d u r e e st a p p liq u e r c u r s iv e m e n t
c h a q u e c a rr , ju s q u l in f in i. L e s d e s s in s c i-d e s s o u s illu s t r e n t le s d e u x p r e m i r e s it r a t io n s
d e la c o n s t r u c t io n .
TJ
O
c
rj
Q
kD
O
rM
(5)
s_
>.
CL
O
U
c r ir e u n p r o g r a m m e q u i d e s s in e l a r b r e d e P y t h a g o r e a u b o u t d u n n o m b r e d o n n d it r a
t io n s . O n p o u r r a u t ilis e r le m o d u le P o s t s c r ip t .p y p o u r c r e r le g r a p h iq u e . A u b o u t d e 1 4 it r a
t io n s , o n o b t ie n t :
76 Programmation en Python pour les mathmatiques
E x e r c ic e 2 9 . ( U t ilis a t io n d e m at p l o t l i b )
a) E n s a id a n t d e l a id e e n lig n e d e m a t p l o t l i b , t r a c e r la r o s a c e r e n c o n t r e l e x e r c ic e 2 6 .
b) O b t e n ir la s u r f a c e r e p r s e n t a t iv e d e la f o n c t io n : / : ( x i, X 2 ) e [R^ \ {(0 ,0 )} ^
TJ
O
c
rj
JD
tH
O
CM
(y)
XI
OJ
>-
Q.
O
U
Thm es mathmatiques
Sommaire
Matrices.................................................................................................. 78
1.1 Les matrices avec NumPy et S c iP y .......................................................... 78
1.2 Fabriquons nos o u tils ..................................................................................... 79
1.3 Inverse dune matrice par la mthodede G auss - J o r d a n ................ 87
1.4 Chiffrement de HiLL ..................................................................................... 93
1.5 Chanes de M a r k o v ..................................................................................... 98
1.6 Manipulation dim ag es.....................................................................................102
1.7 Exercices dentranement..................................................................................111
Les nombres : entre analyseet algbre.............................................. 112
2.1 Manipulation des entiers comme chanes de b i t s ..................................112
2.2 Les nombres rationnels.....................................................................................119
2.3 Les nombres r e ls ............................................................................................... 122
2.4 Rels et flottants : un trs rapide survolde la norme IEEE754 . . 132
2.5 Les nombres complexes.....................................................................................144
2.6 Exercices dentranement..................................................................................146
Le nombre n .......................................................................................... 149
3.1 Lapproximation de jt de Nicolas D e C u e s ............................................149
3.2 Approximation de tt et calcul approch dintgrale.............................. 151
a 3.3 Le nombre 7t et les arctangentes....................................................................156
O
c
13 3.4 Mthodes modernes............................................................................................161
1 M a tric e s
> im p o rt numpy a s np
> from s c ip y im p o rt l i n a l g
> A = n p .a r r a y ( [ ( 1 , 2 ) , ( 3 , 4 ) 1 )
> A
array([[l, 2],
[3, 4]])
> 3 * A # chaque terme e s t m u l t i p l i p a r 3
a r r a y ( [[ 3 , 6],
[ 9, 12]])
> A + 10 # chaque terme e s t a d d i t i o n n 10
array([[ll, 12],
[13, 14]])
> A.T # transpose
array([[l, 3],
[2, 4]])
A t t e n t io n , l o p r a t e u r e ffe c tu e le p r o d u it t e r m e t e r m e . P o u r m u lt ip lie r d e u x m a t r ic e s a u
s e n s u s u e l, i l fa u t u t ilis e r d o t :
O n p e u t c a lc u le r le d t e r m in a n t et l in v e r s e d u n e m a t r ic e f a c ile m e n t :
ai > A.dot(iA)
> array([[ l.OOOOOOOOe+OO, 0 . 0OO00OOOe+OO],
Q.
O [ 8 . 8 8 1 7 8 4 2 0 e -1 6 , 1 . 0OO0OO0Oe+OO]])
U
...c o m p t e -t e n u d e s e r r e u r s d a r r o n d is d o n t n o u s r e p a r le r o n s p lu s t a r d ( c f s e c t io n s 2 .4 p a g e 1 3 2
et 1 p a g e 18 0 ). O n p e u t c e p e n d a n t y r e m d ie r a v e c la f o n c t io n a l lc l o s e :
> h e lp ( n p .a llc lo s e )
H e lp on f u n c t io n a l l c l o s e in m odule numpy. c o r e . n u m e ric :
a l l c l o s e ( a , b, r t o l = l e - 0 5 , a t o l = l e - 0 8 )
R e t u r n s T ru e i f two a r r a y s a r e e le m e n t -w is e e q u a l w it h in a t o le r a n c e .
Thmes mathmatiques 79
A lo r s , s a c h a n t q u e n p . e y e { n ) r e n v o ie la m a t r ic e id e n t it d e t a ille n :
D e n o m b r e u x e x e m p le s et u n e p r s e n t a t io n q u a s i e x h a u s t iv e d e s p o s s ib ilit s d e c e s d e u x m o
d u le s p e u v e n t tre c o n s u lt s s u r h t t p s :/ / s c ip y - le c t u r e s .g it h u b . io / in t r o / n u m p y / n u m p y .h t m l
et h t t p s : / / s c ip y -le c t u r e s .g it h u b .io / in t r o / s c ip y .h t m l# lin e a r -a lg e b r a -o p e r a t io n s -s c ip y -lin a lg .
D a n s c e tte s e c t io n , n o u s c r e r o n s n o s m a t r ic e s e n d o n n a n t le u r d im e n s io n et la f o n c t io n d
f in is s a n t le u r s c o e f f ic ie n t s e n f o n c t io n d e le u r s in d ic e s . C o m m e P y t h o n e st u n la n g a g e o b je t,
a u t a n t c r e r u n e c la s s e q u i d b u t e r a a in s i et q u e n o u s c o m p l t e r o n s a u f u r et m e s u r e :
m atrice, p y
c l a s s M at:
...... une m a t r i c e sous l a forme M a t ( [ n b l i g n e s , nb c o l s ] , f o n c t i o n ( i , j ) ) ......
r , c = l e n ( m a t ) , l e n ( m a t [ 0] )
re tu rn M a t ( [ r , c ] , lam b da i , j : mat[i][j])
CT
s_
>. L a m a t r ic e p r c d e n t e a u r a it d o n c p u tre d f in ie p a r :
CL
O
U > M = U s t 2 m a t ( [ [ l, 2 ] , [3,4], [5,6]])
E x e rc ic e 3 0 . c riv e z une fo n ctio n q u i renvo ie une m a trice n u lle de ta ille n x m p u is une autre
q u i renvo ie la m a trice id e n tit de ta ille n.
S o lu tio n .
def z e r o s ( n ,m ) :
re tu rn Mat([n,m], lambda i , j : 0)
def un it e( n) :
re tu rn M a t ( [ n ,n ] , lambda i , j : 1 i f i == j e ls e 0 )
N ous rajo u to n s q uelques m thodes h ab itu e lle m e n t d fin ie s p o ur les objets stru ctu r s de ce
ty p e :
m a tr i c e , p y
d e f __ getitem __ ( s e l f , d e ) :
...... permet d 'o b t e n ir M ij avec M [ i , j ] ......
re tu rn s e l f . F ( * c l e )
def __ i t e r __ ( s e l f ) :
""" pour i t r e r su r la l i s t e des c o e f f ic ie n t s donns p a r colonnes """
[r,c ] = self.D
f o r j in r a n g e ( c ) :
f o r i in r a n g e ( r ) :
y ie ld s e l f . F ( i , j )
def __ S tr __ ( s e l f ) :
...... j o l i a ffic h a g e d'une m a tric e """
[ r , c ] , f = self.D , s e lf.F
Imax = l e n ( s t r ( m a x ( i t e r ( s e l f ) ) ) ) + 1
a
O s = ' \ n ' . j o i n ( (' ' . ] o i n ( ' { 0 : > . { 1 } G } ' . f o r m a t ( f ( i , j ) ,l=lmax) f o r j in
c r a n g e (c )) ) f o r i in ra ng e (r ))
re tu rn s
O
fM def __ repr___( s e l f ) :
(y) ...... re p r se n ta tio n dans le REPL......
sz re tu rn s t r ( s e l f )
CT
>.
Cl
O La m thode j o i n est em ployer systm ati- > M
(J
q uem ent p o ur la co n catn atio n des ch an e s 1 2
> [ i fo r i in M .c o l( 0 )]
[1, 3, 5]
S o lu tio n .
m a tr i c e , p y m a tr i c e , p y
d ef l i g n e ( s e l f , i ) : def c o l ( s e l f , j ):
f o r j in r a n g e ( s e l f . D [ l ] ) f o r i in r a n g e ( s e l f . D [ 0 ] )
y ie ld s e l f . F ( i , j ) y ie ld s e l f . F ( i , j )
1 .2 .2 T ra n sp o s e d une m a tric e
L a transp ose d une m a trice (M/y) est gale la m atrice (M,/) A tten tio n au x
> M.transpose )
13 5
2 4 6
S o lu tio n .
m a tr i c e , p y
def t r a n s p o s e ( s e l f ) :
...... tra n sp o se d'une m a trice ......
[r ,c ] = self.D
re tu rn M a t ( [ c , r ] , lambda i , j : s e l f . F ( j , i ) )
"O
O
c
rj
Q 1 .2 .3 So m m e de m a tric e s
(X)1
O
r\i O n vo u d ra it cr er une m thode q u i p rend com m e argum ents d eu x m atrices et renvo ie le u r
som m e. Il fau d ra v rifie r que les m atrice s ad d itio n n e r sont de bonnes ta ille s : on u tilise ra la
fo n ctio n a s s e r t q u i est su ivie d une co n d itio n v rifie r et du n m essage a ffich h e r en cas de
ai
s_
>- p rob lm e.
CL
O Po ur p o u vo ir u tilis e r le sym bole + p ar la su ite , on va n o m m er notre m th o d e __add__ :
U
m a tr i c e , p y
def __ add__ ( s e l f , o t h e r ) :
...... somme de deux m a tric e s : u t i l i s a t i o n du symbole +......
a s s e r t s e l f . D == o t h e r . D, " t a ille s in co m p atib les"
re tu rn M a t ( s e lf .D , lambda i , j : s e l f . F ( i , j ) + o t h e r . F ( i , j ))
> M + M
2 4
6 8
10 12
O n d fin it de m m e __ neg__ p o u r l oppos e t ___ sub__ p o ur la so u stractio n :
m a tr i c e , p y
def neg ( s e l f ) :
...... oppos d'une m a trice ; u t i l i s a t i o n du symbole
re tu rn Mat(self.D,lambda i , j : - s e l f . F ( i , j ) )
def sub ( s e l f , o t h e r ) :
...... d iff r e n c e de deux m a trice s : u t i l i s a t i o n dyu symbole - .....
re tu rn s e lf + (-other)
1 .2 .4 P ro d u it p ar un s c a la ire
def p r o d _ p a r _ s c a l ( s e l f , k ) :
....... ren vo ie le p ro d u it d'une m a trice p a r un s c a la ir e " " "
re tu rn M a t ( s e lf .D , lambda i , j : k * s e l f . F ( i , j ))
OO 1 .2 .5 P ro d u it de m a tric e s
c
n SoitA= e t B = ( f i / y ) i ^ / ^ , . A l o r s A x B = C a v e c C = (c/y)i^/^ et
Q
JD 1< i < m l^i^p P
tH
O
CM
m
V(/, )e N * xN *
7 Cij=
k= l
JZ
"s^ C est l alg o rithm e h a b itu e l des tro is b oucles im b riq u es.
>. N ous a llo n s l ab straire d un p e tit n ive au : chaque co e fficie n t c/y est en fa it gal au p ro d u it
CL
O
U sca la ire de la lig ne i de A et de la co lo nn e j de B.
C om m enons donc p ar co n stru ire une fo n ctio n q u i ca lcu le le p ro d u it scalaire de d eux it-
rab le s. Pour ce la, nous a llo n s u tilis e r une fo n ctio n extrm em ent im p o rtan te q u i v ie n t du
m onde de la p ro g ram m atio n fo n ctio n e lle : map.
map ( f one, it e r b le ( s ) ) renvo ie u n it ra te u r de type map m ais o chaque lm ent sera rem
p lac p ar son im age p ar la fo n ctio n (si c est une fo n ctio n dune v a ria b le ) ou p ar l im age co m
bine des it rab le s si cest une fo n ctio n de p lu sie u rs v a ria b le s. Par exem ple :
Thmes mathmatiques 83
arghhh : l objet cre est de type map et on a son adresse m ais on ne sa it pas ce q uil y a dedans.
> [ i fo r i in m]
[]
Si on veu t en garder une trace on peut u tilis e r p ar exem ple l i s t :
TJ Po ur notre p ro d u it sca la ire , nous u tiliso n s galem ent la classiq u e fo n ctio n sum :
O
c
rj m a tr i c e , p y
I
JD def p r o d _ s c a l ( i t l , i t 2 ) :
tH
O re tu rn sum(map(mul, i t l , it2))
CM
P ar exem ple :
ai > prod_scal([ 1 ,2 ,3 ] ,[ 4 ,5 ,6 ] )
> 32
CL
O
U
S o lu tio n .
84 Programmation en Python pour les mathmatiques
m a tr i c e , p y
def p ro d _ m a t(s e lf , o t h e r ) :
....... ren vo ie le p ro d u it de deux m a tric e s ......
[ r s , e s ] , [ ro,co] = s e l f . D , o t h e r . D
a s s e r t CS == ro, " t a ille s in co m p atib le s"
re tu rn M a t ( [ r s , c o ] , lambda i , j : p r o d _ s c a l ( s e l f . l i g n e ( i ) , o t h e r . c o l ( j ) ) )
def __ mul__ ( s e l f , o t h e r ) :
....... p ro d u it d'une m a trice p a r un s c a la ir e ou une m a trice : u t i l i s a t i o n
du symbole * ......
i f Mat == t y p e ( o t h e r ) :
re tu rn s e l f . prod_mat(other)
e ls e :
re tu rn s e l f .pr o d_ p a r_s c al (o th e r)
N otre p ro d u it nest pas si m al : il s c rit trs sim p lem en t et est assez efficace. C o m p aro n s-le
avec dautres im p lm en tatio n s.
ra, ca = A . shape
xz
DI rb, cb = B . shape
>-
Q.
a s s e r t ca == rb, " T a ille s in co m p atib les"
O C = n p . z e r o s ( ( ra, cb),dtype = i n t )
U
f o r i in r a n g e ! r a ) :
A i,C i = A [i],C [i]
f o r j in r an g e (c b):
f o r k in r a n g e ! c a ) :
C i [ j ] += A i [ k ] * B[k, j ]
re tu rn C
Thmes mathmatiques 85
A vec C yth o n Cython (h ttp ://cy th o n .o rg /) est un langage dont la syntaxe est trs p roche de
celle de Pyth o n m ais cest u n langage q u i p erm et de gnrer des excutab les co m p ils et du ti
lise r un style de p ro g ram m atio n p roche du C . C ela p erm et d o p tim ise r grandem ent Pyth o n .
Le lo g icie l de ca lcu l fo rm el Sage http ://w w w .sag em ath .o rg / est p rin cip a le m e n t crit en C y
thon p o u r gagner en e ffica cit .
Voyons u n exem ple en uvre. Lusage co n jo in t de P yth o n et C yth o n est grandem ent fa c ilit
p ar le tra v a il dans l en viro n n em en t iP yth o n .
P y th o n
In [ 2 ] :
%%cython
cim port cython
im port numpy as np
cim port numpy as np
cdef l o n g ! : , :] matprodC( l o n g [ : , :] A, l o n g [ : , :] B) :
I 1 I
cdef :
in t i , j , k
in t ra = A.shape[0]
i n t ca = A .s ha p e[ l]
i n t rb = B.shape[0]
i n t cb = B .s h a p e [l ]
long [ : , :] C
long [ : ] A i, C i
C = n p . z e r o s ( ( ra, cb ),dtype=int)
f o r i in r a n g e ( r a ) :
TO3 A i,C i = A [i],C [i]
c
3 f o r ] in range(cb):
f o r k in r a n g e ( c a ) :
tH
O C i [ ] ] = C i [ j ] + A i [ k ] * B[ k, j ]
CM
re tu rn C
(y)
xz def matP rod(long [ : , :] A, B ):
CTI
>- re tu rn matprodC(A, B)
Q.
O
U O n rem arqu e q u crire en C yth o n re vie n t u n peu crire en Pyth o n m ais en d claran t des
va riab le s com m e en C .
iP yth o n p erm et galem ent de co m p arer facile m e n t les tem ps de c a lcu l avec la com m ande
m agique % tim e it.
O n co m m ence p ar cr er une m a trice de ta ille 200 x 200 p u is on va dem ander son co e fficie n t
[100,100] :
IP y th o n
86 Programmation en Python pour les mathmatiques
I In [ 3 ] : A = np .o ne s(( 2 0 0 ,2 0 0 ),dtype = i n t )
N otre fo n ctio n en C yth o n est 500 fo is p lu s rap id e ! ! ! E lle est trs lgrem ent p lus lente que le
p ro d u it de numpy.
E t notre im p lm en tatio n p erso n n elle avec la classe Mat ?
P y th o n
In [ 7 ] : A = Mat([2 0 0 ,2 0 0 ] ,lambda i , j : l )
Trop fo rt! N ous b attons tout le m onde p late co u tu re ! N ous som m es 100 fois p lu s rap id es
que numpy ! ! ! ...e t nous avons b ien le bon r su lta t :
P y th o n
I
ln [ 9 ] : (A* A )[100,100]
Out[ 9 ] : 200
E n effet, J = est u n r su lta t cla ssiq u e . O n u tilise u n alg o rithm e dexp o n en tiatio n ra
p id e. Par exem ple, en v o ic i une ve rsio n r cu rsive rap id e crire q u i se n o m m e __pow___a fin
OJ
du tilis e r le sym bole ** :
>-
CL
O m a tn c e .p y
U
def __ pow__ ( s e l f , n ) :
r = self.D[0]
def p u i ( m , k , a c c ) :
i f == 0:
re tu rn
re tu rn pui((m*m), k / / 2 ,a c c i f % 2 == 0 e ls e (m*acc))
re tu rn p u i ( s e l f , n , u n i t e ( r ) )
Thmes mathmatiques 87
S o lu tio n .
= self.D [ ] 0 i f % == 2 1
= n acc *= m
m = s e lf m *= m
acc = u n i t e ( r ) //= 2
re tu rn acc
Tout est dans le titre . N ous vous rap p elo ns que la trace dune m atrice est gale la som m e de
ses lm ents d iag onaux.
m a t ri c e . p y
def t r a c e ( s e l f ) :
r,c = self.D
a s s e r t r == c, "La matrice d o it tr e carre"
re tu rn s u m ( s e l f [ i , i ] f o r i in r an g e (r ))
Po ur effectu er une co m b in aiso n lin a ire des lig n es, on va cr er une fo n ctio n :
co m b_lig n e(ki,kj,M ,i,j)
q u i ren ve rra la m a trice co n stru ite p a rtir de M en rem p laan t la lig ne Ly p ar k j x Ly + ki x L / .
a m a tr i c e , p y
O
c def c o m b _ l i g n e s ( s e l f , k i , k j , i , j ) :
D
.... ' L i <- k i* L i + kj * L j .....
f = self.F
O
rs] g = lambda r ,c : k i * f ( i , c ) + k j * f ( j , c ) i f r == i e ls e f ( r , c )
re tu rn M a t ( s e lf .D ,g )
Jd
DI O n cre galem ent une fo n ctio n m u lt_lig n e ( k , M, j ) : q u i ren ve rra la m atrice co n stru ite p a r
>-
Q.
O tir de M en rem p laan t la lig ne Ly p ar A: x L y .
U m a tr i c e , p y
def m u l t _ l i g n e ( s e l f , k , i ) :
"""Li <- k * L i .....
f = self.F
g = lambda r ,c : k * f ( i , c ) i f r == i e ls e f ( r , c )
re tu rn M a t ( s e lf .D ,g )
88 Programmation en Python pour les mathmatiques
1 .3 .2 C a lc u l de l in v e rse ta p e p ar ta p e
On com m ence p ar cr e r une fo n ctio n q ui renvo ie une m a trice o se ju xtap o sen t la m atrice
in itia le et la m atrice id e n tit :
m a tr i c e , p y
def c a t _ c a r r e _ d r o i t e ( s e l f ) :
Il II II
fl 0 n
0 1 1
1 1
1 oj
m m e ta ille :
> T = T .m u lt_lig n e (-0.5,2)
> T = M cat c a r r e _ d r o i t e ( ) > T
> T 1 0 1 1 0 0
1 0 1 1 0 0 0 1 1 0 1 0
On effectue Li ^ Li - L 3 :
On effectue L ^ L - L i : 3 3
> T = T = T .com b_lignes(l,-1,1,2)
> T = T.com b _lignes(l,-1,2,0) > T
> T 1 0 1 1 0 0
0 1 0 1 1 0 0 0 1 0 0.5 0.5 0. 5
c
D
0 1 1 0 1 0 0 0 1 0.5 0.5 -0 .5
OD 0 1 - 1 - 1 0 1
1 1
et enfin L 2 ^ L 2 - L 3 :
0
CM puis L 3 - L 3 - U
(y) > T = T comb_lignes(l,- , , ) 1 0 2
-M
XI
> T = T.comb_ l i g n e s ( l , - , , ) 1 2 1 > T
CTI > T 1 0 0 0.5 -0.5 0.5
>-
Q . 1 0 1 1 0 0 0 1 0 -0.5 0.5 0.5
0
U 0 1 1 0 1 0 - 0 - 0 1 0.5 0.5 -0.5
0 0 - 2 - 1 - 1 1
Il ne reste p lu s q u e xtraire la m o iti d roite du tab leau q u i sera l in ve rse cherche l aide
dune p etite fo n ctio n :
m a tr ic e .p y
I def e x t r a i t _ c a r r e _ d r o i t e ( s e l f ) :
Thmes mathmatiques 89
E x t r a i t le c a rr de d r o it e d'un tableau de GJ
il II II
r ,f = se lf.D [0 ], self.F
re tu rn M a t ( [ r , r ] , lambda i , j : f ( i , j + r) )
O n p o u rra it ca lcu le r l in ve rse dune m a trice en g n ralisan t la m thode prcdente m ais cela
sa vrerait b eaucoup trop gourm and en tem ps.
N ous a llo n s dans u n p re m ie r tem ps trig o n a lise r la m a trice en effectu an t des o p ratio ns l
m en taires.
Po ur vite r de faire trop de tra n sfo rm atio n s, nous a llo n s p etit p etit rd u ire la ta ille de la
m a trice trig o n a lise r en ne co n sid ran t que le carr in f rie u r d ro it situ sous le p ivo t co u ran t
et m m o rise r chaque lig ne obtenue dans une m atrice .
C ela p erm et galem ent de g n raliser l em p lo i de la m thode de G auss des m atrice s non
carres p o u r la r so lu tio n de systm es p ar exem p le. Il fau t donc faire atten tio n m ain te n an t
u tilis e r le m in im u m entre le nom bre de lig nes et le nom bre de co lo nn es de la m atrice .
O n p lace des m o u chard s p o u r com prendre l vo lu tio n du code.
m a tr i c e , p y
def t r i a n g l e ( s e l f ) :
""" re n vo ie la tria n g u la tio n d'une m a trice de haut en bas " " "
[r,c ] = self.D
m = m in(r,c)
TJ
O S = s e lf
c
rj T = zeros(r,c)
JD
tH
w h ile m > : 0
O
CM
NoLigne = 0
w h ile S[NoLigne, 0] == 0 and (NoLigne < m - 1 ):
(y)
NoLigne += 1
XI
OJ i f S[NoLigne, 0] != 0:
>- p iv o t = S[NoLigne,0]
Q.
O f o r k in ran g e ( , m):
U 1
i f S [ k , 0 ] != 0:
S = S. com b_lig nes(pivot, - S [ k , 0 ] , k , 0 )
print("pivot = "+ str(p ivo t))
p r i n t ("S dans fo r :" )
p r i n t (5)
T = T .r em p la c e_ li g ne d ( r - m,S.F)
p r i n t ( "volution de T : " )
90 Programmation en Python pour les mathmatiques
p r i n t (T)
S = S.dswap(NoLigne;
m -= 1
re tu rn T
P ar exem ple :
In [ 1 ] : M v o lu tio n de T
O u til]: 1 2 3
1 2 3 0 0 0
4 5 6 0 0 0
7 8 8 p iv o t = -3
In [ 2 ] : M . t r i a n g l e ! ) S dans fo r :
p ivo t = 1 -3 - 6
S dans fo r : 0 3
1 2 3 v o lu tio n de T
0 -3 - 6 1 2 3
7 8 8 0 -3 - 6
p ivo t = 1 0 0 0
s dans fo r : v o lu tio n de T
1 2 3 1 2 3
0 -3 - 6 0 -3 - 6
0 -13
- 6 0 0 3
N ous avons b eso in de deux fo n ctio n s in te rm d ia ire s, une re m p lissan t le tableau T et l autre
rd u isa n t S.
m a tr i c e , p y
def d e c o u p e ( s e l f , i ) :
Il II II
O
a
cZJ [lig , co l], f = self.D , s e lf.F
re tu rn Mat( [ l i g - 1 , c o l - 1 ] , lambda r , c : f ( r + l , c + l ) )
U3
tH
O
fM
def remplace_ligned( s e l f , i , g) :
Il II II
S o lu tio n .
Thmes mathmatiques 91
def r a n g ( s e l f ) :
r,c = self.D
T = s e lf .triangle()
re tu rn l e n ( [ T [ i , i ] f o r i in range(r) i f T [ i , i ] != 0 ])
1 .3 .4 C a lc u l du d te rm in a n t
def d e t ( s e l f ) :
..... . re n vo ie le dterm inant de s e l f par G auss-Jordan ......
[ r,c] = self.D
a s s e r t r == c, "M atrice non carre"
S , i , d = s e l f , 1,1
w h ile r > : 0
NoLigne = 0
w h ile S[NoLigne, 0] == 0 and (NoLigne < r - 1 ):
NoLigne += 1
i f S[NoLigne, 0] == 0:
re tu rn 0
pivot = S[NoLigne,0]
S = S.swap(0,NoLigne)
i *= ( - ) 1 (NoLigne != 0)
fo r k in range(1 , r ) :
i f S [ k , 0 ] != 0:
S = S .c om b _ li g ne s (p iv o t, - S [ k , 0 ] , k , 0 )
i *= p ivo t
S = S.decoupe()
r -= 1
d *= pivot
a
O re tu rn ( d / i )
c
13
Q C est assez efficace p o u r du P yth o n b asique : 555 m s p o u r u n d term in an t dune m a trice de
y> ta ille .2 0 0
O
r\i In [ 1 ] : M = unite(20O)
In [ 2 ] : % tim eit M.det()
ai
s_
1 loops, best of 3: 555 ms per loop
>-
CL
O
U
1 .3 .5 C a lc u l de l in v e rse d une m a tric e
L a trig o n a lisa tio n est assez rap id e du fa it de la rd u ctio n prog ressive de S. Lide est alo rs de
trig o n a lise r de bas en h au t p u is de h au t en bas p o u r a rriv e r une m atrice diagonale ce q ui
sera p lu s efficace q uu n traite m e n t de tout le tab leau en co n tin u .
O n peut u tilis e r la fo n ctio n det q u i est rap id e et p erm et de ne pas prend re trop de p rcau tio n s
en su ite sach an t que la m atrice est in ve rsib le .
92 Programmation en Python pour les mathmatiques
m a tr i c e , p y
def i n v e r s e ( s e l f ) :
re tu rn
s e l f . c a t_ca rre _d ro ite () . t r i a n g l e ( ) .d iag o _triang le () .e x t r a it _ c a r r e _ d r o it e ()
def d i a g o _ t r i a n g l e ( s e l f ) :
[r ,c ] = self.D
a s s e r t c == 2 * r , "Le tab leau d o it tr e un re cta n g le L x (2L)"
m =r - 1
S =self
T =zeros(r,c)
w h ile m>= : 0
pivot = S[m,m]
a s s e r t p iv o t != , "matrice non in v e r s ib le "
0
fo r k in r a n g e (m - l ,- , - ) :1 1
i f S[k,m] != 0:
S = S .c om b _ li g ne s (p iv o t, -S[ k,m],k ,m)
T = T.rem plac e_l igne g(m,S .F)
S = S.decoupe_bas()
m -= 1
f o r k in r a n g e ! r ) :
T = T . m u l t _ l i g n e ( 1 / T [ k , r - 1 ] , k)
re tu rn T
On transforme lgrement les fonctions intermdiaires prcdentes pour les adapter au nou
veau parcours :
m a tr ic e , p y
def decoupe_bas(self) :
Il II II
O
(N
#g = lambda r , c : f ( l i g - l , c ) i f r == l i g e ls e f ( i , c ) i f r == lig - 1 e ls e
f(r,c)
g = lambda r , c : f ( r , c ) i f c < lig - e ls e f ( r , c + l )
1
x:
DI re tu rn Mat( [ l i g - 1 , c o l - 1 ] , lambda r , c : g ( r , c ) )
>-
Q.
O def r e m p l a c e _ l i g n e g ( s e l f , i , g ) :
U Il II II
S o lu tio n .
Avec nos fo n ctio n s :
In [ 1 1 : M = l i s t mat( [ [le-
2 2 0 , , ] , [l,le
0 1 2 0 ,l],[ , ,-
0 1 1 1 1 )
In [ ] : M.,t r i a n g l e ! )
2 In [31: M.rang! )
0ut[ ] : 2 0ut[3]: 2
lE- 2 0 0 1
0 1 - 1 In [ 4 ] : M.det()
0 0 0 0ut[4]: 0
0 1 A
P o u rtan t en effectu an t la trig o n a lisa tio n la m a in on trouve : 0 -1 1-1020
V 0 0 )
La m atrice est donc de rang 3 et son d te rm in an t vau t 10 ^^.
Le p rob lm e :
In [ 5 ] : 1 - le-20 == 1
Out[ 5 ] : T rue
L a rep r sen tatio n des flo tta n ts en p r cisio n stan d ard su r 64 b its en tran e l lim in a tio n de
10 ^^ devant 1 (vo ir 2.4 page 132).
kD des m a trice s co e fficie n ts dans Z / 2 6 Z (co m b ien y a -t-il de lettres dans notre a lp h a b e t?). Par
O la su ite nous noterons Z l ensem ble Z / n Z . C ela a ouvert le d om aine de la cryp to g rap hie
rs]
alg briq ue et de nos jo u rs, cest I A e s {A d va nced E n cry p tin g Sta n d a rd ], n en 2000, q u i assure
la m ajo rit de la scu rit in fo rm atiq u e .
ai
> N ous a llo n s exp lo rer cette m thode en tra v a illa n t su r tous les caractres affich ab les en A S C II.
CL
O
U
1 .4 .1 Codage
C haq ue caractre est asso ci un codage b in a ire , en gnral su r b its (un octet) ce q u i donne
8
Il a en su ite fa llu tendre ce code p o ur les langues co m p o rtant des caractres sp cia u x et l ,
les no rm es d iff ren t, ce q u i cre des p rob lm es de co m p a tib ilit .
D ep u is q uelques annes, le codage U nicode tente de rem d ier ce p rob lm e en co dant tous
les caractres e xistan ts.
La p lu p a rt des langages de p ro g ram m atio n , et b ien s r P y th o n , ont une com m ande q u i a s
socie le code A S C II (ven tu ellem en t tendu) un caractre. O n p o u rra donc L u tilis e r p o ur
rsoud re notre p rob lm e. Il sagit de la com m ande or d ( c a r a t re ) q u i renvoie le code A S C II
du caractre caractre.
Le -ord ( ' ' ) p erm et do b ten ir des caractres cods entre 0 et 94.
tH
Le p rin cip e co n siste alo rs regrouper les nom bres p ar paquets de lo ng ueur co nstante p et
donc co n stru ire p a rtir de la liste L une m a trice de p lig nes com plte ven tu ellem en t de
zros.
N ous allo n s p o ur cela cr er une fo n ctio n t o . H i l l ( l i s t e , p) q u i tran sfo rm e une liste en une
m a trice de p co lo nn es en co m p ltan t p ar des zros si ncessaire :
m a tr i c e , p y
def t o _ H i l l ( m , p ) :
CS = a s c ii (m )
w h ile l e n ( c s ) % p > : 0
CS += [0]
g = lambda i , j : c s [ ( i % p ) + p*j]
re tu rn Mat( [ p , l e n ( c s ) / / p ] , g)
Le m essage en c la ir d evient une m a trice . C h o isisso n s p ar exem ple u n 3-ch iffrem en t de H ill;
la m a trice c l a ir au ra donc 3 lig n es :
> c la ir = to_Hill(m ,3)
> c la ir
33 72 1 35 17 16 65 69 65 65 0 20 65 69 31
82 72 1 69 16 0 84 83 85 73 19 0 84 83 31
71 0 0 0 16 80 84 0 82 84 17 80 84 0 0
Il fau t ch o isir p rsent une cl de ch iffre m e n t : ce sera une m atrice carre de ta ille 3, coeffi-
1 23 29 \
( ^^ J co n vie n t.
0 3^1 1
N ous vo u d rio n s u tilise r in ver se m ais on y effectue une d iv isio n relle ce q u i nest pas au to
rise dans Z . N ous allo n s donc un peu tra n sfo rm er in ver se p o u r d onner la m thode din
9 5
versio n des nom bres com m e arg um ent. Seule la d ernire lig ne de d ia g o _tria n g le change en
fa it :
m a tr i c e , p y
"O
O
c def d i a g o _ t r i a n g l e ( s e l f , i n v ) :
rj
y>
O
r\l T = T . m u l t _ l i g n e ( i n v ( T [ k , r - 1 ] ) , k)
re tu rn T
ai p u is :
s_
>. m a tr i c e , p y
CL
O
(J def i n v e r s e ( s e l f , i n v ) :
re tu rn
s e l f . cat_carre_droite() .t r ia n g le ! ) .d iag o _tria n g le (in v).e xtra it_ca rre _d ro ite ()
C est u n p roblm e da rith m tiq u e q u i se rso ut l aide de l alg o rithm e d E u clid e tendu :
Petit rap p el su r cet alg o rithm e q u i p erm et de p ro u ver le thorm e de B zout et d o b ten ir des
co efficien ts u et v v rifia n t a u + b v = a A b :
96 Programmation en Python pour les mathmatiques
k Uk Vk rk Vjk
0 1 0 ro = a /
1 0 1 r\ = b ^1
2 U q U \ Cfi v ) - v iq i r2 = r o - n q i
3 U] - U 2 Cf2 v\ - V zq 2 r3 = r i - T2q2 /3
;
\ ;
P - 1 P p-i - a r \ b Cjp-\
P rp = 0
Uk
l^k+\ X ^k+\
= Uk+2
k Uk Vk rk ^k
0 1 0 19 / Lo
1 0 1 15 1 Li
2 1 -1 4 3 L2 ^ L q -|~ ^ X L i 1
3 -3 4 3 1 L3 L i 3 X L2
4 4 -5 1 3 L4 *L2 ~ 1 X L3
5 0 L5 L3 3 X L4
C est--d ire 4 x 1 9- 5x = 1 et 19 A 15 = 1.
1 5
O n va u tilis e r les tab leau x de numpy q u i p erm etten t deffectu er des o p ratio ns vecto rie lle s su r
a
O les liste s :
c13 m a tr i c e , p y
l a , Ib = Ib , la - q *lb
re tu rn la
Soit la classe de le n tie r a m odulo ri. D m o ntro ns que est in ve rsib le dans Z si et se u le
m ent si a et n sont p rem iers entre eux :
^ b = i O a b = l [ n] O 3 k & Z a b = l + k n O 3 k E Z b a - k n = l O a /\ n = l , la. d ernire
q u ivalen ce tant obtenue grce au thorm e de B zo ut.
Thmes mathmatiques 97
p ar exem ple nest pas p re m ie r avec 9, donc nest pas in ve rsib le dans Z , c est p o u rq u o i la
6 6 9
N ous allo n s donc u tilis e r la fo n ctio n bezout cre p rcdem m ent p o ur d term in er l in verse
dun nom bre dans Tn :
m a tr i c e , p y
def inv_mod(p,n):
B = bezout(p,n)
a s s e r t B[2] == 1, s t r ( p ) + ' non in v e r s ib le modulo ' + s t r ( n )
re tu rn B [ ] % n
0
> d e = U s t 2 m a t ( [ [ l , 23,29] , [ 0 , 3 1 , 1 ] , [ 4 7 , 3 , 1 ] ] )
> i n v _ d e = d e . i n v e r s e d a m b d a x ; inv_mod(x, 95))
> in v_d e
-1.82136E+09 -4.16311E+09 5.69826E+10
23312 -575552 -496
-30597 22638 651
ca lcu le r le reste de chaque co e fficie n t dans la d iv isio n p ar 95 donc dap p liq u er la fo n ctio n
lambda coeff : coeff % 95.
Com m e ce genre d actio n est stan d ard , on cr er une m thode map dans notre classe Mat (on
p arle alo rs de fo n c te u r en p rog ram m ation fo n ctio n n e lle q u i re jo in t la notion hom onym e en
th o rie des catg o ries).
m a tr i c e , p y
I
def map( s e l f , f ) :
re tu rn Mat( s e l f . D , lambda i , j : f ( s e l f . F ( i , j )))
A lo rs :
> i n v _ c l e = d e . in v e r s e ( l a m b d a x: inv_mod(x, 9 5 ) ) .map(lambda coeff : coeff % 95)
> inv_cle
"O 18 14 34
0
c 37 74
8 8
=3
Q 8 828 81
'JD
0 O n v rifie :
(N
> (d e * coeff % 95)
-4-1
xz 1 0 0
DI
0 1 0
>-
Q.
0 0 0 1
U
N ous pouvons m u ltip lie r d e p ar c l a i r p o u r co der notre m essage. Po ur le dcoder, il su ffira
de m u ltip lie r le m essage cod p ar i n v _ c l e .
L a m a trice d e x c l a i r est une m atrice de 3 lig n es. 11 fau d ra la tra n sfo rm er ensuite en liste p o ur
lu i a p p liq u er decode. O n u tilise la fo n ctio n i t e r d fin ie dans notre classe Mat.
> crypte
" sP_20u8?R' QOyE(Xph_<bn( h<Yc cAkDj\\pf_<bn( ho+>"
1 .4 .2 D co d a g e
a m arche ! O n rem arque les d eu x espaces (n eutres) rajo u ts la fin p o u r o b ten ir une ch an e
de lo ng ueu r u n m u ltip le de 3.
p erm ettan t de p asser u n in sta n t donn du n tat p rsent u n tat fu tu r ne dpend du pass
I
O q u travers le p rsen t so it : la p ro b ab ilit du fu tu r sach an t p rsent et pass est gale la
]
m arch an d ise p rise le m atin dans la v ille V/ so it rend ue le so ir dans la v ille V y. L a m atrice
P = est appele m atrice de tran sition de la ch an e de M a r k o v .
Thmes mathmatiques 99
O n sattend donc que la som m e des co m po santes de chaque vecteu r co lonne so it gal 1.
Supposons que P so it co nnue et v a ille :
' 0 , 8 0 ,3 0 ,2 \
p= 0 , 1 0 , 2 0 , 6
lo,i 0 ,5 0 , ,
2
Les tra fiq u a n ts se p ro m enant de v ille en v ille , il p eut tre u tile de v isu a lise r leu rs d p lacem ents
p ar le diagram m e de tran sition su iva n t :
0,8
0,2
y k e ll,n l x^^^
et donc p ar une rcu rren ce im m d iate :
a
O
c:
rj
JD Supposons que le ch e f de la m a fia lo cale d ispose de tra fiq u a n ts q u i p arten t tous le m atin
O 1 0 0 0
(N du jo u r 0 de la v ille de Z lo t. Q uelle sera la p ro p o rtio n de tra fiq u a n ts dans ch acu n e des v ille s
au bout d une sem aine ? dun an ?
CT Il sagit donc de ca lcu le r des p u issan ce s su ccessives de P. N ous allo n s u tilise r les o u tils de la
s_
>. sectio n p rcdente.
CL
O
U O n o b tient les p ro p o rtio n s au bout dune sem aine en ca lcu la n t P^ avec x^^ ( ) *
i.e . des p ro p o rtio n s resp ectives dans ch acu n e des v ille s d e n viro n 56,4 %, 22,6 % et 21 %.
Au bout d u n m o is, les p ro p o rtio n s ne changent gure :
> P**30 * X0
0.557377
0.229508
0.213115
> Xs = P**30 * XO
> D = P*Xs - Xs
> D
-2.79954E-09
1.47778E-09
1.32177E-09
1 .5 .3 L itt ra tu re a l a to ire
O n peut p ro d u ire des textes (ou de la m u siq u e ...) alato irem en t l aide de ch an es de M arkov.
Par exem ple, co n n a issa n t un co uple de lettres co n scu tives, on peut ca lcu le r la p ro b ab ilit
q uil so it su iv i p ar telle lettre en fa isa n t un ca lcu l de frq u ence su r un trs grand texte.
O n va en p ro fite r p o ur v o ir q uelq ues o u tils de m a n ip u la tio n de texte, de rcu p ratio n de textes
en lig n e.
On cre une classe p o u r tre p lu s P yth o n e sq u e...
m a r k o v .p y
O
(N
class M a r k o v ( o b j e c t ) :
03
"s_
>-
Q .
def __ i n i t __ ( s e l f , f i c h i e r ) :
O self.dicAssoc = { }
U
s e l f .fich ie r = fich ier
s e l f . lettres = self.fich ierV ersLettresO
s e l f . baseDeTuplets()
f ic h ie r . close()
def f i c h i e r V e r s L e t t r e s ( s e l f ) :
""" Renvoie le s l e t t r e s du t e x t e sous forme d'une l i s t e
Thmes mathmatiques 101
def t u p l e t s ( s e l f ) :
...... Cre un gn ra teu r de t r i p l e t s de l e t t r e s s u c c e s s iv e s """
f o r i in r a n g e ( l e n ( s e l f . l e t t r e s ) - ) : 2
y ie ld ( s e l f . l e t t r e s [ i ] , s e l f . l e t t r e s [ i + ] , s e l f . l e t t r e s [ i + ] )
1 2
def b a s e D e Tu pl et s (s e lf) :
......Cre un d ic t io n n a ir e dont le s c l s son t des co u p les de l e t t r e s
s u c c e s s iv e s e t la v a le u r la l i s t e des su c c e sse u rs o b se rv s. """
f o r 1 1 ,1 2 ,1 3 in s e l f . t u p l e t s ( ) :
key = 1 1 , 1 2
i f key i n s e l f . d i c A s s o c :
s e l f . d ic A s s o c [ k e y ] . a p p e n d ( l 3 )
else:
s e l f . d i c A s s o c [ k e y ] = [13]
(11,12) = c h o i c e ( l i s t ( s e l f . d i c A s s o c . k e y s ( ) ) ) # on c h o is i t un couple de
l e t t r e s au hasard dans le d ico
g e n _ le tt r e s = "" # on i n i t i a l i s e le te x te gnr
f o r i in r an g e (n b L e t t r e s ):
g e n _ le tt r e s += I l # on c r i t 11 dans le t e x t e
11,12 = l 2 , c h o i c e ( s e l f . d i c A s s o c [ ( 1 1 , 1 2 ) ] ) # on avance d' un cran
p r i n t ( g e n _ le t t r e s )
O n peut rcu p re r des textes en lig ne dont les d ro its sont lib re s :
# Notre-Dame de P a ris
U r l r e t r i e v e ! ' http : / / www.gutenberg. org/cache/epub/19657/pg19657.t x t ' , ' ndp. t x t ' )
TJ
O # Gone w ith the wind in e n g lis h
c
Z3 u r l r e t r i e v e ( ' http: // gut en ber g.ne t.a u/e bo ok s02 /0 200 16 1.tx t', ' a u t a n t . t x t ' )
KD Les textes sont m a in te n a n t enreg istrs au fo rm at txt dans le rp erto ire co u ran t.
tH
Oi
rs Il ne reste p lu s q u en faire des objets de type M arkov :
(S)
ndp = Markov(open(' n d p . t x t ' , ' r ' ) )
sz
OJ autant = Markov(open( ' a u t a n t . t x t ' , ' r ' ))
>-
CL
O O n peut alo rs gnrer du V icto r H u g o alato ire avec la com m ande :
U
> ndp.genereMarkovText(300)
Vot, M a m ill befugh tow n sh er to h a n ica n d She m ong fo r sestraid and he sa ir tons
w h is A s b ey yo u ts, ass w elp gionto the carm e : He depe ? A tled I die theard the
w rain g . Eurgo anked , streft te shou de up sw are shand m or w h ard er lan k.
I w it. H o p le n cith e ons. D on sw itay : To d d ly yo u rs. D e a rry bee
O n p eut o b ten ir quelque chose de p lu s lisib le en ne co m b in an t p lu s les lettres m ais les m ots
du texte.
Il su ffit de faire d eux lgres m o d ifica tio n s. D une p art la p rem ire fo n ctio n doit renvoyer la
liste des m ots ce que l on peut o b ten ir avec la m thode s p l i t :
def f i c h i e r V e r s L e t t r e s ( s e l f ) :
data = s e l f . f i c h i e r . read()
re tu rn d a t a . s p l i t ()
D autre p art, dans la d ern ire fo n ctio n , on in tro d u it une espace entre les m ots :
g e n _ le tt r e s += ' ' + I l
E n ang lais :
x:
DI 1.6 Manipulation dimages
>.
CL D ans cette sectio n , des m athm atiq ues co ncrtes vo n t nous p erm ettre de rd u ire, ag rand ir,
O
U asso m b rir, c la irc ir, co m presser, b ru ite r, q u a n tifie r,... une photo. Pour ce la, il existe des m
thodes p ro venant de la th o rie du sig nal et des m athm atiq ues co n tin u e s. Nous nous p en ch e
rons p lu t t su r des m thodes p lu s lgres bases su r l algbre lin a ire et lanalyse m a tricie lle .
U ne im age sera p o u r nous une m atrice carre de ta ille co e fficie n ts dans ] , ^ - ] . C ela
2 0 2 1
m anque de ch arm e ? C est sans co m p ter su r Le n a q u i d ep uis q uarante ans rend les m aths
sexy (la p o p u latio n h a n ta n t les lab o rato ires m athm atiq ues et su rto u t in fo rm atiq u e s est p lu
tt m a sc u lin e ...).
Thmes mathmatiques 103
U n peu de tout ce la et dautres choses encore : ce la sa p p e lle ...L a m athm atiq ue.
1 .6 .1 Le n a
N ous allo n s tra v a ille r avec des im ages q u i sont des m a trice s de n ive a u x de g ris. N otre b elle
am ie L n a sera rep rsente p ar une m a trice carre de ta ille 2^ ce q u i p erm et de rep ro d uire
L n a l aide de 2^^ = 262144 p ixe ls. L n a prend alo rs beaucoup de p lace. N ous a llo n s ten ter
de co m p resser la p auvre L n a sans p o u r ce la q uelle ne perde sa q u alit g rap hiq ue. U ne des
m thodes les p lu s abordables est d u tilis e r la d co m p o sitio n dune m atrice en va le u rs sin g u
li re s.
C est un su je t extrm em ent rich e q u i a de nom breuses a p p lica tio n s. Lalg orithm e que nous
u tilise ro n s (m ais que nous ne d ta ille ro n s pas) a t m is au p o in t p ar deux trs m in en ts
ch erch eu rs en 1965 (G ene G o l u b , tats-u n ien et W illia m Ka h a n , can ad ien , pre de la norm e
lE E E -7 5 4 ). 11 sagit donc de m athm atiq ues assez rcen tes, au m o in s en co m p araiso n avec
votre p ro g ram m e...
La p etite h isto ire d it que des ch erch e u rs a m rica in s de l U n iv e rsity o f So u th ern C a lifo rn ia
taien t presss de tro u ve r une im age de ta ille 2^^ p ixels p o ur le u r co nfrence. Passe alo rs un
de le u rs collgues avec, en bon in fo rm a tic ie n , le d e rn ie r P layb o y sous le bras. Ils d cid rent
alo rs du tilis e r le p o ster ce n tra l de la Playm ate com m e su p p o rt...
L a photo o rig in ale est ic i : h ttp ://w w w .le n n a .o rg /fu ll/le n _fu ll.h tm l m ais nous nu tilise ro n s
que la p artie scanne p ar les ch erch e u rs, de ta ille 5 .1 2 in x 5 .1 2 in ...
1 .6 .2 E n v iro n n e m e n t de tra v a il
N ous tra v a ille ro n s dans IP yth o n avec l o p tio n p y l a b q u i charge les b ib lio th q u es n cessaires
la m a n ip u la tio n dim ages (en fa it, p ylab charge les b ib lio th q u es p o u r se retro u ver dans un
a en viro n n em en t p roche de ce lu i de lo g icie ls com m e M atLab ou S c ila b ).
O
c13 $ ipython --pylab
def mat a rr a y( m a t ) :
2
def montre(mat):
104 Programmation en Python pour les mathmatiques
P ytho n co n tie n t un tab leau carr de ta ille 512 co n ten an t les n ive a u x de gris rep rsen tan t
Le n a . Il su ffit de ch arg er les bonnes b ib lio th q u es :
In [ 9 ] : matlena.D
0 u t [ 9 ] : [512, 512]
On peut v o ir Le n a :
In [ 3 ] : montre(matlena)
0 u t [ 3 ] : <matplotlib.image.Axesimage at 0x7fO6c6d0c7b8>
et on o b tien t :
def rvb_to_gray(m):
r , c = m.shape
r e t u r n ( n p . a r r a y ( [ [ s u m ( m [ i , i ]) / 3 f o r j in range(c)] f o r i in r a n g e ( r ) ] ) )
In [ 3 ] : montre(lena_face)
0 u t [ 3 ] : <matplotlib.image.Axesimage at 0x7f6d8c68cc88>
1 .6 .3 M a n ip u la tio n s b asiq u es
E x e rc ic e 3 8 . C om m ent o b ten ir les d eux im ages de gauche sach an t que l im age o rig in ale est
d ro ite :
S o lu tio n .
Juste p ar de sim p les m a n ip u la tio n s des co e fficie n ts :
m a tr i c e , p y
def retourne(m):
[ r , c ] , f = m.D, m.F
re tu rn Mat( [ r , c ] , lambda i , j : f(r - 1 - i, j))
def m i r o i r ( m ) :
[ r , c ] , f = m.D, m.F
re tu rn Mat( [ r , c ] , lambda i , j : f(i,c - 1 - ]))
Sach an t que l ch elle de g ris va rie entre 0 et 255, co m m ent o b ten ir les im ages su ivan tes :
a
O
c
13
Q
y>
1 1
O
r\i
ai
s_
>-
CL
O
U
m atlena.map(lambda x : i n t ( x * * 3 / 2 5 5 * * 2 ) )
106 Programmation en Python pour les mathmatiques
S o lu tio n .
O n prend le co m p lm en taire p ar rap p o rt 255 :
m atlena.m ap(lam bda x : 255 - x)
1.6.4 R so lu tio n
in f rie u re ^). 2
TJ
O
c
rj m a tr i c e , p y
JD
I
def r e s o l u t i o n ( k , m a t ) :
tH
O
(N
[ r , c ] , f = mat.D,mat.F
>. Par exem p le, p o ur rd u ire l im age 128 x 128 de cette m anire :
Cl
O
U r e s o l u t i o n ( 4 , matlena)
1 .6 .5 Q u a n tific a tio n
O n peut galem ent rd u ire le nom bre de n ive a u x de g ris en reg ro upant p ar exem ple tous les
n ive a u x entre 0 et 63 en u n seu l n ive au 0, p u is 64 127 en 64, 128 191 en 128, 192 256 en
192.
Par exem ple, avec 4, p u is 16 n ive a u x :
8
Thmes mathmatiques 107
m atlena.map(lambda x : x / / 2**4)
M ais une d iv isio n d un nom bre p ar une p u issan ce de 2 re vie n t faire un dcalage de la ch an e
de b its rep rsen tan t ce nom bre vers la d roite Ce dcalage vers la d roite est effectu en P ytho n
p ar l op rateur . Lim age p rcdente peut donc tre obtenue p ar :
m atlena.map(lambda x : x 4)
1.6.6 E n le v e r le b ru it
def b e r ( p ) :
re tu rn 1 i f randomO < p e ls e 0
def rand_image(dim,p):
re tu rn Mat(dim, lambda i , j : randint(0,255)*ber(p))
def b r u i t ( m a t , p ) :
re tu rn (mat + rand_image(mat.D,p))
Il existe de nom breuses m thodes, ce rta in es trs labo res, p erm ettan t de m in im ise r ce b ru it.
U ne des p lu s sim p les est de rem p lacer chaque p ixe l p ar la m oyenne de lu i-m m e et de ses 8
v o isin s d ire cts, vo ire a u ssi ses 24 v o isin s d irects et in d ire cts, vo ire p lu s, ou de la m d iane de
ces sries de cercles co n ce n triq u es de p ixe ls.
m a tr i c e , p y
def moyenne(mat, k ) :
[ l i , c o ] , f = mat.D, mat.F
re tu rn M a t ( [ l i - k,co - k ] ,
lambda i , j : np. mean( [ f ( r, c)
f o r r in range(i - k, i + k + ) 1
f o r c in range(j - k, j + k + ) ] ) )
1
def mediane(mat, k ) :
[ l i , c o ] , f = mat.D, mat.F
re tu rn M a t ( [ l i - k,co - k ] ,
lambda i , j : n p .m e d ia n( [f ( r, c)
f o r r in rang e( i - k, i +k + 1 )
f o r c in range(j - k, j +k+ 1 )]))
V o ici les rsu lta ts avec resp ectivem en t la m oyenne su r des 9 p ixe ls p u is 25 p ixels et doite la
m d iane de carr s de 9 p ixe ls. L a m d iane est p lu s e fficace que la m oyenne !
a
O
c13
Q
yo
1 1
O
r\l
ai
> 1.6.7 C o m p re ssio n p ar S V D
CL
O
U
U n thorm e dm ontr o fficie lle m e n t en 1936 p ar C a ri E c k a r t et G ale Y o u n g a ffirm e alo rs
que toute m a trice rectan g u laire A se dcom pose sous la form e :
A =U XS XV
' O l
\ "ViA
A=(Ui U2 Ur Um ) Or X 'V ,.
< 0.
OUformul autrement :
A O'! U] X -f- 02 U 2 ^ ^^2 "H -h O/- U/- X ^V/- -l- 0 U / -1-1 X ^V/-i-i -!-
= Ol-Ui X Vi-h02-U2 X V2-H----HO,--Ur X V,-
II fau t en su ite se so u ve n ir que les o/ sont classs dans l ordre d cro issan t ce q u i va a vo ir des
a p p lica tio n s im p o rtan tes en in fo rm atiq u e .
D an s de no m b reu x d o m ain es, on d oit tra v a ille r avec de grosses m a trice s. Il est alo rs trs im
p o rtan t de d te rm in e r une m a trice A^ de m m e ta ille q u une m a trice A m ais de rang in f 5
a souvent la norm e de F r o b e n iu s , i.e . la racin e carre de la som m e des carrs des co e fficie n ts).
O
c Le thorm e dEcKA RT-Y o u n g p erm et alo rs de d ire que :
13
y)
1-H
O
rsl m in IIA
rg(X)^5
X || f = ||A-A^II f - , Ct2(A)
\ y=s+l
03
s_
avec A = Oi -U i X V i -i- 'U x V - -- * X
5 0 2 2 2 1 1 0 5 : on co nsid re que les lm ents diag onaux
1 3 5 ^ 5
>. de A sont n u is en-dessous d un ce rta in se u il. N ous a llo n s l illu s tre r in fo rm atiq u e m e n t dfaut
CL
O de le dm onter. O n v o it tout de su ite des co nsq uences p ratiq u e s, que nous allo n s galem ent
U
illu s tre r in fo rm atiq u e m e n t dans le cas de la co m p ressio n des im ages.
La m atrice donc im age peut tre dcom pose sous la form e :
avec les a i de p lu s en p lu s p etits. O n peut donc ap p ro xim er A en ne gardant que les p rem iers
term es de la som m e sach an t que les d ern iers sont m u ltip li s p ar des p etits o /.
110 Programmation en Python pour les mathmatiques
Le p rob lm e est do b ten ir cette d co m p o sitio n . Pyth o n heureusem ent sen charge grce la
fo n ctio n l i n a l g . svd(mat) q u i renvo ie la d co m p o sitio n en va le u rs sin g u lires sous la form e
de tro is a rra y de numpy U , S et V .
Par so u ci de ffica cit , nous tra v a ille ro n s ic i u n iq u em en t avec les a rra y de numpy.
def c _ s v d ( m a t , k ) :
U , s , t V = l i n a l g . svd(mat)
d = mat.shape
C = np.zeros(d)
f o r P in r a n g e ( k ) :
C += s [ p ] * ( n p . d o t ( U [ : , p ] . reshape!( d [ 0 ] , 1 ) ) , t V [ p , : ] . reshape!( l , d [ l ] ) ) ) )
re tu rn C
obtenus p ar :
On peut o b server la d cro issan ce extrm em ent rap id e des va le u rs sin g u lires
In [11 U,s,tV = l i n a l g . s v d ! m i s e . l e n a ! ))
In [2] X = np.arange!len!s))
In [3] p lo t !x [:1 0 ],s[:1 0 ])
In [4] p lo t !x [10 : 5 0 ] , s [ 1 0 : 5 0 ] )
a
O
In [5] p lo t !x [50 : ] , s [ 5 0 : ] )
c
13
O
Thmes mathmatiques 111
O n peut galem ent faire une p etite a n im atio n des im ages com presses :
m a tr i c e , p y
def a n im (i m ,n ):
f o r in ran g e (n ):
p i t . imsave("lena_face_svd" + str(10OO + k ) , c _ s v d ( l e n a _ f a c e _ a r r a y , k ) ,
= cm.pink)
im port os
anim(150)
o s . system!"animate le n a _ f a c e _ s v d * . png")
o s . system!" rm le n a _ f a c e _ s v d * . png")
On o b tien t l im age anim e dont on peut rg ler la vite sse avec les touches < et >. U ne copie au
fo rm at m pg est fo u rn ie dans l arch ive .
a b W X
c d g h y Z
a
O
O n note :
c
(p i = a i f - h ) , p 2 = (a-\-b)h, ps = {c + d )e , p ^ - d { g - e ) ,
tH
[P 5 = {a + d ) [ e + h), pe = i b - d ) { g + h ) , py = i c - a ) { e + f ]
alo rs :
sz
CTI
L .
>- ' U; = P4 + P5 + P6 - P2
CL
O
U X = Pi + P2
y =P3 + P4
Z = pi-\-p5-p3-\-p7
- r r iij- i + [rrii+ij - r r i i - i jf
2 L e s n o m b re s : e n t r e a n a ly s e e t a lg b re
2 .1.1 M u lt ip lic a t io n e t c o m p le x it
O n co u p e p a r e x e m p le c h a q u e n o m b re en d e u x p a rtie s de m = [ n ! 2 \ c h iffre s :
\in I
(1 0 '" x i + X 2 )(1 0 '" y i + 2 ) = 1 0 ^ '" x iy i + 10'"(21 + 1 2 ) + 2 2
Si n==l Alors
j Retourner x.y
Sinon
m [n/2\
T (^ ) = 4 T (L / 2 J ) -h ( {n ) T (l) = 1
Xk = 4 x k - i + i 2 '^ ) Xo = l
O n o b tie n t :
TJ
O
c
rj
b c + a d = a c + b d - {a - b) {c - d )
114 Programmation en Python pour les mathmatiques
2 .1.2 C la s s e d e c h a n e s d e b it s
c la s s B i t s ( li s t ) :
Il II II
d e f __i n i t __ ( s e l f , b i t s = [ ] ) :
""" Une chane de b i t s e s t c o n s t r u i t e p a r t i r de l a l i s t e de ses b i t s " " "
s e l f . b i t s = b it s
d e f __i t e r __ ( s e l f ) :
""" On i t r e s u r l a l i s t e des b i t s " " "
return it e r ( s e l f . b it s )
d e f __l e n __ ( s e l f ) :
""" Permet de donner l e nombre de b i t s avec l a mthode l e n " " "
return le n (s e l f . b it s )
TJ
O
c
rj d e f __g e t it e m __ ( s e l f , d e ) :
ai d e f __r e v e r s e d __ ( s e l f ) :
> " " " P o u r re nv oy er l a chane de b i t s i n v e r s e " " "
CL
O return B i t s ( s e l f . b i t s [ : : - 1 ] )
U
def n o rm (s e lf) :
" " " N o r m a l i s e l ' c r i t u r e d ' une chane de b i t s en supprimant les
b i t s non s i g n i f i c a t i f s gauche'""'
if l e n ( s e l f ) == 0:
return s e lf
if le n (s e lf) == 1 :
Thmes mathmatiques 115
return B it s ( s e lf .b it s + s e lf.b it s )
te t e = s e l f [ 0 ]
qs = s e l f [1 :]
i f qs[0] == t e t e :
r e t u r n B i t s ( q s ) . norm{)
return s e lf
d e f __ s t r __ ( s e l f )
:
'""'On u t i l i s e la fo n c tio n s t r pour a f f i c h e r la l i s t e des b i t s .....
re tu rn s t r ( s e l f . b its )
d e f __ repr___( s e l f ) :
......Une b e l l e re p r s e n ta tio n dans l ' i n t e r p r t e u r
B i t s ( [ 0 , 1 , 1 , 0 , 1 ] ) e s t a f f i c h 0 :1 1 0 1 """
n = s e lf.n o rm O
return s t r (n [0 ] ) + . jo in ( s t r (b ) fo r b in n .b it s [ l:] )
2 .1.3 S o m m e d e d e u x c h a n e s d e b its
00101
+ 01001
01110
O n tro u ve b ie n 14.
I l fa u t fa ire a tte n tio n re p o rte r la re te n u e .
Q u e se p a sse -t-il q u a n d o n a d d itio n n e 3 b its ?
b'i ^3 re te n u e u n it
TJ 0 0 0 0 0
O
c
rj 0 0 1 0 1
0 1 0 0 1
JD
tH
O
CM
0 1 1 1 0
1 0 0 0 1
(y)
1 0 1 1 0
XI
OJ 1 1 0 1 0
>-
Q. 1 1 1 1 1
O
U
O n re m a rq u e q ue u = b l (b 2 b3) avec l o p ra te u r d u O U E X C L U S IF .
Q u a n t la re te n u e , elle v a u t 1 s i au m o in s d e u x des b its so n t 1. O n v a d o n c u tilis e r les o p
ra te u rs lo g iq u es E T et O U q u i s c riv e n t & et | e n P y th o n .
B its .p y
d e f __ add__ ( s e l f , other) :
I Il II II
116 Programmation en Python pour les mathmatiques
00101
+ 11001
a
O
c13 11110
Q
M a is o n tro u ve 5 + ( - 9 ) = - 1 4 ! I l fa u t tro u v e r u n e au tre id e s in o n il fa u d ra it c r e r u n e a d
O
d itio n p o u r les p o sitifs et u n e a u tre p o u r les n o m b re s de sig n es d iff re n ts ce q u i ra le n tira it
n o rm m e n t le tra ite m e n t des n o m b re s s u r m a c h in e .
ai C o n s id ro n s n= 1 1 1 1 0 et c a lc u lo n s n + 2.
>-
CL
O 11110
U
+ 00010
(1)00000
Si n e garde q ue le n o m b re de b its c o rre sp o n d a n t au p lu s lo n g n o m b re , on o b tie n t 0 (su r
m a c h in e , o n tra v a ille s u r 64 b its p a r e xe m p le et to u t ce q u i d p asse cette ta ille n est p as p ris
en c o m p te ).
Thmes mathmatiques 117
complment 1 +1
01001--- ^10110>10111
A in s i - 9 s c rit 1 0 1 1 1 et cette fo is :
00101
+ 10111
11100
P o u r sa v o ir le n o m b re q ue cette c h a n e re p r se n te , on effe ctu e les tra n sfo rm a tio n s r c ip ro q u e s
d a n s l o rd re in v e rse :
-1 complment 1
1 1 1 0 0 ^ 1 1 0 1 1 ---- ----------- ^00100
d e f m a p (s e lf,fo n c ) :
"""A p p liq u e une fo n c tio n aux b i t s d'une ch a n e ......
r e t u r n B i t s ( l i s t ( m a p ( f o n c , s e l f . b i t s ) ))
d e f c o m p l(s e lf ) :
"""R en vo ie le complment 1 d'une chane'""'
r e t u r n s e l f .m ap(lam bda x : 0 i f
x == 1 e l s e 1)
a
O
cD d e f __ neg__ ( s e l f ) :
'""'Oppos d'une chane en u t i l i s a n t le symbole - ......
tH bs = s e l f . b i t s
O
signe = bs[0]
i f signe == 1:
XI
r e t u r n ( s e l f + B i t s ( [ l f o r k i n r a n g e ( l e n ( b s ) ) ] ) ) .com p l()
ai r e t u r n s e lf.c o m p lO + B i t s ( [ 0 , l ] )
>-
Q.
O
U def sub ( s e l f , other) :
......D if f r e n c e de deux chanes avec ........
r e t u r n s e l f + (-o th e r)
def abs ( s e l f ) :
......Valeur absolue d'une chane'""'
r e t u r n - s e l f i f s e l f . s i g n e O == 1 e l s e s e l f
118 Programmation en Python pour les mathmatiques
2 .1.4 C o n v e rs io n en b a se 1 0
O n ra jo u te q u e lq u e s m th o d e s u tile s :
B its .p y
d e f m a n t is s e ( s e lf ) :
"""L a l i s t e des b i t s sans le b i t de s i g n e ......
r e t u r n s e l f .n o r m ( ) [ 1 : ]
d e f __ eq__ ( s e l f , other) :
"""Permet de t e s t e r l ' g a l i t de deux chanes p a r t i r de le u r forme
n o rm a lis e " ""
r e t u r n s e l f . norm() . b it s == o t h e r .norm() . b it s
def s ig n e (s e lf) :
"""R en vo ie le b i t de s ig n e " " "
return s e lf[0 ]
d e f t o _ d e c ( s e lf )
:
"""R en vo ie l ' c r i t u r e dcimale de la chane de b i t s " " "
"OO ab = a b s ( s e l f )
c13 CS = a b .m a n t is s e !) [ : : - 1 ]
Q if CS == []:
'JD
return 0
O
f
M n =0
dec = 0
xz f o r c i n es:
DI
>- n += i n t ( c ) dec
CL
O dec += 1
U
r e t u r n n i f s e l f . s ig n e !) == 0 e l s e -n
P a r e xe m p le :
In [29]: t re iz e = B i t s ! [ 0 , 1 , 1 , 0 , 1 ] ) In [ 3 1 ] : t re iz e
In [30 ]: d ix = B i t s ! [ 0 , 1 , 0 , 1 , 0 ] ) 0 u t[31]: 0 :110 1
Thmes mathmatiques 119
2 .1.5 M u l t i p l i c a t i o n d e l c o l e p r i m a i r e
def m u l_ p r im a ir e ( s e lf , o ther) :
..... ' M u l t i p l i c a t i o n avec l ' a l g o a p p r i s l ' c o l e p r i m a i r e ......
s i , s2 = s e l f . s i g n e ( ) , o t h e r . s i g n e ( )
s ig = s i s2
o p l, op2 = a b s ( s e l f ) [ 1 : ] , ab s(o th e r)[1:]
m = B i t s ( [0 ,0 ])
dec = l e n ( o p l ) - 1 # l e dcalage
f o r n i in o p l:
ml = []
f o r n2 i n o p2:
m l.a p p e n d ( n 2 * n i )
m = m + B i t s ( [ 0 ] + ml + [0 f o r k i n r a n g e ( d e c ) ] )
dec - = 1 # on va de gauche d r o i t e
if s i g == 1 :
r e t u r n -m
return m
d e f __mul__ ( s e l f , o t h e r ) :
...... D f i n i t l a m u l t p l i c a t i o n de deux chane avec l ' a l g o de l ' c o l e
"OO p rim a ire""
c13 re tu rn s e l f . m u l_ p rim a ire (o th e r)
Q
yo P a r e x e m p le :
O
r\l
In [38 ]: d ix * - t r e iz e In [39 ]: ( d ix * -t r e iz e ) .t o _ d e c
0 u t[38 ]: 1:0 1111110 0 u t[39 ]: -13 0
ai
s_
>
CL
O
U
2.2 Les nombres rationnels
N o u s u tilis e ro n s d a n s cette se c tio n la cla sse r a t i o n n e l in tro d u ite page 2 5 2 .
2 .2 .1 L e s fr a c t io n s c o n t in u e s
- V o u s c o n n a iss e z l a lg o rith m e s u iv a n t :
120 Programmation en Python pour les mathmatiques
172 = 3 x 5 1 -F 19
51 = 2 x 1 9 + 13
19 = 1x 13 + 6
13 = 2x 6 + 1
6 = 6 x 1+ 0
172 19 1 1
-------- 3 H---------- 3 + 3 +
51 51 fl 2 + 1^
P r a t iq u e d u d v e lo p p e m e n t
172
= [3 ,2 ,...]
~5
def fc r(F ) :
def a u x (n ,d ,r,L ) :
i f r == 0:
L.append(n / / d)
return L
D
O
e lse :
C
D L.append(n / / d)
r e t u r n a u x ( d ,r ,d % r , L )
UD
1I r e t u r n a ux(F.num () , F .d e n ( ) , F.num() % F .d e n ( ) , [])
O
r\i
P o u r re p re n d re n o tre e xe m p le :
ai In [1 7 0 ]: f c r ( r a t i o n n e l ( 1 7 2 , 5 1 ) )
>-.
s_
0 u t [ 1 7 0 ] : [3, 2, 1, 2, 6]
Q
O
U O n p eu t d m o n tre r q u u n n o m b re est ra tio n n e l s i, et se u le m e n t si, il a d m e t u n d v e lo p p e
m e n t e n fra c tio n s c o n tin u e s fin i.
V o ic i u n e v e rs io n im p ra tiv e , sim p le tra d u c tio n de la v e rs io n r c u rs iv e :
def f c i( F ) :
n , d , r = F.numO, F .d e n O , F.numO % F .d e n ()
L = []
w h ile r > 0 :
Thmes mathmatiques 121
L.append(n / / d)
n, d, r = d, r , d % r
r e t u r n L + [n / / d]
s a c h a n t q ue L 1 1 : ] re n vo ie la liste L tro n q u e de so n p re m ie r te rm e .
P a r e x e m p le : C u rio sit :
In [1 7 5 ]: f c 2 f ( [ 3 , 2 , 1 , 2 , 6 1 ) In [1 7 7 ]: f c 2 f ( [ 0 , 3 , 2 , 1 , 2 , 6 1 )
0 u t [ 1 7 6 ] : 172 / 51 0 u t [ 1 7 7 ] : 51 / 172
2 .2 .2 L e s r d u ite s d u n e fr a c t io n c o n t in u e
1
<7o+
c j\ -\-
j _
O n a p p e lle ce n o m b re ra tio n n e l la r d u ite de la fra c tio n c o n tin u e co n sid r e . C o m m e c est
u n ra tio n n e l, il s c rit so u s fo rm e irre d u c tib le
P o u r d c o u v rir u n e ve n tu e lle re la tio n de r c u rre n c e , o n p e u t o b se rv e r les p re m i re s r d u ite s :
TJ
No = i/o L>o= 1
O Ni = qocji -1-1 Di = qi
c
rj
N 2 = q o q i q z + ^0 + ^2 = <7 2 N i - i- N o D 2 = /1^ 7 2 + 1 = <^2^1 + D q
JD
tH
(y)
Nfc = i/jtNjt-i+Njt_2
XI
OJ Dfc = i/fcDjt-i +Dfc-2
>-
Q. a v e c N 0 = q o ,D o = 1 , N 1 = q o q i + l e t D i = q i.
O
U A p p e lo n s P y t h o n la re sco u sse :
d e f re d u ite (k ,Q ) :
i f k == 0:
r e t u r n f r a c ( Q [ 0 ] ,1 )
e lif k == 1:
r e t u r n f r a c (Q [l]* Q [0 ]- H l,Q [l] )
e ls e :
122 Programmation en Python pour les mathmatiques
r e t u r n f r a c ( Q [ k ] * { r e d u i t e ( k - l , Q ) ) .num +
( r d u i t e ( k - 2 , Q ) ) . n u m , Q [ k ] * { r d u i t e ( k - l , Q ) ) .den +
( r d u i t e ( k - 2 , Q ) ) .d e n)
d e f h e r o n _ r e c ( a ,fo ,n ) :
i f n == 0:
r e t u r n fo
r e t u r n h e r o n _ r e c ( a ,(f o + r a t io n n e l(a ) / fo) / r a t i o n n e l ( 2 ) , n - 1)
d e f h e r o n _ i t ( a ,f o , n ) :
app = fo
fo r k in range(n) :
app = (app + r a t io n n e l(a ) / app) / r a t io n n e l(2 )
r e t u r n app
C e q u i d o n n e p a r e xe m p le :
In [ 1 ] : h e r o n _ r e c ( 2 , r a t i o n n e l ( l ) ,6 )
0 u t [ l ] : 1572584048032918633353217 / 1111984844349868137938112
"O
O In [ 2 ] : h e r o n _ i t ( 2 , r a t i o n n e l ( l ) ,6)
c
=3 Out[ 2 ] : 1572584048032918633353217 / 1111984844349868137938112
Q
E s t- c e q u e la s u ite d es v a le u r s c a lc u l e s p a r la b o u c le c o n v e rg e v e rs \ / 2 ? N ous a u ro n s b e
XI
so in de d e u x th o r m e s q ue n o u s a d m e ttro n s et d o n t n o u s n e d o n n e ro n s que des v e rs io n s
>-
s_
Q . s im p lifi e s .
O
U
T h o r m e 3.1 (T h o r m e de la lim ite m o n o to n e ). T o u te su ite c ro is sa n te m a jo r e (ou d
c ro issa n te m in o r e ) co n verg e.
a) p o u r to u t e n tie r n a tu re l n o n n u l n, o n a r ^ y /2 ;
b) la su ite est d c ro issa n te ;
c) \ / 2 est l u n iq u e p o in t fix e p o s itif de / .
\ r n + l - ^ \ ^
lim ---------- r = C
n ^+00
JD rn+l - V 2
tH
fl
O
CM
2 .3 .2 D v e lo p p e m e n t e n f r a c t io n s c o n t in u e s d e n o m b r e s r e ls p a r t ir d e n o m b r e s
r a t io n n e ls
In [ 1 ] : [ f c i ( h e r o n _ i t ( 2 , r a t i o n n e l ( l ) , k ) ) f o r k i n r a n g e ( 5 ) ]
O u til]:
[ [ 1 ] ,
[ 1 , 2 ]
[ 1 , 2 , 2 , 2 ] t
[ 1 , 2 , 2 , 2 , 2, 2 , 2 , 2 ] ,
[ 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
In [ 3 ] : [ f c i ( h e r o n _ i t ( 5 , r a t i o n n e l ( 2 ) , k ) ) f o r k i n r a n g e ( 5 ) ]
0 u t[3 ] :
[[2],
[2, 4 ],
[2, 4, 4, 4 ] ,
[2, 4, 4, 4, 4, 4, 4, 4 ] ,
[2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ]]
A in s i, V 2 - 1 =
Thmes mathmatiques 125
O n e n d d u it q ue \ 2 - 1 = [ 0 ,2 ,2 ,2 ,2 ,2 ,2 , ] p u is que \ 2 - [1 ,2 ,2 ,2 ,2 ,- - - ].
P o u r le p la is ir, reg ard o n s q u o i p e u t re sse m b le r le d b u t d u d ve lo p p e m e n t en fra c tio n s
c o n tin u e s d u n o m b re d o r O = to u jo u rs a ve c n o s o u tils ru d im e n ta ire s :
In [ 1 ] : [ r e d u i t e ( k , f c i ( h e r o n _ i t ( 2 , r a t i o n n e l ( l ) , 5 ) ) ) f o r k in ran ge(8)]
O u t il] : U , 3 / 2 , 7 / 5 , 1 7 / 1 2 , 4 1 / 2 9 , 99 / 7 0 , 239 / 16 9 , 577 / 408]
U n e a p p ro x im a tio n r a t io n n e lle de e 10 p r s P o so n s = l +^ +
A lo rs o n a a u ssi
1f 1 f 1
1
1 + 1+ - 1 + - 1+ - L . ( 1 + -M 11)1
2 3 4 l U -1 l n] II))
U n e x e rc ic e c la s s iq u e m o n tre q ue e - e n <
A in s i, p o u r 7? = 167, o n o b tie n d ra 300 b o n n e s d c im a le s a u m o in s de e.
def ex po r(n) :
i f n == 1 6 7 :
return r a t io n n e l(1)
re tu rn r a t i o n n e l ( l ) + e x p o r(n + l) / r a t io n n e l( n )
In 1 1 ] : f c i( e x p o r ( 1 ) )
O u t il] :
12, 1 , 2, 1 , 1 , 4, 1 , 1 , 6, 1 , 1 , 8, 1 , 1 , 1 0 , 1 , 1 , 1 2 , 1 , 1 , 1 4 , 1 , 1 , 1 6 , 1 ,
1 , 18 , 1 , 1 , 20, 1 , 1, 22, 1 , 1 , 24, 1 , 1 , 26, 1 , 1 , 28, 1 , 1 , 30, 1 , 1 , 32,
1 , 1 , 34, 1 , 1 , 36, 1, 1 , 3 8 , 1 , 1 , 40, 1 , 1 , 4 2 , 1 , 1 , 44, 1 , 1 , 46, 1, 1,
a 48, 1 , 1 , 50, 1 , 1 , 52, 1 , 1 , 5 4 , 1 , 1 , 5 6 , 1 , 1 , 5 8 , 1 , 1 , 60, 1 , 1 , 6 2 , 1 ,
O
c
D 1 , 64, 1 , 1 , 66, 1 , 1, 68, 1 , 1 , 7 0 , 1 , 1 , 72, 1 , 1, 74, 1 , 1 , 76, 1 , 1 , 78 ,
1 , 1 , 80, 1 , 1 , 8 2 , 1 , 1 , 84, 1 , 1 , 86, 1 , 1 , 88, 1 , 1 , 90, 1 , 1 , 92, 1, 1,
kD
94, 1 , 1 , 96, 1 , 1 , 98, 1 , 1 , 10 0 , 1 , 1 , 10 2 , 1 , 1 , 104, 1 , 1 , 10 6 , 1 , 1,
Oi
rs 108, 1, 1, 110 , 1, 1, 112, 1, 1, 114 , 1, 1, 116 , 1, 1, 118 , 1, 1 , 120, 1, 1,
122, 1, 1, 124, 1, 1, 126 , 1, 1, 128 , 1, 1, 130, 1 , 1 , 132, 1, 1 , 134 , 1 , 1,
x: 136 , 1, 1, 138, 1, 1, 140, 1, 1, 142, 1, 1, 144, 1 , 1 , 142, 1 , 1 1 , 1 , 7 , ---------
CTI
>-
Q. E t p o u r fqpY :
O
U
In [ 2 ] : f c i( ( e x p o r ( l) r a t io n n e l( 1 ) ) / (e x p o r ( l) + r a t i o n n e l ( l ) ))
0 u t[2]:
[0 , 2 , 6 , 1 0 , 1 4 , 1 8 , 2 2 , 2 6 , 3 0 , 3 4 , 3 8 , 4 2 , 4 6 , 50 , 5 4 , 5 8 , 6 2 , 66, 7 0 , 7 4 , 78 ,
8 2 , 86, 90 , 9 4 , 98, 1 0 2 , 1 0 6 , 1 1 0 , 1 1 4 , 118 , 12 2 , 126, 130, 134, 138, 142,
146, 150, 15 4 , 15 8 , 16 2 , 166, 17 0 , 17 4 , 178, 1 8 2 , 18 6 , 19 0 , 1 9 4 , 19 8 , 202,
206, 2 1 0 , 2 1 4 , 218 , 222, 226, 230, 234, 238, 2 4 2 , 24 6 , 2 5 0 , 2 5 4 , 2 5 8 , 262,
26 6 , 270, 274, 278, 2 8 2 , 28 6 , 29 0 , 2 8 6 , ---------
126 Programmation en Python pour les mathmatiques
2 .3 .3 M t h o d e d e B r i g g s p o u r le c a l c u l d e s l o g a r i t h m e s
d e s r a c in e s c a r r e s .
E n s u it e , o n u t ilis e l a lg o r it h m e d e H r o n p o u r a v o ir u n e a p p r o x im a t io n d c im a le d e V z :
O 0 u t[3 ]: 3.1622776601683795
@ O n o b tie n t d o n c le ta b le a u s u iv a n t :
4 -1
XI
CTI
N o m b re s 10 ,0 0 0 0 3,1623 1,7783 1,3335 1,0 0 0 0
>-
Q.
O Lo g a rith m e s 1 0,5 0,25 0,125 0
U
L e p ro b l m e , c est q ue c o n n a tre le lo g a rith m e de 3,1623 n est p as trs in t re ssa n t. O n a im e
ra it p lu t t c o n n a tre c e u x des e n tie rs de 1 1 0 .
C est ic i q u in te rv ie n t l a n g la is H e n ry B r ig g s q u i p u b lia e n 1617 ses p re m i re s ta b les de lo g a
rith m e s d c im a u x c o n te n a n t 1 0 0 0 v a le u rs avec q u a to rze d c im a le s.
V o yo ns c o m m e n t il a p ro cd p o u r le c a lc u l de lo g (2 ).
Il a c o m m e n c p a r o b te n ir des v a le u rs a p p ro c h e s des n o m b re s s u iv a n t :
Thmes mathmatiques 127
102 \/2 = 22
>/7= lo i y ^ =2 i
\/\/7o = lo i V v ^ =2 i
10 254 1,000 000 000 000 000 127 819 149 320 032 35
1+iZ
2 i^ ^ 1,000 000 000 000 000 038 477 397 965 583 10
^ N/ ^
1+^
7
O r o n c h e rc h e d te rm in e r x = lo g ( 2 ) m a is x = lo g ( 2 ) 1 0 ^ = 2.
D a p r s les c a lc u ls de B r ig g s :
In [ 1 ] : 3847739796558310 / 12781914932003235
O u t i l ] : 0.30102999566398114
tH
log(3) - 0,477 121 254 719 662 44 log(7) 0,845 098 040 014 256 7
ai
> 2 .3 .4 M t h o d e d e s d if f re n c e s d e N e w t o n e t a p p lic a t io n a u c a lc u l d e s lo g a r it h m e s
CL
O
U O n c o n n a t m a in te n a n t q u e lq u e s v a le u rs d u lo g a rith m e d c im a l et l o n v o u d ra it c o n n a tre
des v a le u rs in te rm d ia ire s . N o u s a llo n s p o u r c e la p ro c d e r p a r in te rp o la tio n : ta n t d o n n e s
q u a tre v a le u rs, n o u s a llo n s c h e rc h e r u n p o ly n m e P de degr 3 tel q ue P (x ) = lo g (x ) p o u r ces
4 v a le u rs.
P o u r c e la , n o u s a llo n s u tilis e r la m th o d e p r se n t e p a r Isa a c N e w t o n e n 1676.
A vec des n o ta tio n s m o d e rn e s, p o so n s P ( x ) = a + b x + c x ^ + d x ^ . O n c o n n a t les v a le u rs d u
lo g a rith m e s p o u r 1, 2, 3 et 4.
128 Programmation en Python pour les mathmatiques
X = 1 p{x) = a + b + c + d = y i
X =2 p{x) = a + 2b 4c 3d = y2
X =3 p {x) = a + 3 b + 9 c + 27 d = ys
x =4 p { x ) = fl + 4 ^ 7 + 16c + 6 4 d = y 4
y2- y i = b + 3c + 7 d = A y i
ys - yz = b + 5c + I 9 d = A y2
y 4 ~ y 3 = b + 7 c + 3 7 d = Aya
A y 2 - A y i = 2 c + I 2 d = A ^ yi
A ya - A y 2 = 2 c + I 8 d = A^ya
1 2 1 q
P U ) = y i + ( x - l)A y i + - ( x - l)(x - 2 )A ^ y i + - ( x - l) ( x - 2 ) ( x - 3 ) A ^ y i
2 6
N e w t o n a v a it l h a b it u d e d e r u n i r le s r s u lt a t s d a n s u n s c h m a d e c e tte fo r m e :
yi
A yi
y2 A ^ yi
TJ
O A y2 A*yi
c
rj ys ^ y z
y> A ys
1I
O y4
r\l
avec Ay,- = yj+i - y,-, A^y; = Ay,+i - Ay,- et A^y,- = - ^yi.
DJ O n p e u t g n ra lise r d a u tre s v a le u rs d e n tie rs s u c c e ssifs et u n n o m b re q u e lc o n q u e de
>-
Q. p les.
O
U In te rp o la tio n de N e w t o n p a s s a n t p a r les p o in ts (a , y i ) , (a + 1 , y a ),, ioL + n - 1, y ) :
1 O 1
p(x) = yi + (x-a)Ayi + - ( x - a ) ( x - a - DA^yi + + ----- ( x - a ) - - - ( x - a - ( f l - 2 ) ) A " ^yi
2! (fl-1)!
P o u r des p les q u e lc o n q u e s, on p o u rra se r f re r la s e c tio n 4 page 199.
E t P y t h o n d a n s to u t a ? U n e p re m i re m th o d e la m a in :
Thmes mathmatiques 129
n e w to n , p y
V o ic i u n e m th o d e p lu s g n rale :
n e w to n .p y
def r e d u it _ lis t e ( L ) :
..... . C a lcu le la l i s t e des d i f f r e n c e s 2 2 d'une l i s t e de nbs ......
return [a - b f o r (a ,b ) in z ip ( L [ l:j, L)j
def r d u it( L ) :
""" Renvoie la l i s t e des l i s t e s de d i f f r e n c e s : le t r i a n g l e de Newton
a p p la t i ......
if L == [] :
return L
r e t u r n [L] + r d u i t ( r e d u i t _ l i s t e ( L ) )
def d iff_n e w to n (L ) :
..... . Renvoie le s y l , Dyl, D2yl, e t c . ......
return [ l i s t e [ 0 ] f o r l i s t e in r e d u i t ( L ) ]
def base_newton(alpha, x , n) :
....... Renvoie la l i s t e des v a lu a tio n s des ( x - a ) ( x - a - 1 ) . /n! accumules dans
une l i s t e """
a terme = 1
O base = [terme]
c13
Q f o r k in r a n g e (l,n ) :
y> terme *= ( ( x - alpha - (k - 1 )) / k )
O
(N
b a s e .append(terme)
return base
xz
DI def in t e r p o l_ n e w t o n ( lis t e , alpha, x) :
>-
Q .
....... ren voie l ' v a l u a t i o n du p o ly de Newton en x en p a rta n t de a avec une
O l i s t e de v a le u rs donne ......
U
return sum([ a * b f o r (a ,b ) in z i p ( d i f f _ n e w t o n ( l i s t e ) , base_newton(alpha,
X , l e n ( l i s t e ) ) ) ])
def l i s t e _ l o g _ e n t i e r s ( a , b ) :
..... . ren voie la l i s t e des logarithm es dcimaux des e n t i e r s de a b i n c l u s ......
return [m ath.lo g lG (k) f o r k in range(a, b + 1)]
130 Programmation en Python pour les mathmatiques
O u til]: 1 (1 .0 , 0 . 0 ) , (2 .7 5 , 0.44077626292584499),
(1 .2 5 , 0.091005689059948658), (3 .0 , 0.47712125471966244),
(1 .5 , 0.17074397829308552), (3 .2 5 , 0.51026921386051849),
(1 .7 5 , 0.24036777729567488), (3 .5 , 0.54137304994467772),
(2 .0 , 0.3010299956639812), (3 .7 5 , 0.5715856725684042),
(2 .2 5 , 0.35388354299426877), (4 .0 , 0.60205999132796229)]
(2 .5 , 0.4000813288828019),
0 u t[2 ]: [ ( 4 4 .0 , 0 . 0 ) , (4 6 .2 5 , -3.8808622981889584e-lO),
(4 4 .2 5 , -1.4762764344311563e-09), (4 6 .5 , - 5 . 8871596486653743e-10),
(4 4 .5 , -1.4248640O45622O96e-09), (4 6 .7 5 , -4.70090188997573936-10),
(4 4 .7 5 , - 7 . 4078276846023527e-10), (4 7 .0 , 0 .0 ),
(4 5 .0 , 0 .0 ), (4 7 .2 5 , 7.07972347413488026-10),
(4 5 .2 5 , 4.83041828758246O8e-lO), (4 7 .5 , 1.3494656503354463e-09),
(4 5 .5 , 5.99479799134883256-10), (4 7 .7 5 , 1.3855363523163O78e-09),
(4 5 .7 5 , 3 . 9161784926022847e-1 0 ), (4 8 .0 , 0 .0 ) ]
(4 6 .0 , 0 .0 ),
Le rre u r c o m m is e est de l o rd re de 10 ^.
2 .3 .5 A lg o r ith m e C O R D I C
TJ
O
c A vec l a p p a ritio n des p re m i re s c a lc u la te u rs le c tro n iq u e s, les p ro g ra m m e u rs d e v a ie n t c o n c i
rj
lie r p r c is io n et c o n o m ie de m m o ire . p a rtir de 1956, l a rm e de l a ir des ta ts-U n is v o u
JD
tH lu t a m lio re r le syst m e de n a v ig a tio n e m b a rq u des b o m b a rd ie rs B -5 8 . C est a in s i q ue Ja c k
O
rs]
E. V O LD E R m it au p o in t l a lg o rith m e C O R D IC (p o u r C o o rd in a te R o ta tio n D ig ita l C o m p u te r)
(S) p o u r c a lc u le r ra p id e m e n t des lig n e s trig o n o m triq u e s. Il fu t e n su ite re p ris d an s des d o m a in e s
ai p lu s p a c ifiq u e s , n o ta m m e n t d a n s la p ro g ra m m a tio n des c a lc u la tric e s sc ie n tifiq u e s p o u r c a l
> c u le r n o n se u le m e n t des fo n c tio n s trig o n o m triq u e s m a is a u ssi des lo g a rith m e s c o m m e le
CL
O m o n tra Jo h n W a l t h e r en 1971.
U
def d ic _ lo g (n ) :
die = { x : l o g ( l + 1 0 * * ( - x ) ) f o r x in ra n g e (n + l)}
d i c [ - l ] = log(10)
r e t u r n (d ic )
P a r e x e m p le :
A in s i, D [2 ] re n vo ie l n ( l + 10 ^).
O n u tilis e e n su ite le th o r m e s u iv a n t [p o u r u n e d m o n stra tio n v o ir B o p 07 ]) :
a) 0 ^ ii ^ 10;
b) p o u r to u t e n tie r p o s itif N :
( A
X n 1 + 10 "M K I O ^ X 1+ 1 0 -
^ ) ^i-0 /
N .
ce q u i p e rm e t de m o n tre r, en p o sa n t = In (lO ) - ^ n/ In 1 -h 10 M :
i=0 ^
T h o r m e 3 .4 . P o u r to u t e n tie r p o s itif N , il existe u n e su ite d e n tie rs p o sitifs ^ 10 tels que
yN so it u n e v a le u r a p p ro c h e de ln (x ) 10 ^ p rs.
a
O C e la d o n n e , a ve c P y t h o n :
c
U
def c o rd ic (x ,N ) :
JD
tH
O D = d ic-lo g (N )
CM
y = D [ - l]
(y) f o r i in range(N+1) :
xz a = 1 + 1 0 **(- i)
ai
> w h ile x*a <= 10:
CL
O X *= a
U
y -= D [ i]
return y
P a r e xe m p le , c o m p a ro n s ce q ue d o n n e c o r d ic a vec ce q ue le lo g de P y t h o n re n vo ie :
132 Programmation en Python pour les mathmatiques
In [ 1 ] : c o rd ic (3 .1 9 5 7 ,1 5 ) In [ 2 ] : lo g (3 .1 9 57 )
O u t [ l ] : 1.1618061561640456 0 u t [ 2 ] : 1.1618061561640467
d e f sommel(n) :
S = 0
fo r in r a n g e (l,n + l) :
S += 1.0 /
return S
O n o b tie n t :
In [ 1 ] : sommel(100000)
Out[ 1 ] : 12.090146129863335
sage: d e f sommel(n) :
5 =0
fo r in ra n g e ( l,n + l) :
S += 1 /
return S
sage: sommel(100000). n (64)
*a
O 12.0901461298634279
c
D
C e nest p as to u t fa it p a re il. A lle z , e n co re u n e id e sa u g re n u e ! C a lc u lo n s la so m m e d a n s
O l a u tre se n s : de 100 000 ju s q u 1...
d e f somme2(n) :
xz
5 =0
CTI fo r in r a n g e ( n , 0 , -1) :
>- 5 += 1.0 /
Q.
O
U return 5
qui donne :
In [2 2 ]: somme2(100000)
0 u t [ 2 2 j: 12.090146129863408
In [ 1 4 ] : (1 + le -1 6 ) + le -1 6 In [ 1 5 ] : 1 + ( le -1 6 + le -16 )
0 u t[14 j: 1.0 0 ut[15]: 1.00 0 0 0 0 00 0 0 0 0 0 0 02
In [ 1 ] : (1.0 0 0 0 0 0 0 1 * l e - 1 5 ) * le l5 In [ 2 ] : 1.0 0 0 0 0 0 01 * ( l e - 1 5 * l e l 5 )
O ut[ 1 ] : 1.0 0 0 0 0 0 0 10 0 0 0 0 0 0 2 0 u t[2]: 1 .0 0 0 0 0 0 0 1
In [3 ]: l e l 5 * ( l e - 1 6 + 1) In [4 ]: ( le l5 * le -16 ) + ( le l5 * 1)
O ut[3 ]: 10 0 0 00 0 000000000.0 O ut[4 ]: 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .1
2 .4 .2 C o m m e n t la m a c h i n e f a i t - e l l e d e s a d d i t i o n s ?
In [ 9 ] : 2 .**5 3 In [1 2 ]: 2 .* *5 3 + 3
0 u t [ 9 ] : 9007199254740992.0 0 u t [ 1 2 ] : 9007199254740996.0
TJ
O
c
rj Il fa u t a v o ir en tte q ue la m a c h in e n e tra v a ille p as d a n s U m a is s u r u n e n se m b le fin i o o n
Q p e u t p a rle r de s u c c e s se u r et de p r d ce sse u r. N o u s tra v a ille ro n s d a n s l e n se m b le le p lu s c o m
O m u n , V 6 4 , c e lu i des b in a ry 6 4 c est- -d ire des n o m b re s e n b ase 2 q u i s c riv e n t s u r 64 b its se lo n
rs]
le d co u p ag e s u iv a n t :
(S)
u = i-l xl,fx2^^
0 10000110100 0000000000000000000000000000000000000000000000000000
0 01111111111 0000000000000000000000000000000000000000000000000000
53
1 = 0,000...000 1 x 2
'---- V---- '
52bits
C e la d o n n e
1,0000000000000000000000000000000000000000000000000000I
0,0000000000000000000000000000000000000000000000000000|1
1,0000000000000000000000000000000000000000000000000000I1
O n p e u t illu s tre r p a r le s c h m a s u iv a n t :
TJ
O 253 2^3 + 2
c
rj
tH 0.1 ulp
O 0.1 ulp
2^3 + 1
ai
'^
1
>
CL O n n e p e u t p as m e ttre le d e rn ie r 1 d a n s la p se u d o -m a n tisse q u i n a que 52 cases. L e n o m b re
O
U o b te n u n est d o n c p as u n flo tta n t : il v a fa llo ir l a rro n d ir. L a n o rm e I E E E 754 p ro p o se q u a tre
m o d es d a rro n d i. L e m o d e p a r d fau t est l a rro n d i a u p lu s p ro c h e (R N : R o u n d to th e N e a re st).
E n cas d q u id ista n c e , o n c h o is it le flo tta n t d o n t la p se u d o -m a n tisse se te rm in e p a r u n 0.
11 n y a d o n c p as de n o m b re V F en tre 2^^ et 2^^ -1- 2 c o m m e illu s tr s u r le sch m a . LU L P est
l c a rt en tre d e u x V F su c c e s sifs q u i v a rie se lo n l o rd re de g ra n d e u r du n o m b re . U L P sig n ifie
U n i t i n t h e L a s t P l a c e : l u n it en d e rn i re p o sitio n .
Si V est u n VF, en tre v et so n su c c e sse u r, il n y a p as de V F !
Thmes mathmatiques 135
52bits 52bits
p a r u n 0:2^ ^ .
RN(2^^ + 1) = 2^^
V o u s p o u v e z alo rs co m p re n d re p o u rq u o i :
RN(2^^ + 3) = 2^^+4
2 .4 .3 L e s s o m m e s c o m p e n s e s de d e u x flo tta n ts
X
T h o r m e 3 .5 (L e m m e de S t e r b e n z (1 9 7 3 )). S o it ( x ,y ) e v rifia n t ^ y ^ 2 x . O n a
x e y = x -y
TJ 5 X 0 y
O
c
rj ;< 50 X
d *- y e y v
tH
O
Retourner {s,d)
XI A lo rs x + y = s + d avec 5 = x y e t i i = e r r ( x y ) . D e p lu s 5 et ne se c h e v a u c h e n t p as.
OJ
>-
Q. L a lig n e 1 d o n n e 5 = x + y + e r r ( x y ) . D e p lu s, c o m m e |x | ^ |y |, c est x q u i gagne d o n c s et
O
U X o n t le m m e sig ne. L a lig n e 2 c a lc u le u n y v irtu e l {y ^ ) q u i v a u t 5 x : o n a im e ra it b ie n q ue a
fa sse s - x c est- -d ire y -i-e rr(x y ). E n fin la lig n e 3 c a lc u le y e y ^ : on a im e ra it b ie n a u ssi que a
fasse y - y v c est- -d ire - e r r ( x y ) c o m m e a on r c u p re ra it e x a c te m e n t l e rre u r c o m m ise .
E n p lu s, c o m m e d - - e r r ( x y ) =, on a |r/| ^ ^ u lp (s ) d o n c s e t d n e se c h e v a u c h e n t p as d ans
le u r so m m e . O n a im e ra it b ie n , o n a im e ra it b ie n ...E n fa it to u t s a rran g e c a r n o u s a llo n s p o u v o ir
u tilis e r le le m m e de S te r b e n z .
Il s u ffit de d is tin g u e r d e u x cas :
136 Programmation en Python pour les mathmatiques
O n illu s tre ra e n co re m ie u x le p ro b l m e p a r ce s c h m a :
X X i a :2
T l yz
=s ^1 ^ 2 +y i y z est p erd u
-X yi
-y yz
O n r cu p re T e rre u r - y 2 .
A in s i, X + y = 5 + i i se lit :
X X i J:2
'------------------------------- \
+y yi T2
= 5 X i X2 + y z y 2 est p e rd u
-\-d T2
O n r c u p re T e rre u r y 2
2 .4 .4 L e s s o m m e s c o m p e n s e s d un n o m b re q u e lc o n q u e d e flo tt a n ts
(S) Xi X2 ^3 X4
CT
> Xo
CL
O
U
e\ ^2 ^3 ^4
>53 -(254-2)
253-1
-1
En P y th o n :
et o n o b tie n t :
In [ 1 ] : P i c h a t ( [ 1 .0 / k f o r k i n r a n g e ( 1,1 0 0 00 1 )])
Out[ 1 ] : 12.090146129863427
2 .4 .5 L a m a c h in e c o m p te en b ase 2
O
a
c13
Q D te rm in o n s l c ritu re de 0 ,1 en b ase 2. C e n o m b re est gal 1/10 en base 10 c est- -d ire
y> 1/1010 en b ase 2. P o so n s la d iv is io n :
O
rsl
(y)
1010
4-J
ai 10 0,00011
>-
CL
100
O 1000
U
10000
1010
1100
1010
10
138 Programmation en Python pour les mathmatiques
In [1] p e t it s 2 b i t s ( 0 . 12 5 ,5 0 )
0 u t[l] 0:001'
I n [2] p e t it s 2 b i t s ( 0 . 1,5 0 )
0 ut[2] 0:00011001100110011001100110011001100110011001100110'
Il fa u d ra d o n c v ite r de d iv is e r des n o m b re s p a r des p u is sa n c e s de 10 et p r f re r les p u is sa n c e s
de 2.
2 .4 .6 C a lc u l d e lim it e s - In d t e r m in a t io n s
-O O b se rv o n s :
O
c
n
In [1] X = le50O I n [5] 4 - X
JD 0 ut[5] -in f
tH
O
rsj I n [2] 1 + X I n [6] x**2 -
0 ut[2] in f 0ut[6] nan
I n [3] x**2 I n [7] x**2 -
ai
0ut[3] in f 0 ut[7] F a lse
>
Q. I n [4] 1 / X I n [8] X * (x
O
U 0 ut[4] 0 .0 0ut[8] F a lse
V = (-1 )^ X m X 2'
Thmes mathmatiques 139
; = 0,01007 x2^
0 = 0,1007 x2 ^
O = 1,001 x2"^
C est I n f o r m e n o r m a l e d u n V E O n n o te ra m = 1 , / .
O n ra p p e lle q u o n p e u t gagner de la p la ce en ne s to c k a n t p as le signe de l e x p o sa n t : il s u ffit
de le tra n s la te r de - 1
R e p r se n to n s 0 ,7 5 en to y? .
3io - 1
0 ,7 5 io = ^ = I I 2 X 2 " ^ = 1 , IOO 2 X 2
2a^
'10
L e x p o sa n t sto ck e v rifie avec le d calag e :
e-(2^"^-l)=E = - lo e = - l+ 3 = 2 = IO2
A in s i :
a
O
N o u s v e n o n s de v o ir q ue l e x p o sa n t E , q u i est u n e n tie r sig n , est sto ck s u r # E b its so u s la
c fo rm e e = E + - 1.
=3
Q C o m m e e est u n e n tie r n a tu re l sto ck s u r # E b its, il v a rie en tre emin = 0 et e ^ a x = 2^^ - 1.
KD
1-H P a r e xe m p le , en toy?, # E = 3 d o n c ^ = 000 et e ^ a x = 111 = 1000 - 1.
O
rsl
C E P E N D A N T les v a le u rs e xtr m e s de E so n t r se rv e s p o u r des cas s p cia u x.
C e la d o n n e :
03
>. Emin = (emin - + 1) + 1 = 0 - 2=*-' + 1+ 1= -2
CL
O
U Emax = + l) - 1 = ( 2 ^ - 1) -2 = ^ - + 1 - 1 = 7 - 4 + 1 - 1 = 3
- o n ne p e u t p as re p r se n te r zro so u s fo rm e n o rm a le ;
- des n o m b re s d u typ e 0 .0 0 0 ...0 0 1 1 x 2^ = 1.1 x 2 ^^^+h n e so n t p as re p r se n ta b le s so us
#E
fo rm e n o rm a le c a r il fa u d ra it u n e x p o sa n t p lu s p e tit q ue Emin-
140 Programmation en Python pour les mathmatiques
A lo rs jc^ p u is y ^ p u is x ^ -I- y ^ se ra ie n t re m p la c s p a r 1 ,1 1 1 x2 ^
1./2
O n a u ra it d o n c N = ( l , 111 x 2^^) a rro n d i 1,010 x 2^ ce q u i est d ra m a tiq u e m e n t fa u x.
L a n o rm e in tro d u it d o n c d e u x in fin is co d s en t o y 7 :
-boo : -o o :
So it, p lu s g n ra le m e n t, e = ^max e i f = 0.
O n re tro u v e a lo rs les lim ite s h a b itu e lle s vu e s a u lyc e :
E n fin la n o rm e in tro d u it le NaN (c o m m e d a n s N o t a N u m b e r ) d a n s les cas o le c a lc u l d e m a n d
est in d fin i .
U n NaN n est p as c o m p a ra b le . T rie r u n ta b le a u c o m p o rta n t u n NaN n e pose d o n c p as de p ro
b l m e .
(S)
ai R e p re n o n s n os fo rm e s in d te rm in e s
>-
Q.
O In [7 1 ]: X = le500 Out [7 2 ]: nan
U
In [7 3 ]: x * ( x - 1)
In [7 2 ]: x**2 - X Out [7 3 ]: i n f
e = 0 ...0 / = 0 - v = i-lV xO .O
e = 0 ...0 f^ O - V - (-1 )^ X0 . / X
f = 0 ^ V - (-1 )^ XO
O
e = l..A f9^0 - N aN
0 . . . 0 < e < 1 ...1 f ^ O - V = ( - 1 ) '^ X1 ./ X
In [50 ]: f ( le S O O )
O ut[50 ]: nan
In [ 5 1 ] : f(le lO O )
O O ut[ 5 1 ] : le + 5 0
O
c
n
Q In [52]: f ( le l5 0 )
JD
tH
O
CM O v e rflo w E rro r T r a c e b a c k (most r e c e n t c a l l l a s t )
(y) < i p y t h o n - i n p u t - 5 2 - 7 9 7 7 5 d 8 5 f 3 1 a > i n < m o d u le > ()
XI -------- > 1 f ( l e l 5 0 )
ai
>
Cl < i p y t h o n - i n p u t - 4 9 - b a 3 d b a 7 9 9 3 9 6 > i n < la m b d a > (x )
O
U -------- > 1 f =lam bda x : x ** 2 / s q r t ( x * * 3 + 1 )
b) C o m m e n t v ite r le p re m ie r N aN ?
2 .4 .7 T r o p d e p r c i s i o n t u e la p r c i s i o n
d e f d e r i v ( f , h ,x ) :
r e t u r n ( f ( x + h) - f ( x ) ) / h
E t p o u r la d riv e :
def d e r iv n (f,x ,h ,n ) :
i f n == 0:
return f(x )
e ls e :
r e t u r n d e r iv n ( lam bda x : d e r i v ( f , h , x ) , x , h , n - l )
In [ 1 ] : [ d e r iv n (lam bda x : x * * 4 , 1 , l e - 7 ,k ) f o r k i n r a n g e ( 5 ) ]
0 u t[l]:
[1,
4.000000501855902,
12.012613126444194,
-222044.6049250313,
2220446049250.313]
P re n o n s a lo rs u n h p lu s p e tit p o u r tre p lu s p r c is :
In [ 2 ] : [ d e r iv n (lam bda x : x * * 4 , 1 , l e - 8 ,k ) f o r k i n r a n g e ( 5 ) j
Out[ 2 ] : [1, 4.000000042303498, 11.102230246251565, 0 .0 , 2 . 22O446O49250313e+16]
a In s is to n s :
O
c
D In [ 3 ] : [ d e r iv n (lam bda x : x * * 4 , 1 , l e - 9 ,k ) f o r k i n r a n g e ( 5 ) ]
In [ 4 ] : [ d e r iv n (lam bda x : x * * 4 , 1 , l e - 3 ,k ) f o r k i n r a n g e ( 6 ) ]
ai 0 u t[4 ]:
> [1,
CL
O 4.006004000999486,
U
12.024014000244776,
24.03599941303014,
24.001245435556484,
-2.4424906541753444]
In [ 7 ] : [ d e r iv n (lam b da x : x * * 4 , 1 , 2 * * - 2 0 ,k ) f o r k i n r a n g e ( 6 ) ]
0 u t[7 ]: [1, 4.000005722045898, 1 2 .0 , 0 .0 , 268435456.0, -844424930131968.0]
2 .4 .8 D e s s u je t s d e B a c d a n g e r e u x
ln = dx
Jo
O n o b tie n t p a r in t g ra tio n p a r p a rtie s :
1 n+1 1
In+2 2^ 2
E n c lasse , il est s o u v e n t d e m a n d de d e v in e r le c o m p o rte m e n t de la su ite en o b se rv a n t les
p re m ie rs te rm e s :
d e f bac(n) :
i f n == 1:
r e t u r n 0 .5 * ( e x p ( l . ) - 1 . )
r e t u r n (0 .5 * ( e x p ( l . ) - (n - 1) * bac(n - 2 ) ) )
d o n c la su ite o s c ille en tre -i-oo et - o o ... p o u rta n t la su ite est d c ro issa n te et v a le u rs p o sitiv e s
si l o n tu d ie la d fin itio n de la su ite so u s fo rm e in t g ra le ;-)
144 Programmation en Python pour les mathmatiques
2.4.9 Prolongements
Pour explorer plus avant Tarithmtique des flottants et des intervalles, des rfrences ont t
donnes en bibliographie :
- des pages personnelles trs riches : [Kahl4], [dD14], [Goul4] ;
- un article de rfrence sur le mauvais traitement des flottants par Java : [KD98] ;
- les articles historiques introduisant les thormes cits dans ce chapitre : [Ste73], [Pic72] ;
- La rfrence pour comprendre larithmtique des flottants : [MBdD^ 10] ;
- un article qui rsume lessentiel : [Gol91].
Une premire ide est de construire les complexes comme des couples de rels. On dfinit
pour cela une classe la plus basique possible avec un oprateur alg pour afficher la forme
algbrique :
class cplx:
def _i n i t _( s e l f , pa rt ie _ re el le ,p a r ti e _i m a g in a ir e) :
s e l f . r = p a r t i e _ r e e ll e
s e l f . i = partie_imaginaire
def a l g ( s e l f ) :
return s t r ( s e l f . r) + + '+ str(self.i) + ' ( i ) '
Par exemple :
In [1] Z = cplx(3,2)
In [2] z.algO
0ut[ ] 2 3 + 2(i)'
On peut alors dfinir addition et multiplication en utilisant les oprateurs de base de Pyth on .
On pourrait, si ncessaire, ne travailler quavec les rationnels dfinis dans une section prc
a
O dente et utiliser alors les oprateurs spcifiques qui avaient t introduits.
c
D
def cso m( zl, z ) : 2
kD return c p l x ( z l . r + z . r, z l . i + z .i )
2 2
O def c p r o d ( z l , z ) : 2
rs]
On dfinit le conjugu :
def conj(z) :
return c p l x ( z . r , z .i.
Par exemple :
Thmes mathmatiques 145
In [1] Z = cplx(3,4)
In [2] c p r o d ( z ,c o n ] ( z ) ) . a l g ( )
0ut[ ] 2 25 + 0 ( i ) '
def cmod(z) :
return s q r t ( z . r * z . r + z . i * z . i )
On prcise P y th o n quon prend la partie relle de z-~z mme si lon sait que la partie imagi
naire est nulle pour pouvoir utiliser sq rt sur un objet de type rel et non pas complexe.
On peut galement dfinir linverse dun complexe non nul et donc une division :
def cinv(z) :
i f z == c p l x ( , ) : 0 0
ra is e ZeroDivisionError
return c p l x ( z . r / (cmod(z))** , - z . i / (cmod(z)** ) )
2 2
def c d i v ( z l , z ) :
2
return c p r o d ( z l , i n v ( z ) ) 2
Par exemple :
Il y a cependant quelques petits problmes avec le calcul des inverses ds quon sapproche
a
trop de zro :
O
c
13
In [1] z = cp lx(l,le- ) 8 In [3]: c p r o d ( z , c i n v ( z ) ) . a l g ( )
xz
DI
>- 2.5.2 Les c o m p le x e s c o m m e matri ces
Q.
O
U Notons U = (q j) et J = ( -Q^). On vrifie aisment que = -U et = U.
On considre lensemble des matrices obtenues par combinaisons linaires de U et J.
Elles sont de la forme Z = aU + b] = [^ avec a et b des rels. Appelons ces matrices cellules
et Gleur ensemble.
On peut demander aux lves de comparer (2 et C.
On peut alors dfinir les oprations sur les nombres complexes partir des oprations sur les
matrices.
146 Programmation en Python pour les mathmatiques
Nous reprendrons les notations et les oprations matricielles introduites la section 1 page 78
pour dfinir une nouvelle classe de nombres et les oprations introduites dans la section pr
cdente partir des oprations sur les matrices :
c la s s cplx:
def _i n i t _( s e lf , p a r t i e _ r e e l l e , p a r t i e _ i m a g i n a i r e ) :
s e l f . r = partie_reelle
s e l f . i = partie_imaginaire
def m c p lx ( s e lf ) :
return (U * s e l f . r ) + (J * s e l f . i )
def a l g ( s e l f ) :
return s t r ( s e l f [ ] [ ] ) + + + s t r ( s e l f [ ] [ ] ) + ' ( i )
0 0 1 0
def mconj(self) :
return U * s e l f . r + J * - s e l f . i
Par exemple :
0u t [ ] : -1 -7
2 - 1 1
7 -1 In [5]: alg(mconj(Z2))
a
In [3]: (ZI * Z 2 ).a lg () Out[5]: + -l(i)'
1
O 0ut[3] : -1 + 7 ( i )
c
D
kD
O
rs]
Exercice 44. (Multiplication du paysan russe) Voici ce quapprenaient les petits sovitiques
pour multiplier deux entiers. Une variante de cet algorithme a t retrouve sur le papyrus de
Rhind datant de 1650 av. J.-C, le scribe A h m e s affirmant que cet algorithme tait lpoque
vieux de 350 ans. 11a survcu en Europe occidentale jusquaux travaux de F ib o n a c c i .
Thmes mathmatiques 147
def m u l _ d i v i s ( s e l f , other) :
.... A l g o dichotom ique n a f de m u l t i p l i c a t i o n .....
opl, op = s e lf . n o r m ( ) , o t h e r . norm()
2
i f o p l . s i g n e O == : 1
return - ( ( -opl).mul_divis(op ) ) 2
i f op .signe() == :
2 1
return - (opl.mul_divis(-op ) ) 2
i f long <= : 2
ml = long 1
pl = xl. m u l_ d iv is (y ) 0
p 2 = x .mul_divis(yl)
0
p3 = x l.m ul _d iv is (y i)
z0 = B i t s ( p 0 . b i t s + fo r i in range(0, ml 1)])
[ 0
z l = B i t s ( ( p l + p 2 ) . b i t s + [0 f o r i in range(0, ml)])
148 Programmation en Python pour les mathmatiques
z2 = p3
return z 0 + zl + z 2
Exercice 46. (Le Pape Grgoire et les fractions continues) Voici lnonc dun problme pro
pos par Ernst Hairer et Gerhard WANNER[voir HWOO, p. 78] :
La longueur dune anne astronomique est de (Euler 1748) :
365 jours 5 heures 4855
Calculer le dveloppement de 5 heures 4855 (mesurs en jours) en une fraction continue
et chercher les rduites correspondantes. Le Pape Grgoire XIll aurait apprci vos prcieux
conseils pour la rforme de son calendrier, mme si la prcision retenue est largement suffi
sante.
(y) i f (a + . ) - a !=
1 0 1 . :
0 i f (a + b) - a == b:
xz return a return b
DI
e ls e : e ls e :
>-
Q.
O return b a s e l ( 2 . 0 * a) return base (a, b +
2 1 . )
0
Regardons la premire boucle. On y construit une suite {ai) vrifiant pour tout naturel i ai+\ -
2i avec q = 1.0. Une rcurrence immdiate dmontre que ai - 2' pour tout entier naturel i
et notre boucle ne sarrte jamais et pourtant :
Thmes mathmatiques 149
3 Le n o m b r e tt
2 iih n ^ 2 ^ 27tr
cest--dire :
1 1
Thfi
T
a
O
c
13
Q
'D
O
(N
Notons AB un ct du polygone rgulier de 2" cts de primtre 2 et de centre O. Comme
XI
EF = ^ alors EF est le ct du polygone suivant.
D3 Ainsi
>- OD = r, OG =hn, OE = r+i, OC = h+i
Q.
O
U
Comme OC = alors
+ hfi
h n ., =
Ensuite, ODE est rectangle en E, on peut faire dmontrer en 2^ que OE^ = OH x OD et donc
que
^n+l \/ ^n^n+1
150 Programmation en Python pour les mathmatiques
On peut donc dfinir une fonction qui dterminera partir de quand deux flottants seront
considrs comme gaux par le systme :
def pseudo_egal_float(a, b) :
return abs(a - b) <= ( f l o a t _ i n f o . e p s i l o n * min(abs(a), abs(b)))
2 . 220446049250313e-16
> 10-i-10*float_inf O . e p s i l o n - 10
1 . 7763568394002505e-15
xz
h = (r-i-h ) / 2
DI = s q r t ( r*h)
>- compteur -i-=
Q. 1
O return / r , / h , /h-l/r,compteur
U 1 1 1
3 . 2 .1 M t h o d e des re ct a ng le s
Il semble falloir 2^^ itrations pour obtenir trois bonnes dcimales de tt.
Pour plus de prcision, on pourrait tre tent de prendre un plus petit arc de cercle, disons
entre ^ et en utilisant encore / . En effet, la fonction ntant pas drivable en 1, on a un peu
peur que cela cre des perturbations. Et intuitivement, on se dit quen limitant lintervalle
dintgration, on devrait limiter lampleur de lapproximation.
In[ ] fo r in range(15) :
8 0.00014095159728411133
p r i n t (pi - 3.52384727166921150-05
* ( i n t _ t r a p ( f , , l / , **k)
1 2 0 2 2 8.80965402183520-06
- sqrt(3)/8)) 2.20241574577784150-06
5.5060407389007080-07
0.14159265358979312 1.37651026577145790-07
0.035893249610888134 3.44127588647324960-08
0.009008728472729821 8.6031821666665560-09
0.0022544939728321722 2.15078577170402240-09
0.0005637697200326919 5.377085443569740-10
On a utilis des segments de droite horizontaux, des segments de droite obliques...Et si lon
utilisait des segments de parabole : intuitivement, cela colle plus la courbe, cela devrait tre
plus prcis.
3.2.3 M t h o d e de Simps on
a
O
On interpole la courbe par un arc de parabole. On veut que cet arc passe par les points ex
c trmes de la courbe et le point dabscisse le milieu de lintervalle. Pour cela, on va dterminer
Q les Ci tels que :
( a +b
O
/
fix]dx = fia) + ci f
J a
+ c if ib )
*->
xz soit exacte pour f{x) successivement gale 1, x et
DI
>-
Posons h b a et ramenons-nous au cas a = 0. On obtient le systme suivant :
Q.
O
U co + Cl -b C2 = /
O + 2 c2 = h
Cl - 4 2 =
alors co = C2 = I et Cl =
b-a (a + b
/(x)dx = f{a)+4f + f{b)
f
Thmes mathmatiques 153
t --= dt
1
return S
fo r k in range( ) : 1 0
On distingue mieux cette fois la hirarchie des mthodes selon leur efficacit.
Nous navons pas le choix : il est temps prsent dinvoquer les mathmatiques pour prciser
un peu ces observations.
En fait, ces trois mthodes sont des cas particuliers dune mme mthode : on utilise une
interpolation polynomiale de la fonction / de degr 0 pour les rectangles, de degr 1 pour les
trapzes et de degr 2 pour Simpson.
On peut galement voir la mthode de Simpson comme le premier pas de lacclration de
convergence de Romberg de la mthode des trapzes...mais bon, laissons cela pour plus tard.
Nous allons nous contenter dans un premier temps dtudier lerreur commise par la m
thode des trapzes. Nous avons juste besoin du thorme de Rolle qui peut tre tudi en
Terminale titre dexercice.
On considre une fonction / de classe sur un intervalle [a, b] valeurs relles. On considre
une subdivision rgulire de [a, b] et on pose :
b-a
Xj = a + j
N
o N dsigne le nombre dintervalles. On cherche une fonction polynomiale P de degr au
plus 1 telle que P{a) = f{a) et P() = f{b).
Lintgrale de P sur [a, b] vaut J = (fi -
Soit Xe] a, b[. On introduit la fonction dfinie sur [a, b] par :
gxit) = f{t)-Fit) + k A t - a ) { b - t )
o le rel kx est choisi tel que gx(x) = 0.
La fonction gx est de classe et sannule en a, x et b donc on peut appliquer le thorme de
Rolle sur ]a,x[ et ]x,b[ et sannule donc sur chacun de ces intervalle. On applique alors
une nouvelle fois le thorme de Rolle g'^ sur ]a, b[ et g sannule donc au moins une fois
en un rel Cx de ]a,b[.
f 'iC x )
On pose kx = - . On obtient finalement que pour tout x e]a, b[, il existe Cx e]a,b[ tel que :
fiCx)
fix) -P(x) = - {x - a){b- x)
a 2
O On peut videmment inclure les bornes de lintervalle.
c
13
Soit M2 un majorant de |/" | sur [a,b]. On obtient donc, par intgration de lgalit prc
'JD
dente :
O
(N
M2 Q
CT
s_
li fix) dx - J ^ - i b - a)^
12
>.
CL
puis, par application de cette ingalit sur chaque intervalle [Xj,Xj+i] :
O
U
/(a)
N-1
avec Jn = T
On obtient donc que quand N est multipli par 2, le majorant de lerreur est divis par 4.
Cela correspond en effet ce que nous observons avec P y t h o n :
Thmes mathmatiques 155
0.035893249610888134 0.03539816339744828
0.009008728472729821 0.008973312402722033
0.0022544939728321722 0.0022521821181824553
0.0005637697200326919 0.0005636234932080431
0.00014095159728411133 0.00014094243000817297
3.5238472716692115e-05 3.5237899321027836-05
8.8096540218352e-06 8.8096181791730296-06
2.20241574577784156-06 2.20241350545886-06
5.5060407389007086-07 5.5060393644446046-07
1.37651026577145796-07 1.3765101847251776-07
3.44127588647324966-08 3.44127566442864466-08
8.6031821666665566-09 8.6031897161831246-09
2.15078577170402246-09 2.1507955416666396-09
5.377085443569746-10 5.3769644292600566-10
Dans la colonne de gauche se trouvent les rsultats dj calculs. Dans la colonne de droite,
le rsultat de la ligne i est celui de la ligne / - 1 de la colonne de gauche divis par 4 : Terreur
sur le majorant et sur le calcul lui-mme est bien corrle.
On peut dmontrer de mme quavec la mthode de Simpson, si / est de classe sur [a, b],
alors le majorant de Terreur est
M4 { b - a f
2880 N4
avec M4 un majorant de sur [a, b].
Cette mthode subtile, comme celles aussi de Romberg o u de Gauss, sont efficaces pour des
fonctions rgulires (ici de classe Pour les fonctions plus sauvages, la mthode des
trapzes sera souvent meilleure.
Cette fois, on obtient que quand N est multipli par 2, le majorant de Terreur est divis par 16.
On observe bien le mme phnomne quavec la mthode des trapzes :
TJ
O > fo r k in range(l,9) :
c
rj print(pi-12*(int_simps(f,0 ,l/2,2**k)-sqrt(3)/8), "\t",\
Q
(O ( p i - 1 2 * ( in t _ s im p s ( f ,0 , 1 / 2 ,2 * * ( k - 1 ) ) -sq rt(3)/8))/16)
O
r\i
@ 4.722142667734636-05 4.1257184453358246-05
3.08247286717744376-06 2.9513391673341446-06
OJ 1.94969097755404166-07 1.92654554198590236-07
s_
>. 1.2223035028569036-08 1.2185568609712766-08
CL
O 7.6453066100157236-10 7.6393968928556436-10
U
4.7791104407224346-11 4.7783166312598276-11
2.98872038229092146-12 2.9869440254515216-12
1.84741111297626056-13 1.8679502389318266-13
Pour cela, il faut repenser totalement la faon de calculer et rflchir des algorithmes per
mettant de passer outre la limitation de reprsentation des nombres. Mais ceci est une autre
histoire...
Moralit, comme aurait pu le dire un contemporain franais de Newton, dmonstration ma
thmatique et domination de la machine valent mieux qu'observation et utilisation au petit
bonheur ou encore les mathmatiques ne sont pas uniquement une science exprimentale as
siste par ordinateur^.
Mais a ne va pas nous avancer grand chose puisque pour avoir 15 bonnes dcimales avec
la mthode de Simpson, il nous a fallu dix millions ditrations.
Faisons un petit dtour par lhistoire...
Tout commence peu prs en 1671, quand lcossais James Gregory dcouvre la formule
suivante :
ai
Soit {Un) une suite relle alterne. Si {\Un\) est dcroissante et converge vers 0 alors :
s_
>.
CL
O - ^ Un converge;
U
- 1R1^ IUn+i I o (R) est la suite des restes associs J^Un.
X
2n+3
Arctan (jc) - ^ <
k^O 2k+\ 2/1 + 3
On peut alors utiliser P y t h o n pour dterminer une fonction mini_g reg ( a , d ) avec 0 < a < 1
2n+3
dterminant une valeur de n telle que ^ 10\~d .
pipy
def mini_greg(a,d) :
g e t c o n t e x t ( ) . prec = d
+ 2
n = 1
fd = nd/ad
n += 1
return n
Elle nest pas trs efficace. On peut toutefois remarquer que lingalit quivaut
, 1 d log(2/i + 3)
2+- l o g - > -----------------
n) a n n
Donc pour n grand, le rapport entre le nombre de dcimales cherches et le nombre de termes
ncessaires est de lordre de 2log^.
On peut tablir les formules daddition des tangentes puis montrer que, a et h tant deux rels
tels que ah 7^ 1, on a
, ( a +b
arctan a + arctan b = arctan + 7T
"O V1 - ab,
O
c
=3 avec = 0 si ah < 1, = 1 si ah > 1 et i > 0 et e = - 1 si flh > 1 et a < 0.
Q Seul le premier cas va nous intresser dans ce paragraphe.
y>
O En 1706, langlais John Machin en dduisit la fameuse formule :
r\l
1 1 JT
4 arctan arctan----=
03 5 239 4
>.
Q.
ce qui lui permit dobtenir 100 bonnes dcimales de Ji sans laide daucune machine mais
O avec la formule propose par son voisin cossais.
U
On appelle polynmes de G regory les polynmes G(X) = ^
2fc+l
crivons une fonction g reg ( a , N) qui donne une valeur de Gn (a) :
p i. p y
I def greg(a,N) :
ad = Dcimal!' 1 ' ) / D ec im a l(s tr( a ))
158 Programmation en Python pour les mathmatiques
nd = ad
dd = Decimal( ' 1 ' )
s = nd/dd
fo r k in range(l,N) :
nd *= Decimal(' - 1 ' )*ad*ad
dd += Decimal( ' 2 ' )
s += nd/dd
return s
rap = 2*log(5)/log(10)
N = in t(d/rap)+ l
return 4*(4*greg( 5 , N) - g r e g (239,N))
Pour dautres formules avec des arctangentes, on pourra se rfrer un vieil article de la revue
PLOT [Bri91].
On a not que plus le plus petit dnominateur dune formule la M a c h in sera grand, moins
a
O il faudra ditrations (vous avez plus ou moins suivi ?).
c
13
Q
On veut pouvoir transformer un arctan en un arctan -i-arctan ^ avec, on espre, a et b plus
y> grands que n.
1
I
O
r\i Or, en manipulant la fameuse formule daddition des tangentes :
tan(fl) -ftan(?)
tan(fl + >) =
gi 1 - tan(fl) tan(b)
>.
Q .
O
on dmontre que, sous nos conditions de temprature et de pression, comme dj vu page
U prcdente :
1 1 a +b
arctan -I- arctan = arctan
a h ^ a b -l
puis a :
n{a + b) + 1 = ab
Thmes mathmatiques 159
+1= - n{a + b) + ab
Finalement, la dissection de larctangente de revient chercher a et b tels que :
\ = {a - n){b - ri)
Cest donc un problme de recherche des diviseurs de lentier /7^ + 1.
P y t h o n peut bien sr nous y aider :
p i.p y
def dissec(n) :
N = n*n+l
L = [[1,N],[-1,-N]]
if n % 2 == :
0
L += [[2,N//2],[-2,-N//2]]
e ls e :
f o r k in range{3,N//2,2) :
i f N%k == 0:
L += [[k,N//k],[-k,-N//k]]
fo r j in range( len( L) ) :
i f n o t( -n in L [ j ]) :
p r i n t ( ' Arctan l / , n , ' = Arctan 1 / ' , L [ j ] [0]+n,' + Arctan
1 / ' , L [ j ] [l] + n , e n d = '\ n ')
Par exemple, on a :
TT
= arctan(l)
4
Or
In [225]: d i s s e c ( l )
Arctan 1/ 1 = Arctan 1/ 2 + Arctan 1/ 3
TJ
O Arctan 1/ 1 = Arctan 1/ 3 + Arctan 1/ 2
c
3
donc on en dduit, comme Hutton en 1776 :
k1
D1
O TT 1 1
CM
= arctan - + arctan -
4 2 3
sz
OJ puis, comme :
v_
>- In [226]: dissec(2)
Q .
O
U Arctan 1/ 2 = Arctan 1/ 3 + Arctan 1/ 7
Arctan 1/ 2 = Arctan 1/ I + Arctan 1/ -3
3.3.3 Calculs
On saperoit vite que sous cette forme, nos algorithmes peuvent nous fournir quelques mil
liers de dcimales mais partir de dix mille, il faut commencer tre vraiment patient.
On peut tenter dacclrer un peu les choses en ne relanant pas plusieurs fois g reg.
On peut galement gnraliser la fonction pour ladapter toutes les formules.
p i.p y
def greg(p,C,A) :
rap = 2 * lo g l0 ( A [0 ] )
N = int(p/rap) + 1
s = (-1 )
g e t c o n t e x t ( ) . prec = p -I- 2
ex = [ s * D ec i m a l( s t r( C [j ])) for in range(len(C))
ax = [ D ec im a l( s t r( A [ j])) for in range(len(C))
X = [ cx [ j] / ax[j]**(2*N + 1) for in range(len(C))
kx [ ax [j] * ax[j] for in range(len(C))
S sum(X) / (2*N + ) 1
y
A Quelques explications :
O
CM
(y) - on peut montrer que le rapport entre le nombre de dcimales dsires et le nombre
xz
CTI
de termes de la somme ncessaires est de lordre de 2logio(<^) avec a gal au plus petit
>- dnominateur intervenant dans la formule ;
Q .
O - on rentre les coefficients multiplicateurs dans la liste C (en noubliant pas de les multi
U
plier par 4) ;
- on rentre les dnominateurs dans la liste A;
- on les transforme en Decimal dans ex et ax ;
- on va sommer par ordre dcroissant des puissances ;
- comme on va de 2 en 2 pour les puissances, on multiplie chaque itration par le carr
des X .
Thmes mathmatiques 161
Comparons les formules aprs avoir charg les modules math et time :
A 1 . . J
Alors, pn = ^ est une approximation de tt.
pipy
def brent(n) :
d = Decimal!'2 ' )
a = Decimal!' 1 ' )
u = Decimal!'0 . 5 ' )
s = u
TJ
O b = s* d . s q r t !)
c
3 c, k = a*a - b*b,
1
fo r j in range!n) :
O a, b = !a + b)*u, !a*b).sqrt!)
]
c, k = a*a - b*b, *k
(S) 2
s = s - c*k
gi return d*a*a / s
>.
Q.
O En une seconde, on a presque 6 000 dcimales de et on double le nombre de bonnes dci
U
males chaque itration...
In [242]: PI - brent!15)
0ut[242]: Decimal!'-3.4252257719542 3684791E-6020')
%%cython -a
cimport cython
return P
de = (k * + j)
8 . 0
return nu / de
cdef f l o a t de
D
tH
de = (((k 3) + j) ((k + 1 - n) 2))
O return / de
rM 1 . 0
(y)
x: cdef f l o a t s l ( i n t n):
CTI cdef f l o a t s
>- cdef i n t k
Q.
O
U s = 0 . 0
s = s + 4 . 0 * s l p a r t ( n , k , 1) - 2 . *slpart(n,k,4)
0 - 1 . *slpart(n,k, )
0 5
. *slpart(n,k, )
1 0 6
return s
2. https://fr.wikipedia.org/wiki/Formule_BBP
Thmes mathmatiques 163
cdef f l o a t s
cdef i n t k
s = 0 . 0
. *s p a r t ( n , k , )
1 0 2 6
return s
cdef f l o a t prem_hexa(float r ) :
cdef f l o a t x
X = r - floor(r)
return flo or(16*x)
def pi _ p lo u f fe ( in t n):
cdef f l o a t s
s = sl(n) + s (n) 2
return hex(int(prem_hexa(s)) ) [ :] 2
In [15]: p i _ p lo u ff e (10000000)
0ut[15]: ' ' 8
C63ad456edf5f457a814551875a64cd3099fl69b5fl8a8c73ee0b5e57368f6c79f4bb7a595926aab49ec
03
>.
Q.
O
u
4 P r o b a b ilit s
Remarque. On utilisera dans toute cette section le module numpy. random et non pas le module
random qui est beaucoup plus lent. Attention! Avec le premier, la borne suprieure nest pas
comprise alors quelle lest avec le second.
164 Programmation en Python pour les mathmatiques
def p i e c e ( n ) :
T = []
fo r k in range(n):
X = 0
fo r j in ra nge(3) :
X += randint(0,2)
T.append(X)
return([ (T.count(i) / f l o a t ( n ) ) f o r i in range(0,4) ])
sachant que :
s_ X += randint(1,10) <=
>. 6
CL
O T.append(X)
U
return([ ( T . count(j) / f l o a t (n) ) f o r j in range(0,4) ])
Obtenir au moins une boule blanche est le contraire de nen obtenir aucune :
In [255]: l-boule(lOOOO0O,O)
0ut[255]: 0.992068
TJ
O En effet
C
rj
tH
O 1- 0,9919
10
XI
OJ 4.4 Problme du Duc de Toscane
>-
Q. Cosme 11 de Mdicis (Florence 1590-1621), Duc de Toscane, fut le protecteur de lillustre Gal-
O
U lile (n Pise le 15 fvrier 1564 et mort Florence le 8 janvier 1642) son ancien prcepteur.
Profitant dun moment de rpit du savant entre lcriture dun thorme sur la chute des corps
et la cration de la lunette astronomique, le Grand Duc lui soumet le problme suivant : il a
observ quen lanant trois ds cubiques et en faisant la somme des numros des faces, on
obtient plus souvent 10 que 9, alors quil y a autant de faons dobtenir 9 que 10, savoir six.
Aprs quelques rflexions, Galile rdigea un petit mmoire sur les jeux de hasard en 1620
expliquant le phnomne.
166 Programmation en Python pour les mathmatiques
p ro b a s . p y
def t o sc a n e (n ):
T = n*[0]
fo r k in range(n):
T[k] = randint(1,6) + r a n d i n t ( l , ) + r a n d i n t ( l , )
6 6
nObs = 144000
def pTheo(n):
s = sTheo(n)
return {x: 100*v/len(s) f o r x ,v in Co u nt e r ( s ) .it e m s( )}
TJ
O
c
rj In [ ]: p0bs(3) 15 4.625694444444444,
Q 6
0ut[ ] : 6 16 2.682638888888889,
O {3 0.5027777777777778, 17 1.3597222222222223,
rsj
4 I . 363888888888889, 18 0.49444444444444446}
5 2.7840277777777778,
JZ
DJ 6 4.572916666666667, In [7]: pTheo(3)
s_
>- 7 6.838888888888889, 0ut[7]:
Q .
O 8 9.699305555555556, {3 0.46296296296296297,
U
9 II. 861805555555556, 4 I . 3888888888888888,
10 12.506944444444445, 5 2.7777777777777777,
11 12.460416666666667, 6 4.62962962962963,
12 11.565277777777778, 7 .944444444444445,
6
13 9.696527777777778, 8 9.722222222222221,
14 6.9847222222222225, 9 II. 574074074074074,
Thmes mathmatiques 167
def piece_max(n):
S = n*[l]
fo r in range!n):
s = []
P = [randint(0, 2) fo r z in range(lO)]
P = 0
while P < 9:
j = P + 1
while (P[]l == P[p] and j < 9):
i += 1
s . append(j - p)
P = i
s . so r t ( reve rse=T rue)
S[k] = s[0]
m = sum(5) / n
return 'Sur '+str(n)+' s r i e s de 10 la ncers, la moyenne du nombre maximal
de r s u lt a t s co nscutifs gaux e st '+str(m)
On obtient :
In [286]: piece_max(100000)
0ut[286]: 'Sur 100000 s r i e s de 10 lanc ers, la moyenne du nombre maximal de
r s u lt a t s cons cu tif s gaux est 3.52318'
168 Programmation en Python pour les mathmatiques
- le prsentateur ayant ouvert une porte, le candidat a une chance sur deux de tomber
sur la voiture ;
- Au dpart, le candidat a une probabilit de | de tomber sur la voiture. Ensuite, sil garde
son choix initial, il a toujours la mme probabilit ^ de gagner donc sil change davis,
la probabilit quil gagne est donc 1 - | = |.
Qui a raison ?
p ro b a s. p y
def monty(n):
gagne_sans_changer = 0
gagne_en_changeant = 0
fo r j in range(n):
voit ure = randint( , ) 0 2
choix = randint( , ) 0 2
i f choix == voiture:
ouverte = (voiture + + randint(0,1)) % 3 1
a e ls e :
O
c ouverte = +
0 1- choix - voiture
+ 2
13
Q changement = 0 + 1 - choix - ouverte
+ 2
i f choix == voiture:
O gagne_sans_changer +=
1
- sil conserve son choix initial, la probabilit que le candidat gagne la voiture est :
TJ 1 1 1 1 1
O X I x =
c
rj 3 2 3 2 3
JD
tH
- sil change son choix initial, la probabilit que le candidat gagne la voiture est :
O
CM
1 1 2
(y) - x l + - x l = -
XI
3 3 3
OJ
>- 11 vaut donc mieux pour le candidat changer son choix initial.
Q .
O
U
4.7 Exercice dentranement
Le corrig est disponible sur le site dunod.com partir de la page d'accueil de louvrage.
Exercice 48. (Le livre et la tortue) On rappelle le jeu bien connu : on dispose dun d cu
bique. On le lance. Si un six sort, le livre gagne sinon la tortue avance dune case. La tortue a
gagn lorsquelle a avanc six fois de suite. Quelle est la probabilit que la tortue gagne ?
170 Programmation en Python pour les mathmatiques
5 R e la t io n s b in a ir e s e t g r a p h e s
Avec Pyth on, on peut utiliser galement un dictionnaire qui est un type de variable prsent
(cf le chapitre 1) :
R = { 'a' : s e t ( [ ' a ', ' b 1 ) ,
> l i s t (R) a c b e d
[ a', ' c ' , ' b ' , 'e', ' d '] > f o r U in R:
> len(R) fo r V in R[u]:
5 print u,v
> fo r U in R: aa ab ce cd b a d b
print U
Il faudra garder en tte que laffectation de structures complexes sous P yt h o n est une copie
dadresses : il faudra donc utiliser deepcopy du module copy pour copier un dictionnaire en
profondeur :
> B = R 147845164
> id(B) > C = deepcopy(R)
147845164 > id(C)
> id (R) 149979180
Nous sommes maintenant prts manipuler les relations binaires sur un ensemble.
5.1.3 C o m p os it io n de relations
Le graphe d e S oIRest lensemble des couples (x, y) de E tels quil existe au moins un z dans E
tel que xOlz et zSy.
On appelle aussi cette relation 01 suivi de S .
Voici une dfinition possible sur P y t h o n :
g ra p h e s , p y
def compose(R,S):
..... R s u i v i de 5 .....
C = {} # Le d ic t io n n a ir e de la compose e s t vide au dpart
fo r U in R: # pour chaque sommet u de E
C[u] = s e t ( [ ] ) # U n ' e s t encore en re la t io n avec personne par C
fo r V in R[u]: # pour chaque v t e l que uRv
TJ
O C[u] 1= S[v] # uCw <-> vSw
c
rj return C
JD
tH
O On aura besoin de dfinir sur quel ensemble est dfinie la relation et la relation identit sur
CM
cet ensemble :
(y)
g ra p h e s , p y
XI
DI def ens(R):
> return s e t ( l i s t ( R ) )
CL
O
U
def i d ( E ) :
D = {}
fo r in E: # chaque sommet u v r i f i e uRu
U
D[u] = s e t ( [ u ] )
return D
g ra p h e s .p y
def iter_compo(R,n):
..... R'^n version re c u r s iv e .....
i f n == : 0
On vrifie si une relation est rfiexive, cest--dire que chaque lment est en relation avec
lui-mme :
g ra p h e s .p y
def e s t _ r e f l e x i v e ( R ) :
fo r U in R:
i f not(u in R[u]): # ds qu'on trouve un contre-exemple, on s o r t
return False
return True # s i on n ' e s t pas dj s o r t i c ' e s t que la re la t io n e s t r f l e x i v e
def est_symetrique(R):
fo r U in R:
i f U not in [R[v] f o r V in R[u]]:
return False
return True
def est_antisymetrique(R):
a fo r U in R:
o
c i f U in [R[v] f o r V in R[u] i f v != u ] :
D
Q return False
kD return True
11
O
rs]
Le V != Upermet de ne pas exclure les cas uJlu .
Pour la transitivit, on utilisera le rsultat classique :
gi La relation Ll est transitive si, et seulement si, Jl^^ Q Jl.
>
C
O
l
On notera que linclusion des ensemble se note <= :
U
g ra p h e s .p y
def e s t _ t r a n s i t i v e ( R ) :
R2 = compose(R,R)
fo r U in R2:
i f not(R2[u] <= R[u]):
return False
return True
Thmes mathmatiques 173
On rappelle que la fermeture transitive dune relation est note et est dfinie par
|E|
0^"- = U
k=l
def r_plus(R):
Rp = deepcopy(R)
fo r k in r a n g e ( l , l e n ( R p ) + l ) :
Rk = iter_compo(R,k)
fo r U in Rp:
Rp[u] 1= Rk[u]
return Rp
5.2 Graphes
Les graphes sont tudis en utilisant la programmation oriente objet dans le chapitre consa
cr aux classes (cf page page 236).
Nous tudierons ici dautres algorithmes et sans utiliser de classes.
graphe.
ai On note Ti(r') la distance de la source 5 un sommet v.
> Au dpart, on pose tt(s) = 0 et pour tous les autres sommets du graphe, { ) = + . ti v o o
CL
O
U Lide est que, pour tout sommet v, si passer par un prdcesseur ude u raccourcit la distance,
alors on remplace n{u) par { ) + p{u, v) avec p{u, v) la pondration de larc (u, v).
t i u
Algorithme Bellman
7T(5) = 0
Comme pour les relations, les graphes seront considrs comme des dictionnaires. Dans le
cas qui nous occupe, il sagit de graphes valus : nous les programmerons donc comme des
dictionnaires dont les sommets font rfrence un sous-dictionnaire .
{ 'a ' {b' 4, C: 2 },
' b' {a' : 4, d ' : 5, 'c : 1},
c' { 'a ' : ,
2 b' : 1, d' : , 8
f {'e' : 3, d : 5}}
4
"O > ' c ' in g [ ' a ' ]
O
c T rue
13
Q
y> Voici une traduction quasi directe de lalgorithme en langage Python qui utilise la mthode
11
O
r\l deepcopy:
g ra p h e s , p y
piO = {}
k=1
Thmes mathmatiques 175
while pi != p i : 0
piO = deepcopy(pi)
f o r U in graphe:
f o r V in graphe[u]:
i f pi[v] > pi[u] + g ra ph e[ u ][v ]:
pi[v] = pi[u] + graphe[u][v]
k+=l
return pi
On a utilis la possibilit de calculer avec linfini qui est en fait programm pour tre un
flottant suivant les proprits du calcul dans U. On le note f lo at {' in f ' ).
Rappelons prsent lalgorithme de Dijkstra qui permet lui aussi de dterminer les plus
courts chemins dans un arbre pondr, mais uniquement dans le cas darcs pondrs positi
vement.
Algorithme D ijkstra
Dbut
p i ^ dictionnaire vide
7T[dbut] =0
Visits-^ liste vide
Chane-^ [dbut]
X dbut
Pour tout s de X \{dbut} Faire
n(s) " f-oo
chane-^ a
FinPour
TantQue x fin Faire
Pour V ^ Visits et voisin de x Faire
7t[v] ^m in {ji[i;],7T[x] + p{x, u)}
O FinPour
O
c Extraire un sommet n ^Visits tel que n [ u ] = min{7r[y], y ^Visits}
n
JD x-<U
tH
O VisitsVisits u{n}
CM
FinTantQue
ai Retourner tt
> Fin
CL
O
U
P y t h o n permet de gagner un peu de temps grce des petites particularits de traitement
des dictionnaires. Voici mme une version rcursive de lalgorithme.
Pour trouver la cl correspondant la valeur minimale dun dictionnaire, on utilise une syn
taxe trs pythonesque. Par exemple, pour avoir le voisin le plus proche de 'a :
> min ( g [ ' a ' ], key=g [ ' a ' ]. get )
'c'
176 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
if extrm it == depart:
return [depart] + tra je t
else:
return (affiche_peres(pere, depart, p ere[ex trem ite], [extrem ite] +
t r a je t) )
so m m ets))
"O
O
c
n # s i on a r r iv e la fin , on a f f i c h e la d is ta n c e e t le s p e re s
tJH
D if etap e == fin:
O return d ist[fin ], a f fic h e _ p e r e s ( p e r e ,d e p a r t, f i n , [])
CM
# si c 'e s t la p re m i re v i s i t e , c 'e s t que l' ta p e a c tu e lle e s t le d p a rt : on
(y)
m et d is t[ e ta p e ] 0
x:
gi if len (v isites) == 0 : dist[etape]= 0
>- # on commence t e s t e r le s v o is in s non v i s i t s
Q.
O for voisin in g rap h e[etap e]:
U
if voisin not in v isites:
# la d is ta n c e e s t s o i t la d is ta n c e c a lc u l e prcdem m ent s o i t
l ' i n f i n i
visites.ap p en d (etap e)
# on ch erch e le sommet *non visit*^ le p lu s p ro ch e du d p a rt
p lu s p ro ch e
V
'tD
H n = len(g) # nb de som m ets
retu rn g _ c o l o r , m a x ( g _ c o l o r . v a l u e s ! ))
Lordre dans lequel les sommets sont choisis a-t-il une influence ? Essayer avec un autre ordre
en crant une permutation alatoire des sommets.
On va utiliser m a x (g . v a l u e s ( ) ) qui donne la valeur maximale des valeurs associes aux labels
du dictionnaire g.
178 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
def colo_rand(g):
n = len{g) # nb de som m ets
ch ro m a tiq u e p r o v is o ir e
p la c e
c h i_ p r o v is o ir e
mi = m i n ( d i c _ c o l . k e y s ( )) # le p lu s p e t i t nb c h ro m a tiq u e p r o v is o ir e
c o lo r a tio n p o s s ib le
TJ
O
c
rj
Q
V
tH
D
O
rsj
XI
DJ
>
Q.
O
U
M th o d e s n u m r iq u e s
Sommaire
1 Les nombres en notation scientifique ............................................... 180
2 Rsolution d'quations non linaires.................................................. 182
2.1 Mthode de dichotom ie................................................................................182
2.2 Mthode rgula faisi .............................................................................183
2.3 Mthode du point fixe ................................................................................183
2.4 Mthode de N ew to n ................................................................................184
2.5 Mthode de la s c a n t e ................................................................................185
2.6 Comparatif des diffrentes m th o d e s ........................................................185
3 Rsolution numrique dquations diffrentielles............................... 186
3.1 Position du p r o b l m e ................................................................................... 186
3.2 M t h o d e d ' E u L E R ......................................................................................................................... 1 8 7
xz
DI
>-
Q.
O
U
I L es n o m b re s en n o ta tio n s c ie n tifiq u e
Comme nous y avons dj fait allusion notamment au chapitre 1 , les nombres dcimaux sont
reprsents en Python par une mantisse (cest--dire la partie fractionnaire) et un exposant
(la puissance de 1 0 par laquelle il faut multiplier la mantisse).
Considrons par exemple la reprsentation de en entier et en notation scientifique :
> 2 **1 0 0 , 2 .* * 1 0 0
(1257650600228229401496703205376, 1 .2676506002282294e+30)
Les nombres rels sont reprsents en Python avec le type double prcision de la norme IEEE
754. Comme nous lavons dj mentionn la page 31, les valeurs possibles pour lexposant
sont limits ; approximativement, en de de le nombre est arrondi 0 ; au del de
I qSOS, q y a dpassement de capacit : le nombre est considr comme infini (de valeur i n f ).
> le-324, le-323
(0 .0 , le-323)
> le308, le309
(le+ 308, inf)
II existe galement des limitations pour la mantisse; les flottants sont reprsents avec 15
chiffres significatifs, comme on peut le vrifier laide dune boucle :
> i = 1
> w hile 1. + 10**(-i) > 1 .:
i += 1
1. Noter que la virgule dcimale (comme on dit en franaivS) est en fait un point dans les pays anglo-saxons (et en
informatique).
M th o d e s n u m riq u e s 181
Un nombre rel x sera donc stock en mmoire sous forme arrondie Jevrifiant
Le nombre Zx est alors appel Verreur relative et le nombre 0;^ = xtx Verreur absolue.
Remarquons quavec ces notations, le nombre e est dfini par
, , U ll x l+ y 4x1+ Iy
| z l ^ --------^ ^ r - ^ ^ + e < +1
U +y
On constate notamment que si lon calcule la diffrence de deux nombres trs proches lun
de lautre (si lon calcule x - y , avec | x - y | trs petit devant |x| (et | y | )) la perte de prcision
risque dtre trs importante.
En outre, en calculant lerreur relative de la somme de trois nombres, on peut constater que
laddition des rels nest plus commutative.
Pour un exemple de calcul avec perte vertigineuse de prcision, on reviendra lexemple
donn dans la section 2.5 du chapitre 2.
Pour un examen prcis des questions lies aux calculs numriques approchs, on renvoie
au premier chapitre de [Dem96]. Pour une tude encore plus approfondie, on consultera
[LZ04] 2 .
En conclusion, les problmes darrondis sont prendre en compte ds que lon travaille avec
des nombres virgule flottante. En gnral, pour viter les pertes de prcision, on essayera
TJ
O autant que peut se faire de respecter les rgles suivantes :
c
rj
- viter dadditionner ou de soustraire deux nombres dordres de grandeur trs diff
tH
O rents ;
def zeta(n, p ):
return sum (l/i**p for i in range(l, n+1))
def zeta_reverse(n, p ):
return sum (l/i>K *p for i in range(n, 0, -1))
n, p = 2**18, 4
p rin t("{ : . 1 6 f}".fo rm at(zeta(n , p) - pi**4/90))
p rin t("{ : . 1 6 f}".fo rm at(zeta_ rev erse(n , p) - pi**4/90))
-0.0000000000002764
0.0000000000000002
Pour rsoudre numriquement une quation non linaire de la forme f { x ) = 0, il faut au pra
lable tudier les variations de la fonction pour isoler les zros. On suppose dans la suite que
cette tude est dj ralise et que dispose dun intervalle [a, b] sur lequel la fonction est
strictement monotone, et tel que lon ait f i a ) f { b ) < 0. Daprs le thorme de la bijection
monotone, on en dduit que / admet un unique zro dans ]a,b[.
Pour programmer les diffrentes mthodes numriques de rsolution, nous allons utiliser la
classe parente suivante :
equations, py
class N o n L i n e a i r e ( o b j e c t ):
d e f __ i n i t ___( s e l f , approx, ep s= le-14, m axlter= 10**7):
s e l f . approx = approx
self.ep s = eps
se lf.m ax iter = m axiter
tH
ment le nombre ditrations.
racine de / .
On pose oq = a et bo = b. Puis pour tout n e N, on pose
{an,Cn) si f (an) fiCn) <0 Cln "h
(^n+l ) bfi +l) icn,bn) si f [an) f { C n ) > 0 ou Cn =
Lerreur absolue de lapproximation de par an ou bn est alors majore par bn~ cin- ) et
lerreur relative est de lordre de
M th o d e s n u m riq u e s 183
e q u a t io n s .p y
bn
fi^n)
fibn)-f(an)
f {x ) =X
Les solutions de cette quation sont appels des points fixes de f ; gomtriquement, ce sont
les abscisses des points dintersection entre la courbe reprsentative de / et la premire bis
sectrice des axes.
184 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
Une mthode fructueuse pour rsoudre ce type dquation est de procder par itration,
condition toutefois que soient vrifies par exemple les hypothses du thorme du point fixe,
dont voici lnonc :
Soit I un intervalle ferm stable pour une application contractante / de rapport de L i P S C H i T Z
/: e [0 , 1 [ ; alors
- / possde un unique point fixe e l ;
iX o = CL
- pour tout a e I, la suite x+ i = fix ) ^ et on a la majoration
V neN , \ X f i - ^\ < \x q - \
Les points fixes peuvent tre classs en diffrentes catgories suivant la valeur de f'{) en
points fixes attractifs ( | f { ) \ < 1 ), rpulsifs ( | f'i) \ > 1 ), super-attractifs if'i) = 0 ), indiff
rents ( I/'(^) I = 1 ).
e q u a tio n s .p y
2 .4 M th o d e d e N ew to n
L a m th o d e de N e w to n e s t u n e d e s m t h o d e s le s p l u s u t i l i s e s p o u r la r s o l u t i o n d e s q u a
t i o n s n o n l i n a i r e s ; e n e f f e t, d u n e p a r t , e lle c o n v e r g e g n r a l e m e n t t r s v i t e , d a u t r e p a r t , e lle
se g n r a lis e a u x s y s t m e s n o n lin a ir e s .
Le principe en est le suivant : partant dune valeur xq, on trace la tangente la courbe re
a prsentative de f au point Mo(xo,/(xo)) ; cette droite coupe laxe des abscisses en un point
O
c dabscisse
D fixo)
X l = X o -
kD f'ixo)
O
rs] On ritre alors lopration tant que deux valeurs conscutives sont distantes dau moins la
(S) valeur de seuil eps. Ceci revient appliquer la mthode du point fixe avec la fonction
f ix )
>- c p (x ) = X -
Q. f'ix)
O
U
Pour programmer cet algorithme, on utilise alors la classe Point Fixe, dont on surcharge la
mthode resolu tion :
e q u a tio n s .p y
class N ew ton( P o i n t F i x e ) :
def reso lu tio n (self, f, fp):
retu rn P o in tF ix e.reso lu tio n (self, lam bda x :x -f(x )/fp (x ))
M th o d e s n u m riq u e s 185
Dans ce cas, la convergence est moins rapide que dans le cas de la mthode de Newton, mais
le rsultat peut tre obtenu plus rapidement si le calcul de / ' est trs long.
e q u a t io n s , p y
La mthode du point fixe converge id une vitesse vertigineuse du fait que le point fixe est
super-attractif. On constate de plus que lalgorithme de H r o n semble concider avec la m
thode de N e w t o n applique la fonction x - 2 , ce que lon vrifie par un calcul rapide.
noter que mme si la mthode de N e w t o n permet en gnral dobtenir une convergence
quadratique, un mauvais choix de la valeur initiale peut provoquer la divergence de cette m
thode (notamment si la courbe reprsentative de / prsente au point dabscisse xo une tan
gente peu prs horizontale). Do limportance dune tude pralable soigne de la fonc
tion / .
3 R s o lu tio n n u m riq u e d q u a t i o n s d i f r r e n t i e l l e s
Dans la plupart des cas, on ne sait pas rsoudre explicitement le problme de Cauchy (C) ;
do la ncessit de mettre au point des mthodes numriques de rsolution approche dun
tel problme.
Nous allons crer une classe ODE qui servira dinterface pour la programmation des diffrents
schmas numriques. Cette classe possde comme attribut la fonction / , le pas h, les condi
tions initiales (ro>^o) ; de plus, elle programme la rsolution de lquation de dpart sur un
intervalle I = [a,b]; pour ce faire, il faut parcourir lintervalle I partir de to vers la droite
jusqu atteindre b, puis partir de to vers la gauche jusqu atteindre a.
o d e .p y
class 0 D E ( o b j e c t ):
def __ i n i t ___( s e l f , f, h):
s e lf.f = f
se lf.h = h
Autrement dit.
x {t + h) ~ x{t) + h-x'it) = x[t) + h - f {t ,x {t ))
Partant du point ito,xo), on suit alors la droite de pente f{to,xo) sur lintervalle de temps
[ t o , t o + h]. On pose alors :
t\ = to h
Xi = xo + h- f{to,xo)
188 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
De nouveau, partant du point (ii,xi), on suit alors la droite de pente /(ii,x i) sur lintervalle
de temps [ti,ti + h], et ainsi de suite.
On construit ainsi une suite de points de la manire suivante :
Vfce[0,Nl, = +
^ \xjc+i=Xk + h-fitjc,Xic)
La ligne brise joignant les points {iticXjc) | k e [0 ,N]} donnera une solution approche de
notre quation diffrentielle.
Voici une manire de programmer ce schma numrique :
o d e .p y
class E uler(O D E ):
def i t e r a t i o n ( s e l f ):
f, h = s e lf.f, se lf.h
[t, x] = se lf.lis te [se lf.in d ic e ]
return [ t + h , x + h * f ( t , x) ]
o d e .p y
"O
O from m ath im port exp
c
=3 im port P o stS crip t as ps
Q
kDI
def f ( t , x ); return x
O
r\i a, b, h = -3, 3, 0.1
approx = E u ler(f, h); a p p ro x .C I(0, 1.0)
4 -J
x: liste_ ap p ro x = ap p ro x .re so lu tio n (a, b)
ai
> liste_ ex acte = [[t, exp (t)] for t in p s.sran g e(a, b, h)]
CL
O
U
nom Fichier, b o ite = "o d e_ ex p o n en tiellel", [-4 .5 , -2, 3.5, 14]
zoom, rouge, bleu, noir = 40, (1, 0, 0), (0, 0, 1), (0, 0, 0)
p s .p lo t(n o m F ich ier, b o ite, zoom, [ [liste_ ap p ro x , bleu], [liste_ ex acte, rouge]],
['a p p ro x ', [1 .5 , 3], bleu], ['e x a c te ', [0 .7 , 5], rouge],
['E u le r avec h = 0 .1 ', [-3, 9], noir], ratio Y = .4 , m arge= l.l)
M th o d e s n u m riq u e s 189
Il f a u t b ie n c o m p r e n d r e q u c h a q u e
t a p e , o n r e p a r t d a n s la d i r e c t i o n d u n e
s o l u t i o n e x a c t e d e l q u a t i o n d i f f
r e n t i e l l e , m a i s q u i n e s t p a s c e l le q u i
est s o lu tio n d u p ro b l m e d e C a u
c h y i n i t i a l . S u r le g r a p h i q u e c i - c o n t r e ,
o n tra c e u n e s o lu tio n a p p r o c h e p o u r
la c o n d i t i o n i n i t i a l e JciO ) = 1 e t le s
c o u r b e s in t g ra le s d e n o t r e q u a t io n
q u i p a s s e n t p a r le s p o i n t s {tjc, x j c ) .
ode.py
def f ( t , x ) : return x
a, b, h = 0, 5, 0.5
approx = E u ler(f, h); a p p ro x .CI(0, 1.0)
liste_ ap p ro x = ap p ro x .re so lu tio n (a, b)
courbes = []
for X in liste_ ap p ro x :
[xO, yO] = X
cou rb es.append![ [ [t, exp(t-xO ) * yO] for t in
p s.sran g e(a, b, 0 .0 5 )], (1 - xO /10, 0.1, xO /30), 0 .4])
c o u rb es.append![liste _ a p p ro x , 10/ 0, 1), 1])
p s . p lo t ! ' o d e _ e x p o n e n tie lle 2 ', [-0 .5 , -2 .5 , 3 .5 , 1 1.5], 80, courbes, ratio Y = .2 )
Pour juger de la qualit dune mthode (ou schma) numrique de rsolution dquations
diffrentielles, il faut prendre en compte plusieurs critres. Pour un expos rigoureux de ces
notions, on se reportera louvrage de rfrence [Dem96].
"O - Il erreur de consistance donne lordre de grandeur de lerreur effectu chaque pas. Par
O
c
=3 exemple, dans le cas de la mthode d E U L E R , lerreur de consistance mesure lerreur
Q quentrane le fait dapprocher le nombre driv par un taux daccroissement. La som
'JD
O mation des erreurs de consistance chaque pas donnera lordre de grandeur de lerreur
(N
globale (sous des hypothses de rgularit pour la fonction /). laide de la formule de
T aylor -L agran g e , on peut montrer que dans le cas de la mthode d E u L E R , lerreur
xz
DI de consistance est domine par ; on dit alors que cette mthode est dordre 1. Ainsi,
>- dun point de vue thorique, plus le pas est petit, meilleure sera lapproximation.
Q.
O
U Un schm a num riq u e est dit consistant si la som m e des erreurs de consistance ten d
vers 0 q u an d le pas h ten d vers 0 ; ce qui est le cas de la m th o d e d EuLER (en gros, car
N/z^ ~ /2 ^ 0 o N dsigne le nom bre d itrations).
- La stabilit c o n t r l e la d if f r e n c e e n t r e d e u x s o lu t io n s a p p r o c h e s c o r r e s p o n d a n t deux
c o n d it io n s in it ia le s v o is in e s : u n s c h m a e s t d it stable s i u n p e t i t c a r t e n t r e le s c o n d i
t io n s in itia le s x{to) = xq e t x{to) = x o + e e t d e p e t i t e s e r r e u r s d a r r o n d i d a n s le c a l c u l r
c u rre n t des X]c p r o v o q u e n t u n e e r r e u r f in a le \X]-Xjc\ c o n tr la b le . La m t h o d e d E U L E R
190 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
Dans le script suivant, on applique la mthode dEULER sur lintervalle [0,1] avec la condi
tion initiale x(0) = 1. Pour minimiser le temps de calcul, lalgorithme est rcrit sous forme
abrge.
o d e .p y
Pour un pas /7 < 10 le temps de calcul devient trop important, de plus, on voit poindre
leffet des erreurs darrondis, puisque la solution approche est devenu suprieure lexpo-
M th o d e s n u m riq u e s 191
En gnral, il ne suffit pas quun schma numrique soit convergent pour quil donne de
bons rsultats sur nimporte quelle quation diffrentielle. Encore faut-il que le problme
soit mathmatiquement bien pos (en particulier, les hypothses du thorme de Cauchy-
L i P S C H i T Z doivent tre vrifies), quil soit numriquement bien pos (continuit suffisam
ment bonne par rapport aux conditions initiales) et quil soit bien conditionn (temps de cal
cul raisonnable).
C o n s i d r o n s p a r e x e m p l e le p r o b l m e d e C a u c h y :
xi l ) = 1
dont la solution est la fonction cp: r>1/r^. La rsolution numrique sur [1,5] seffectue de la
manire suivante :
ode.py
a, b, h = 1, 5, G .1
approx = E u ler(f, h); a p p ro x .CI(1, 1.0)
liste_ ap p ro x = ap p ro x .re so lu tio n (a, b)
liste_ ex acte = [[t, 1 / t**2] for t in p s.sran g e(a, b, h)]
rouge, bleu, b o ite = (1, 0, 0), (0, 0, 1), [-.5 , -5 .5 , 5.5, 2.7]
a
O
c
n
tJH
D
O
CM
(y)
ai
>
CL
O
U
On constate quici la solution approche scarte assez rapidement de la solution exacte cp. En
effet, la forme gnrale des solutions de lquation diffrentielle prcdente est donne par
t X x ^ + 1 / x^. La condition x(l) = 1 impose A = 0 , mais ds quon scarte de la solution cp on
suit tangentiellement des courbes intgrales qui comportent un terme en Xx^ et donc qui
192 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
diffre notablement de la solution. Donc le problme est mal pos. Ici le schma numrique
nest pas en cause.
S o i t r s o u d r e p r s e n t le p r o b l m e d e C a u c h y :
ix(l) = l
\x'{t) = 10 0 (sin(r) - x)
a, b, h = 0, 10, 0.02012
approx = E u ler(f, h); a p p ro x .C I(0 .0 , 0.0)
liste_ ap p ro x = ap p ro x .re so lu tio n (a, b)
liste _ e x ac te = [[t, g(t)] for t in p s.sran g e(a, b, h)]
rouge, bleu, b o ite = (1, 0, 0), (0, 0, 1), [-.5 , -2, 10, 2]
a
O
c
13
Q
11
O
r\i
J-J
x:
ai
s_
>.
CL
O Avec un tel pas, la solution approche oscille en sloignant de plus en plus de la solution
U
exacte. En effet, le schma numrique est donn par :
Donc une erreur de Cjt sur xjc aura les rpercussions suivantes sur le calcul des termes ult
rieurs :
ejt+l = (1 - 100/Z)fc = > E]c+n = (1 - lOO/zl'^Efc
M th o d e s n u m riq u e s 193
Ainsi donc, tant que 1 - lOOh > -1, cest--dire tant que h < 0.002, une petite erreur sur lun
des termes aura des rpercussions allant en samplifiant.
Bien que le problme soit numriquement bien pos, il est en fait mal conditionn.
kl = h-f {t n, Xn)
tk + l - h + h k2 = h - f i t n + ^, Xn + Y
ou
^k+i X]^ + ^ { k \ + 2 k 2 + 2 ks +JC4 ) ks = h-f\^tn + ^, Xn + ^
k4 = h - f { t n + h, Xn + k3)
Les coefficients qui apparaissent dans ces formules mystrieuses sont judicieusement ajusts
pour obtenir une mthode dordre 4 , sans pour autant avoir calculer les drives succes
sives de / (comme cest le cas dans les mthodes de T a y l o r ) , ou recourir une formule de
rcurrence dordre au moins 2 pour dfinir xjc (comme cest le cas dans les mthodes pas
multiples).
Sans plus attendre, compltons notre fichier ode. py en y ajoutant ce schma.
o d e .p y
class RK4(0DE):
def i t e r a t i o n ( s e l f ):
f, h = s e lf.f, se lf.h
[t, x] = se lf.lis te [se lf.in d ic e ]
kl = h f(t, x)
k2 = h * f(t + h/2, X + k l/2 )
def f ( t , x ): return x
a, b, h = 0 , 1, 0.1
liste_ ex acte = [[t, ex p (t)] for t in ps.sran g e(a, b, h)]
194 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
p r i n t ("{:'"10} 1 | { :'"1 7 } ". fo r m a t ( ' h ', ' erreu r e u l e r ' , 'erreu r rk4')
p r i n t ('-'* 5 2 )
for i in r a n g e ( 1, 7):
h = l0 * * (-i)
eu ler = E u ler(f, h); e u le r.C I(0 , 1.0)
e = eu le r.re so lu tio n (a , b )[-l]
rk4 = RK4(f, h); rk 4 .C I(0 , 1.0)
r = rk 4 .re so lu tio n (a , b )[-l]
p rin t(" {0 :> 1 0 g } I {!:> . 10e} | {2 :> . 10e} "
.fo rm at(h , exp(e[0]) - e [l], exp(r[0]) - r[l]))
O n c o n s ta te q u e p o u r h = 0 .0 0 1 , la m t h o d e d ' E U L E R n e d o n n e q u e t r o i s d c i m a l e s s i g n i f i c a
t iv e s d u n o m b r e e, a lo r s q u e la m t h o d e d e Ru n g e -K utta e n d o n n e q u a t o r z e ! O n re m a rq u e
g a l e m e n t q u i l e s t i n u t i l e d a p p l i q u e r la m t h o d e d e Ru n g e -K u tta a v e c u n pas h > 0 .0 0 1 ,
p u i s q u e d a n s c e c a s le s e r r e u r s d a r r o n d i p r e n n e n t le d e s s u s p a r r a p p o r t a u g a i n t h o r i q u e d e
p r c is io n .
x'{t) = 1 + -x{t
TJ
O Si lon tente de rsoudre cette quation avec la classe prcdente, le droulement du pro
c
rj gramme sera arrt un moment par une erreur indiquant un dpassement de capacit pour
solution initiale x(0 ) = 0 , on peut montrer quelle est dfinie sur un intervalle ouvert born et
(y) symtrique par rapport 0 ; de plus, elle admet des limites infinies aux bornes de cet inter
XI valle, ce qui explique qu partir dune certaine valeur de t, x prend des valeurs au-del des
OJ valeurs permises pour les flottants.
>-
Q. Nous sommes donc amens modifier notre classe ODE en ajoutant la possibilit dindiquer
O
U une condition darrt dans la rsolution numrique dune quation diffrentielle. On sinspire
ici dune classe donne dans [Lan09].
o d e .p y
class 0 D E ( o b j e c t ):
def __ i n i t ___( s e l f , f, h):
s e lf.f = f
se lf.h = h
M th o d e s n u m riq u e s 195
def i t e r a t i o n ( s e l f ):
raise N otIm plem entedE rror
class RK4(0DE):
def i t e r a t i o n ( s e l f ):
f, h = s e lf.f, se lf.h
[t, x] = s e l f . l i s t e [ s e l f . in d ice]
kl = h * f(t, x)
k2 = h * f(t + h/2, X + k l/2 )
k3 = h * f(t + h/2, X + k2/2)
k 4 = h * f ( t + h , x + k 3 )
retu rn [t + h, X + (kl + 2*k2 + 2*k3 + k4) / 6]
Pour rsoudre Tquation x' = l + t^x^, on indique alors comme condition darrt de la rsolu
tion numrique, le dpassement dune certaine valeur par x : ds que |x(r)| > 4.5, on sort de
la boucle.
a
o
c
D o d e .p y
Q
y> im port P o stS crip t as ps
o
r\i
def f(t, x ) : return 1 + t**2 * x**2
a, b, h, bleu, b o ite = -4, 4, 0.01, (0, 0, 1), [-4 .5 , -4 .5 , 4 .5 , 4.5]
def horscadre(x): retu rn abs(x) > 4.5
>.
C l
O
(J courbes = []
for k in p s . s r a n g e ( -4, 4, 0 .2 ):
sol = RK4(f, h); sol.C I(0 , k)
cou rb es.append![so l.re so lu tio n (a , b, horscadre), bleu])
3 .3 .2 Un sy st m e a u to n o m e
Soit reprsenter les courbes intgrales du systme autonome suivant, appel oscillateur de
van der Pol :
i^= y
Il faut au pralable adapter la classe RK4 aux cas des systmes diffrentiels : en effet, dans
la fonction ite r a tio n , les variables x, kl,... k 4 reprsentent prsent des listes. Or une ins
XJ
O truction comme x -i- A:l/ 2 renverra un message derreur. En effet, la division dune liste par un
c
rj entier nest pas dfinie ; de plus, laddition de deux listes effectue la concatnation des listes,
tJH
D et non laddition des listes composante par composante. Si on souhaite utiliser la classe RK4
O
CM
sans modification, il faut alors travailler non plus avec des listes, mais avec des objets suppor
(y) tant la vectorisation, comme cest le cas des tableaux de la librairie de tierce partie NumPy ; en
XI outre, cette option a lavantage de rduire de manire significative les temps de calcul. Cette
CTI option sera prsente dans lexercice 51.
>-
Q . Dans un but pdagogique, faisons ici le choix de rcrire une nouvelle classe adaptant la m
O
U thode de Ru n g e -K u tta des vecteurs reprsents par des listes.
o d e .p y
o d e .p y
b = 15
for k in p s.sran g e(0 , 20, 0 .4):
sol = R K 4_system e(f, h)
S O I.C K 0 , [0 .3 * k -3 , 3])
solu tio n = [x[l] for X in s o l. reso lu tio n (a, b, horscadre)]
c o u rb es.append![so lu tio n , (k/20, 0 .32, 0.4 8 -k /4 4 )])
sol = R K 4_system e(f, h)
so l.C I(0 , [3 - 0 .3*k, -3])
XJ solu tio n = [x[l] for X in s o l. reso lu tio n (a, b, horscadre)]
O
c
D cou rb es.append![solu tio n , !k/20, 0.32, 0.4 8 -k /4 4 )])
Q
y
JD
A p s .p lo t ! "syst_autonom e", b o ite, 40, courbes, etiq u e tte= F a lse )
O
CM
x:
OJ
>
Q.
O 3 .3 .3 Un ex em p le d q u a tio n d iffren tielle linaire d o rd re 2
U
On rappelle quune quation diffrentielle linaire dordre n peut toujours scrire comme un
systme diffrentiel dordre 1. Illustrons ceci dans le cas n - 2 \ e n notant :
0 1 ^ 0
A(r) =
- b{ t) -ait)}
X{t) =
?,) c{t)
198 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
on a les quivalences
X = X
V rel x" + a{t)x' + b{t)x = c { t ) < ^ ^ y t l
x - - b x - ax' + c
d (x \ ' 0 1 \ (x\ O]
.\ + \
dt Uj -b -a) [X)
def f ( t , x ) :
alp h a = 0.5
return [x[l], (alpha**2 - t**2) / t**2 * x[0] - x[l] / t]
a
O
c
D
kD
O
rs]
ai
>
CL
O
U
M th o d e s n u m riq u e s 199
3 .3 .4 In c o n v n ien ts d e la m th o d e d e R u n g e -K u tta
La mthode de Runge-Kutta est apprcie par sa simplicit de mise en uvre ; en effet, elle ne
ncessite que quatre valuations de / par pas, tout en offrant une bonne prcision.
Cependant, aucune mthode numrique ntant parfaite... elle souffre de deux inconvnients.
Dune part, on ne dispose daucune indication sur lerreur de troncature au cours des calculs.
Dautre part, elle prsente des problmes de stabilit ds que le second membre varie rapide
ment (problmes raides).
Si lon souhaite surveiller la prcision, une solution simple, mais coteuse, consiste conduire
deux calculs simultanment, lun avec un pas h et lautre avec un pas 2h. Tant que la diff
rence entre les deux rsultats ne dpasse pas une certaine valeur, on admet que lerreur de
troncature est acceptable. Sinon, on repart avec un pas plus petit.
4 In te rp o la tio n p o ly n o m ia le
>- P = /(xo)Lo-t----h/(x)L
Q.
O
U Cependant, cette mthode souffre de deux limitations : dune part, elle sera assez sensible
aux erreurs darrondi vu le grand nombre de multiplications effectuer ; dautre part, on ne
peut pas calculer par rcurrence la suite des polynmes L/ : ds quon rajoute un point la
subdivision, il faut recalculer tous les polynmes de la base.
La mthode utilise le plus couramment en analyse numrique est celle des diffrences divi
ses; elle consiste dcomposer le polynme P dans la base des polynmes de N e w t o n . Cette
mthode a dj t utilise la section 2.3.4 du chapitre 3 pour le calcul des logarithmes.
200 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
Pour programmer cet algorithme, on remplit un tableau triangulaire double entre : chaque
tape, on remplit une colonne supplmentaire.
Une fois le tableau rempli, on extrait les termes diagonaux c o , . . . , c ; puis on utilise lalgo
rithme de H o r n e r pour calculer les valeurs du polynme dinterpolation pn en un point x :
plo t(n o m F ich ier, b o ite, zoom, [[liste _ f, bleu], [liste_ p l, v ert],
[liste_ p 2 , rouge]], [ ' l/(l+ 1 0 x '^ 2 )', [1 .1 , 0.1], bleu],
['p _ ll(x )', [1 .1 , -0 .3 ], v ert], ['p _ 1 9 (x ) , [1 .1 , 1], rouge])
Avec 11 points, le polynme dinterpolation approche relativement bien la fonction tant que
lon ne sapproche pas des bornes du segment [-1]. On serait alors tent daugmenter le
nombre de points dinterpolation. Or comme on le voit sur la figure suivante, avec 19 points
dinterpolation, le mal empire ! Cest le fameux phnomne de R u n g e .
2 / -Fl
O = ^ c o s ------- / e [ 0 , r i - l ] |
n
202 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
in t e r p o la t io n . p y
Compltons alors notre fichier runge. py. En reprenant les essais prcdents, remplaons la
subdivision rgulire de [ - 1 , 1 ] parla subdivision a :
in te r p o la t io n , p y
"O
O
c
13 Cette fois-ci, le polynme dinterpo
Q ------ f(x) lation fournit une approximation de
1
1 ...... P_11(x) / tout fait fidle. Plus prcisment,
O
--- P_19(x) on peut prouver que si / est lipschit-
zienne sur lintervalle [ - 1 , 1 ], la suite
ai des polynmes de Tchebychev con
>- verge uniformment vers / sur cet
Q.
O intervalle (pour une dmonstration
U
de ce rsultat, se reporter [Dem96]).
Notons que si lon souhaite effectuer une interpolation sur un segment [a, b] quelconque, on
se ramne ltude prcdente par le changement de variable affine
t-a
: t
b-a
M th o d e s n u m riq u e s 203
Avant de clore cette section, signalons que pourrait chercher approcher la fonction f
par des polynmes autres que des polynmes dinterpolation :
- le s p o l y n m e s d e B e r n s t e in a s s o c i s la f o n c t i o n / :
n ( Jc\ ^
Bn(/)(x) = / -
fc=o ' ' V
- le polynme de degr au plus n obtenu par la mthode des moindres carrs, cest--dire
le polynme qui ralise le minimum suivant :
inf
!/<">-P (x) I dx Pe[R[X]
Si on munit lespace vectoriel C ([-l,l]) du produit scalaire (/|g) = j l i f g , le polynme
recherch est la projection orthogonale de la fonction / sur le sous-espace vectoriel
[R[X]. La dtermination de ce polynme se ramne la rsolution dun systme li
naire : en effet, P est le projet de f si et seulement si la fonction ( P - / ) est orthogonale
chacun des vecteurs de la base canonique de Un [X].
Encore faut-il disposer dune mthode dintgration numrique...
- etc.
Lorsquune fonction est trop complique pour que le calcul analytique de sa drive soit pra
tique, on peut obtenir une valeur approche de la drive en calculant un taux daccroisse
ment T/ :
f{x+h)-fix)
f i x ) avec h petit
h
En thorie, plus h est petit, plus Tx(h) est proche de f i x ) . Mais, eu gard aux problmes
XJ
O darrondi, il ne faut pas prendre h trop petit. En effet. Le calcul de x^Ch) se fait avec un pr
c
rj cision absolue de lordre de 2 e- | f i x ) | /h (o e 1 0 ^^) ; par ailleurs, daprs lingalit de
tH T a y l o r - L a g r a n g e , on a
O
\xxih)-fix)\ <^||/"||oo
XI
CTI Lingalit triangulaire entrane alors
>-
Q . , ------ h 2 e If {x ) I
O
U fix )-ix ih ) < -iir iio o + '
2 n
2e\f{x)
Une tude rapide de la fonction h: h ^ ||/"||o o + montre que cette fonction possde
un minimum absolu sur atteint en
h =2
204 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
Pour une fonction suffisamment rgulire, il est donc judicieux de choisir une valeur de h qui
soit de Tordre de y/z, cest--dire de Tordre de 1 0 ^.
Lcriture dune classe pour la drivation numrique peut tre :
d e r iv a tio n .p y
class D i f f A v a n t l ( D i f f ):
def __ c a l l ___( s e l f , x ) :
f, h = s e lf.f, se lf.h
return (f(x+h) - f(x ))/h
Comparons pour diffrentes valeurs de h les valeurs donnes pour la drive de la fonction
sinus en 0 :
d e r iv a tio n , p y
im port m ath as m
p rin t('{ :" 7 } I { :^ 2 0 } '.fo rm a t!'h ', 'c o s ')); p rin t ( '- '*28)
for n in r a n g e ! 1, 13):
X, h = 0, 10**(-n); cos = D iffA v an tl(m .sin , h)
p r i n t ! '{ :7 .le} | { : . 15f>' . form at(h , cos(x)))
h 1 cos h 1 cos
, - ^ f { x + 2h) + f { x + h ) - ^ f { x ) - ^ f { x - h )
+ 0[h^) diffrence avant dordre 3
^ h
etc.
M th o d e s n u m riq u e s 205
Pour les programmer, il suffit dajouter une classe pour chacune dans le fichier de rivt io n . py
d e r iv a tio n , p y
class D i f f C e n t r e 2 ( D i f f ):
def __ c a l l ___( s e l f , x ) :
f, h = s e lf.f, se lf.h
retu rn (f(x+h) - f(x -h ))/(2 * h )
im port m ath as m
for n in r a n g e ( 1, 13):
X, h = 0, 10**(-n)
gl = D iffA v an tl(f, h)
g2 = D iffC en tre2 (f, h)
p r i n t ( '{ 0 :7 .1 e } | { l:.1 5 f> I { 2 : . 1 5 f > ' . f o r m a t ! h , g l ( x ) , g 2 ( x ) ))
Cette fois-ci, on voit apparatre trs nettement la perte de prcision lorsque h est trop petit.
TJ
O
c
D
kD 6 In t g ra tio n n u m riq u e
O
rs]
Les mthodes les plus courantes pour approcher numriquement une intgrale reposent sur
une formule de la forme
oi pb n
>- 1=1 f{x)dx=^W jfiXj)+ E (*)
Q. Ja j = i
O
U
o les Wj sont appels les poids, les x j les pivots ou nuds. Le nombre E est lerreur de tron
cature.
Les mthodes classiques dintgration numrique se rpartissent en deux types :
- les algorithmes de N ewton-Cotes o les pivots sont quidistants. Les n poids sont
donc les seuls paramtres ajustables ; ils sont alors choisis pour rendre la mthode exacte
(cest--dire telle que E = 0) pour nimporte quel polynme de degr au plus n - \ .
206 P r o g r a m m a t i o n e n P y t h o n p o u r les m a t h m a t i q u e s
- le s a l g o r i t h m e s d e q u a d r a t u r e d e G auss o le s p i v o t s e t le s p o i d s s o n t a j u s t a b l e s ; c e s
2 n p a r a m t r e s s o n t a l o r s c h o i s i s p o u r r e n d r e la m t h o d e e x a c t e p o u r n i m p o r t e q u e l
p o ly n m e d e d e g r a u p lu s 2 / 7 - 1 .
S i le s m t h o d e s d e G a u ss s o n t p lu s p e r f o r m a n te s (e n t e r m e d e p r c is io n p o u r u n m m e
t e m p s d e c a l c u l ) q u e le s m t h o d e s d e N e w to n -C o te s , e lle s s o n t e n r e v a n c h e p l u s l o u r d e s
p ro g ra m m e r.
A v a n t d e d c r i r e q u e l q u e s m t h o d e s d i n t g r a t i o n n u m r i q u e , o n p e u t c o m m e n c e r p a r c r i r e
u n e s u p e r - c l a s s e q u i r e p o s e s u r la f o r m u l e ( * ) :
in t e g r a t io n , p y
def q u a d r a t u r e ( s e l f ):
raise N otlm plem entedE rror
On modifie alors lide de dpart ainsi : on commence par subdiviser rgulirement linter
valle dintgration en n sous-intervalles [Xj,Xj+\\ o
b - a
Xo - a, X n - b, et V y |0, n\, xi = a + j h , avec h =
n
TJ
O E n s u i t e , o n r e m p l a c e / p a r u n p o l y n m e P y q u i i n t e r p o l e / s u r c h a c u n d e s p e t it s s e g m e n t s
c
rj
[X y , X y + l ]
tJH
D
O - S i Py i n t e r p o le / a u p o i n t Xy, a l o r s le g r a p h e d e P y e s t u n e d r o i t e h o r i z o n t a l e : c e s t la
CM
m t h o d e d e s r e c ta n g le s .
(y)
XI - S i P y i n t e r p o l e / a u x p o i n t s x y e t x y + i , a l o r s le g r a p h e d e P y e s t u n e d r o i t e a f f in e : c e s t
OJ
la m t h o d e d e s t r a p z e s .
>-
Q.
O - Si Py in te r p o le / a u x p o in t s x y , e t x y + i , a lo r s le g r a p h e d e P y e s t u n e p a r a b o l e :
U
c e st la m t h o d e d e S i m p s o n 1/3.
E n f i n , o n s o m m e le s i n t g r a l e s d e c h a q u e p o l y n m e P y s u r [x y , x y + i ] , e t o n o b t i e n t u n e v a l e u r
a p p ro c h e de I:
n -l nXj+i n - l ( nXj +i \ n -1 n x + i
O
rvj
class T r a p e z e s ! I n t e g r a t i o n ):
def q u a d r a t u r e ! s e l f ):
CTI a, b, n = se lf.a , se lf.b , se lf.n
s_
>- h = !b-a) / n
Q.
O return [!h, a + !i+ 0.5)*h) for i in range!n)]
U
e ls e :
re tu rn 2
def q u a d ra tu r e ( s e l f ):
a , b, n = s e l f . a , s e lf .b , s e lf .n
i f n % 2 != 1 :
n += 1
h = ( b -a ) * 0 .5 / n
re tu rn [ ( h /3 * s e lf .c o e f f ( i, 2 * n ) , a + i* h ) fo r i in r a n g e ( 2 * n + l) ]
S o lu t io n .
in t e g r a t io n , p y
from math im p o rt *
from P o s t S c r ip t im p o rt p lo t , n ra n g e
def z ( t ):
s = S im p s o n (0 , t , 10 0 0 )
X = lam b d a u :c o s ( u * * 2 )
y = lam b d a u : s in ( u * * 2 )
re tu rn [ s . in t e g r a le ( x ) , s . in t e g r a le ( y ) ]
b Cl
T(h) = h - / U o ) + V /(JC;) + -/ (-C n ) O vy e [0 ,]|, X j = a + jh , et h = ------------
2 2 j n
On p eu t alors m o n trer (cf. [Dem96]) laide de la form ule d EULER-MACLAURiN que lerreur
com m ise dans la m thode des trapzes possde u n dveloppem ent limit to u t ordre de la
form e
De plus, les ne d p en d e n t ni de n, ni de h.
Lide est alors de faire une com binaison linaire de T (h) et T (/2) p o u r an n u ler le prem ier
term e du dveloppem ent de E :
T() = f i t ) . + a \h ^ +a2h'^ h +
^ ( f ) /fl + + + + 0[h^^)
i(4 T (f)-T ( )) = f ^ f [ t ) d t -f- > 2 + + b j c - i -tO^^^j
N
-------------------- V-------------------- '
0{h^)
On rem arque q u ainsi, on a gagn u n ordre dans le dveloppem ent de lerreur. Cest u n bon
exercice de vrifier que la nouvelle expression o b ten u e correspond la m th o d e de Sim pson .
Le procd p rcdent se gnralise aism ent : on utilise des dichotom ies successives avec des
pas de la form e h - et on rem plit u n tableau triangulaire co m p ren an t les nom bres :
"O
O
c 'b a\ .w iT, H a A/^_ i ^ _ i
13
Q ^m,0 T et V e p , m | , K ,n ,n = --- 4_1
l 2'"
O
(N
tape r=o 1 r=2 t= m
sz
ai tableau [0]
>
Q.
O tab leau ll] Ai.o
U
tableau [2] A2,0 ^ A2,i
En effet, en n o ta n t h = on a
2^'-] 1
Afc,o - h - / ( e ) + Y. f{a +jh) +-f(b)
^ j= i
Y 2^-1-1 )k-l
2'^-^-! ^
= h -/()+ E f { a + 2ph)+ E f [ a + { 2 p + l )h) + - f i b )
p= l p= 0 2^ ^
Y 2^-1-1
= Afc_i_o + E f [a + { 2 j + l)h)
^ y=0
A',k.O
Ceci p erm et de calculer un e fois et une fois seulem ent les valeurs de / ncessaires.
Ensuite, on rem plit les autres colonnes en utilisant la form ule
V e | [ l , m ] , Am,n =
4 ^ '- l
c l a s s R o m b e r g ( o b je c t ) :
d e f __i n i t __ ( s e l f , a , b, m):
s e l f . a , s e l f . b , s e lf . m = a , b, m
a
O
c def in t e g r a le ( s e lf , f ) :
D
a , b, m = s e l f . a , s e l f . b , s e lf .m
A = [ [ ( b -a ) * ( f ( a ) + f ( b ) ) * 0 .5 ] ]
O
] f o r k in r a n g e ( l, m + 1):
h = ( b -a ) / 2 * * k
Ap = h * s u m ( [ f ( a + j>t=h) f o r j in r a n g e ( l, 2**k, 2 )])
A. append ( [ 0 .5 * A [ k - 1 ] [0] -i- A p ])
>-
Q .
O f o r t i n r a n g e ( l, m + 1):
U f o r k i n r a n g e ( t , m + 1):
A [ k ] .a p p e n d ( ( 4 + * t * A [ k ] [ t - 1 ] - A [ k -l] [ t -l] ) / ( 4 * * t -l) )
r e t u r n A[m ][m]
from math im p o rt *
m = Rom berg(0 , 1 , 16 )
d e f u ( n ) : r e t u r n m .i n t e g r a l e (lam b da x : l o g ( l+ x * * n ) )
d e f v ( n ) : r e t u r n n * ( u ( n + l) / u ( n ) - 1 )
n, l i s t e = 2**8, [1, 0]
ai
>
1= 1 f { x ) d x = Y . Wj f i Xj ) -I-E
n
CL 1 ; =1
O
U
exacte p o u r tous les polynm es de degr infrieur k 2 n - l , alors il faut prendre
1 d " r( X ?^
P(x) = --------;--- - 1 ) "
2w!dx' ' '
ou par rcurrence :
-1 d
-------- P(x) = x P (x ) -P n -l(x )
n dx
Le calcul des poids et des pivots sen dd u it :
Pour appliquer cette m thode au calcul d u n e intgrale sur u n segm ent quelconque, on effec
tue u n changem ent de variable affine :
b -a a+ b. ,
/V { x )d x = ^ /( X -I - ----------- d x
la 2 j-i V 2
"O
O
c La form ule de quadrature de G a u s s devient alors
n
Q
kD n , b- a ^ b -a a +b
O X; -I-
rs] Ja
(y)
XI
CTI Pour program m er cette m thode, nous pro p o so n s de calculer n u m riq u em en t les poids et les
> pivots.
CL
O
U
in t g r a t io n , p y
d e f le g e n d r e ( t , m ):
i f m == 0:
re tu rn 1
e l i f m = = l:
re tu rn t
e ls e :
p0, p l = 1 , t
f o r i n r a n g e ( 1 , m ):
P = ( ( 2 * k + l) * t * p l - k*p0) / (1+ k )
p0, p l = p l , P
re tu rn P
from math im p o r t *
from P o s t S c r ip t im p o rt p lo t , o ra n g e
n u m p o in ts , a , b, f i c h i e r , zoom = 10 0 0 , -1 , 1, " le g e n d r e " , 12 0
b o it e = [ - 1 . 1 , - 1 . 1 , 1 . 1 , 1 . 1 ] # xmin, ymin, xmax, ymax
lis t e = [[[[x , le g e n d r e ( x , n ) j f o r x i n n r a n g e ( a , b, n u m p o in t s ) ] ,
( n /1 0 , 0 .3 2 , 1 - n / 1 6 ) ] f o r n i n r a n g e ( l, 1 1 ) ]
p l o t ( f i c h i e r , b o it e , zoom, l i s t e , g r a d H = .0 3 , r a t io Y = . 4 )
D a n s u n d e u x i m e t e m p s , o n u t ilis e l a lg o r it h m e d e N e w t o n p o u r le c a lc u l d e s r a c in e s p o s i
t iv e s d e Pfn, s a c h a n t q u e a m m e p a r it q u e m . P o u r c a lc u le r la i- i m e r a c in e p o s it iv e , il
fa u t u n e v a le u r a p p r o c h e p o u r in it ia lis e r l a lg o r it h m e d e N e w t o n ; i l e st p o s s ib le d e m o n t r e r
q u e la v a le u r c o s f ) c o n v ie n t .
V o ic i d o n c u n e p r o g r a m m a t io n d e la m t h o d e d e G a u s s - L e g e n d r e :
in t e g r a t io n . p y
from math im p o r t p i . co s
c l a s s G a u s s L e g e n d r e ( I n t e g r a t io n ) :
d e f g a u s s P i v o t s ( s e l f , m, t o l = l e - 1 4 ) :
d e f le g e n d r e ( t , m ) :
p0 = 1 ; p l = t
"O
O f o r i n r a n g e ( 1 , m ):
c
P = ( ( 2 * k + l) * t * p l - k*p0) / (1-i-k )
Q
p0, p l = p l , P
O dp = m*(p0 - t * p l ) / ( 1 - t* * 2)
r e t u r n p, dp
ai w = [0 f o r i i n ra n g e (m )] # p o id s
>- X = [0 f o r i i n ra n g e (m )] # p iv o ts
CL
O n R o o ts = (m -I- l ) / / 2 # nombre de ra c in e s p o s i t i v e s
U
fo r i in r a n g e ( n R o o ts ) :
t = c o s ( p i* ( i -i-0 .7 5 ) /( m -1 -0 .5 ) ) # ra c in e approche
f o r j in ra n g e (3 0 ):
p, dp = le g e n d r e ( t , m)
d t = -p / d p ; t = t -f- d t # mthode de Newton
i f a b s(d t) < t o i:
x [ i] = t; x [ m -i-l] = -t
214 Programmation en Python pour les mathmatiques
w [ i] = 2 / ( 1 - t * * 2 ) / (d p * * 2)
w [ m - i - l ] = w [ i]
b re a k
r e t u r n z ip ( w , x)
d e f q u a d r a t u r e ( s e lf ) :
a , b, n = s e l f . a , s e l f . b , s e l f . n
r e t u r n [ [ ( b -a ) * w * 0 .5 , ( a + b ) * 0 .5 + ( a -b ) * 0 .5 * x ]
f o r w, X i n s e l f . g a u s s P i v o t s ( n ) ]
in t e g r a t io n . p y
d e f s im p s o n ( f , a , b) :
c = (a + b ) * 0 .5
re tu rn ( f(a ) + 4 * f{c ) + f(b )) * a b s ( b -a ) / 6
d e f s im p s o n _ a d a p t a t iv e ( f , a , b, e p s ) :
c = (a + b ) * 0 .5
a r e u n io n , g a u c h e , d r o it e = s i m p s o n ( f , a , b ) , s i m p s o n ( f , a , c ) , s in ip s o n ( f , c ,b )
O
c i f a b s (g a u c h e + d r o it e - r e u n io n ) < = 15 * e p s :
13
r e t u r n gau ch e + d r o it e + (g au ch e + d r o it e - r e u n io n ) / 1 5
y>
e ls e :
O
rsl re tu rn ( s im p s o n _ a d a p t a t iv e ( f , a , c , e p s /2 )
+ s im p s o n _ a d a p t a t iv e ( f , c , b , e p s / 2 ) )
ai
from math im p o rt *
>
CL s = 4 * s im p s o n _ a d a p t a t iv e (la m b d a x : s q r t ( l - x * * 2 ) , 0 , 1, le -9 )
O
U p r i n t ( " { : 2 0 } - - - > { : . 1 5 f } " . f o r m a t ( " p i" , p i ) )
p r i n t ( " { : 2 0 } > { : . 1 5 f } => e r r e u r = { : .2 e } "
. f o r m a t ( "Sim p so n a d a p t a t iv e " , s, p i-s ) )
pi ---> 3 .1 4 1 5 9 2 6 5 3 5 8 9 7 9 3
Sim p so n a d a p t a t iv e > 3 .1 4 1 5 9 2 6 5 3 5 8 7 8 3 6 => e r r e u r = 1 .9 6 e -1 2
7 E x e r c i c e s d e n t r a n e m e n t
Les corrigs so n t disponibles sur le site dunod.com partir de la page d'accueil de l'ouvrage.
E x e r c ic e 5 1 . (M odification de la classe ODE p o u r la rendre com patible avec les systmes)
a) M odifier deux lignes de la classe ODE prsen te dans la section 3 (p. 196) p o u r p erm ettre
la vectorisation des donnes : la liste des points calculs doit tre p rsent u n tableau
du type numpy . a r r a y (cf. p. 74).
b) Pour tester cette nouvelle classe ODE, tracer (avec P o st S c r i p t . py puis avec m a t p l o t l i b )
les courbes intgrales du systm e au to n o m e de van der Pol en utilisant non plus la m
thode RK4_systeme m ais RK4.
Les exercices suivants se proposent de reprendre quelques schm as num riques prsents dans
ce chapitre en utilisant cette fois-ci les prim itives disponibles dans le m odule S c i P y
(Point fixe du cosinus) En im p o rtan t la fonction o p t i m i z e du m odule s c i p y ,
E x e r c ic e 5 2 .
trouver la valeur du p o in t fixe de la fonction cosinus, c.--d. la solution de lquation cos x = x.
S o lu t io n . Pour des variantes de la solution ci-dessous, consulter le fichier de corrigs en ligne.
> im p o r t numpy a s np
> from s c ip y im p o r t o p t im iz e
> o p t i m i z e . b i s e c t (lam b d a x : n p . c o s ( x ) - x , 0, 1) # r p .: 0.7390851332156672
T3 ^= y
O a) x'{t) = 1 -h x { t b) c) t^ x it)-\-tx '{t) + [ t ^ - a ^ ) xi t ) = 0
c
3
Q
kO
t H
o
rM
(5)
xz
CTl
>-
Q.
Sommaire
1 Quelques exem ples.............................................................................. 217
1.1 PGCD dune l i s t e .................................................................................... 217
1 . 2 Complments sur la rcursivit ............................................................218
1.3 Complexit................................................................................................ 2 2 2
1 Q u e lq u e s e x e m p le s
gi d e f pgcd(a, b):
lu.
>- ...... pgcd de deux e n t i e r s n a t u r e ls """
Q.
O i f b == 0 :
U
re tu rn a
e ls e :
r e t u r n pgcd(b, (a % b))
def pgcd_liste(l):
...... pgcd d'u ne l i s t e """
i f l e n ( l ) == 1 :
218 Programmation en Python pour les mathmatiques
re tu rn l[ 0 ]
e ls e :
r e t u r n p g c d ( l[ 0 ] , p g c d _ lis t e ( l[ 1 : ] ) )
p r i n t { p g c d _ l i s t e ( [4 * 5 * 6 * 3 7 , 3 * 5 * 6 * 3 7 , 3 * 4 * 6 * 3 7 , 3 * 4 * 5 * 3 7 ] ) )
C om m e illustration, nous calculerons rcursivem ent (et navem ent!) de deux m anires diff-
10
rentes la som m e i.
s o m m e l.p y
d e f som m e(n):
i f n > 0:
r e t u r n n + so m m e(n -1)
e ls e :
re tu rn 0
p r i n t (somme( 1 0 ) )
D ans tous les cas o n est n o n nul, la dernire instruction excute p ar la procdure somme ( )
est u n e addition, d o n t lu n des term es est la valeur rendue par lappel rcursif de sommme ( ) .
Le fait de quitter le corps de la fonction en term in an t p ar u n e addition induit un em pilem ent
des term es avant de raliser lopration, cest--dire u n agrandissem ent de la pile.
xz Selon les historiens, lune des prem ires apparitions de la rcursivit est la program m ation
DI
>- du langage ALGOL60 p ar Edsger D ijkstra , lorsquil m et en uvre la no tio n de pile.
Q.
O
U Si lon songe au calcul de cette expression postfixe depuis u n e pile, on au ra donc valuer la
squence :
10 9 8 . . . 1 0 + + . . . +
Selon le principe consistant dpiler deux o p randes puis em piler le rsultat de lopration,
lvaluation conduira u n e h a u teu r m axim ale de pile gale 12 dans notre exemple. On note
Rcursivit 219
aussi que le prem ier calcul a lieu tardivem ent. Le calcul effectif de la som m e ne p e u t co m m en
cer ta n t que la variable n n a pas attein t la valeur O : lvaluation de somme ( 10 ) atten d lva
luation de somme {9 ), qui elle-m m e est su sp en d u e lvaluation de somme { ), qui... Puis les 8
d e f somme.rec(acc, n):
""" somme r c u r s iv e te r m in a le (avec a ccum ulateur) ......
if n > 0 :
r e t u r n somme.rec(acc + n, n - 1 )
e ls e :
r e t u r n
d e f somme(n):
""" somme ( f o n c t i o n d 'e n v e lo p p e ) """
r e t u r n somme.rec( 0 , n)
p r i n t (somme( 1 0 ))
E x a m in o n s a lo r s la s u it e d e s a p p e ls p o u r le C cd cu l d e somme { 10 ) :
10 9 + 8 -f- 7 + 1 + 0
Le second program m e m ontre une version rcursive term inale de notre fonction de calcul de
la som m e. Lutilisation des ressources est bien m oins im p o rtan te (dans notre exemple, la taille
m axim ale de la pile ncessaire au calcul est attein te ds la prem ire opration, qui survient
d ailleurs sans tre diffre).
220 Programmation en Python pour les mathmatiques
56. crire une fonction qui lve u n nom bre u n e puissance donne, en utilisant
E x e r c ic e
u ne rcursivit term inale.
d e f puissance-rec_term(a, n, p ) :
p r i n t "appel avec a =", a, n =", n, p =", p
i f n == 0 :
re tu rn p
e ls e :
r e t u r n puissance_rec_term(a, n- , p*a)
1
d e f puissance(a, n ) :
r e t u r n puissance-rec_term(a, n, 1 )
p r i n t (puissance( 2 , 1 0 ))
def fibo(n ):
if n < 2 :
re tu rn 1
e ls e :
r e t u r n fibo(n - 1 ) + fibo(n - ) 2
fo r n in ra n g e ( 1 2 ) :
p r in t ( f ib o ( n ) )
p r i n t ( f ib o { 4 0 ) ) # donne 165580141
T3
O
c La version rcursive term inale suit :
D
f ib R e c T e r m .p y
kD
O d e f f ib o _ r e c _ t G n n ( n , i, a, b ):
rs]
i f i == n:
(5)
re tu rn b
XI
DI e ls e :
>- r e t u r n f ib O - r e c - t e r m ( n , i- i- 1 , a-t-b, a)
Q.
O
U
d ef f ib o ( n ) :
""" f o n c t io n d 'e n ve lo p p e """
r e t u r n f ib o - r e c - t e r m ( n , 0 , 1 , 1)
f o r n i n r a n g e ( 1 2 ):
p r i n t (fibo(n) )
p r i n t (f i b o ( 4 0 ) )
Rcursivit 221
La solution rcursive sim ple sature rap id em en t les ressources de la m achine, qui exige u n
tem ps n o n ngligeable (de Tordre 3 m inutes sur u n o rd in ateu r avec processeur 32 bits d 1 Ghz
sous Linux) avant de dlivrer u n e rponse p o u r f ib o ( 40 ). En revanche, le second program m e
d o nne presque im m d iatem en t la rponse.
H orm is les feuilles (toujours gales 1 d aprs la dfinition m ath m atiq u e de la suite de
F ib o n a c c i ), le calcul de chaque n u d d em an d e laddition de deux sous-arbres. On n o te im
m diatem ent que certains sous-arbres identiques ap p araissen t rap id em en t plusieurs re
prises. De tels sous-arbres vont grossir avec lau g m en tatio n du rang du term e calculer ; le
gaspillage de ressources qui en rsulte est considrable.
Ces exercices sont loccasion d voquer lefficacit et la com plexit d u n algorithm e. Lpoque
nest pas si loigne, o les ordinateurs taien t largem ent m oins vloces, avec des units de
calcul op ran t sur des donnes de plus petites tailles, et dots d u n e m m oire de travail trs
restreinte (seulem ent quelques m ega-octets de m m oire vive et des processeurs d o n t la vi
tesse tait m esure en MHz).
TJ
O
c 1.2.1 Drcursification
rj
JD
tH
D ans certains cas, on p eu t drcursifier u n program m e. Prenons lexem ple d u n program m e
O n u m ran t la liste des entiers de 0 9 :
CM
(y)
xz d e f bo u cle (n ): i = 0
OJ
if n > 0 : w h ile i < 1 0 :
>-
Q. boucle(n - 1) p r i n t (i)
O
U p r i n t (n) i = i + 1
boucle(9)
Les deux program m es p ro duisent la liste atten d u e. Le second program m e est itratif, ce qui
nous contraint lem ploi des affectations de variables.
Nous avons substitu une boucle itrative la dfinition rcursive.
222 Programmation en Python pour les mathmatiques
b = 1 f o r i in r a n g e !n ) :
f o r i in ra n g e (n ) a, b = a + b, a
t = a re tu rn b
a += b
b = t fo r n in r a n g e !1 2 ):
re tu rn b p r in t !fib o!n))
fo r n in ra n g e ( 12 ):
p r in t (fibo(n))
1.3 Complexit
1 .3 .1 M o t iv a t io n s : c e q u i e s t a t t e n d u d u n a lg o r it h m e
En algorithm ique com m e en program m ation, on aborde les questions suivantes afin d a p p r
cier la validit et la qualit d u n algorithm e ou d u n program m e.
- preuve de term inaison (lexcution sachve et lalgorithm e se term ine en u n nom bre
fini d tapes) ;
- efficience (lalgorithm e ralise bien ce pourquoi il est conu) ;
- spcification com plte : de m m e que les hypothses d un nonc ou le dom aine de
a dfinition d u n e fonction sont bien tablis, les tapes et instructions qui co m p o sen t
O
c lalgorithm e sont toutes p arfaitem en t dterm ines, p ar leur n atu re et par les donnes
13
sur lesquelles elles sappliquent.
UD
O
(N
1 .3 .2 Q u e m e s u r e -t -o n ?
1 .3 .3 M e s u r e s e x p r im e n t a le s s u r u n p r o g r a m m e r e l
On p eu t effectuer des m esures lors du d ro u lem en t d u n calcul sur u n e m achine. Cela nest
pas toujours possible. Cette approche nest pas souhaitable p o u r des program m es critiques,
com m e ceux qui gouvernent u n calculateur em b arq u p o u r la gestion d u n vol aronautique,
ou le contrle des quipem ents d une centrale nuclaire.
Rcursivit 223
Ces m esures, lorsquelles sont possibles, sont relatives lenvironnem ent m atriel d excu
tion du program m e : architecture de lo rd in ateu r hte, perform ances des processeurs, dispo
nibilit de la m m oire en q u antit suffisante...
Les calculs sur ord in ateu r sont souvent loccasion des nom bres rels m achine , d o n t la m a
trise des arrondis dans les calculs approchs doit tre envisage d em ble avec prcaution.
N anm oins, nous nous lim iterons ici lvocation de la com plexit tem porelle que nous n o
terons t{n).
t{n) est une fonction de N dans p o u r laquelle n ous devons prciser la nature de n :
1 .3 .5 U n e x e m p le : c o t e n t e m p s d u n e f o n c t io n it r a t iv e
a
O
c 10
D
N o u s r e p r e n d r o n s l e x e m p le d e la s o m m e i.
i= l
O somme.py
]
d e f som m e(n): # (0)
4-1
s = 0 # (1)
a i
i = 1 # (2)
>-
Q. w h ile i <= n: # (3)
O
U s = s + i # (4)
i = i + 1 # (5)
re tu rn s # (6)
p r i n t (somme( 1 0 ) ) # (7)
C h a c u n e d e s in s t r u c t io n s (i) p o s s d e u n c o t d e x c u t io n e n t e m p s q u e n o u s n o t e r o n s c/
224 Programmation en Python pour les mathmatiques
- Cl = cz s i o n s u p p o s e q u e t o u te s le s a ffe c t a t io n s l m e n t a ir e s o n t la m m e d u r e ;
- le c o t C 3 s e d c o m p o s e e n u n c o t fix e p o u r le te st, p u is s e lo n le c a s e n u n c o t d e
b r a n c h e m e n t a p r s la f in d e la b o u c le , o u e n n fo is le c o t d u c o r p s d e la b o u c le ;
- C4 = C5 = c+ + C l s o n t le s c o t s d 'in s t r u c t io n s c o m p o s e s d u n e a d d it io n et d u n e a ffe c
t a t io n , et c+ d s ig n e le c o t d u n e in s t r u c t io n d a d d it io n e n tre d e u x n o m b r e s ;
- Ce e st le c o t d u r e t o u r d e f o n c t io n ;
- C7 e st le c o t c o m p o s d u c o t d a p p e l d e f o n c t io n ( e m p ile m e n t d e s p a r a m t r e s , b r a n
c h e m e n t ) et d u c o t d a f f ic h a g e d e la v a le u r c a lc u l e ( d p ile m e n t ) .
S e lo n q u e l o n c o n s id r e q u e c e r t a in e s o p r a t io n s s o n t l m e n t a ir e s o u n o n , o n in f lu e s u r la
g r a n u la r it et l e s t im a t io n d u c o t .
N o u s p o u v o n s m a in t e n a n t e ffe c t u e r n o t re c a lc u l d u c o t d e x c u t io n C{n) :
= Ki n + Kz
N o u s c o n s t a t o n s u n c o t a f f in e e n n. S e lo n la n o t a t io n d e L a n d a u , n o u s a v o n s : C{n) = 0 (/ 7 ).
C e t te g a lit e x p r im e ( n o u s s o m m e s e n p r s e n c e d e f o n c t io n s p o s it iv e s ) :
c a r le p r o g r a m m e c o r r e s p o n d a n t e st l u i e n 0 ( 1 ), c e s t - -d ir e e n t e m p s c o n s t a n t , q u e lle q u e
s o it la v a le u r d e n.
TJ
O
c
rj 1.4 Complexit des algorithmes de tri
JD D ans ce paragraphe, on tudie la com plexit des algorithm es de tri prsents dans la sec
O tion 13 en fin du prem ier chapitre.
rs]
(S)
a) Com plexit du tri par slection :
ai La relative sim plicit de cet algorithm e fait q u on lui attribue le qualificatif d algo
'1^
> rithm e naf. Cela signifie que m m e si lalgorithm e est correct, il est trop naf p o u r tre
CL
O
U rellem ent efficace.
la prem ire itration, sont effectues (/7-1) com paraisons. la p-im e itration, so n t
effectues { n - p ) com paraisons. Soit u n e com plexit en 0(/7^) d o n t on peu t o b ten ir u n e
reprsen tation en d o n n a n t u n cot unitaire aux oprations atom iques :
n-l 1
^ i n - p ) = - { m - n).
p=i ^
Rcursivit 225
n Y
Y,ip-l) = -n).
p = 2 ^
C ependant, en m oyenne, seule la m oiti des lm ents est dcale. Soit u n dcalage de
{p - l)/2 lm ents et donc une com plexit en m oyenne qui se calcule ainsi :
p = 2 ^ ^
Il sagit d une com plexit en 0{n^-) analogue la com plexit du tri par slection. C epen
dant, le tri p ar insertion prsen te u n avantage certain : il p e u t tre facilem ent m is en
uvre p o u r insrer de nouvelles d o n n es dans u n tableau dj tri ou p o u r trier des va
leurs au fur et m esure de leur ap p aritio n (cas des algorithm es en tem ps rel o il faut
parfois exploiter u n e srie de valeurs tries qui vient senrichir, au fil d u tem ps, de n o u
velles valeurs). Cest lu n des seuls algorithm es de tri d o n t la com plexit est m eilleure
q u an d le tableau initial possde u n certain ordre .
c) Com plexit du tri rapide :
La com plexit du tri rapide p o u r trier u n e liste de n lm ents est gale la com plexit
p o u r le tri de p e t d e q lm ents oh p + q + l = n. Soit C{n) = C{p) + C{q) + c o n s ta n te .
D ans le m eilleur des cas, p = q = nl2, soit C{n) = 2C{q). On p eu t alors m o n trer que la
com plexit en m oyenne est en 0(/7 ln()).
2 S p ira le d e p e n ta g o n e s
TJ
O La spirale rgulire ci-dessous est constitue de 50 pentagones (la longueur du
E x e r c ic e 5 9 .
c
D
plus grand ct tan t 370 pixels), em bots de sorte q u entre deux pentagones conscutifs
JD inscrits lu n dans lautre, le ct du plus p etit est u n e rduction de 10 % du ct du plus grand.
't H
O
C
M P rogram m er le dessin de cette spirale.
ai
>
CL
O
U
226 Programmation en Python pour les mathmatiques
S o lu t io n .
p e n ta g o n e s , p y
from math im p o r t *
from t u r t l e im p o rt *
d ef p e n ta g o n e (c o te ):
f o r n in ra n g e (5 ):
fo rw a rd (c o te )
le f t ( 7 2 )
d e f s p ir a le ( n o m b r e _ t r ia n g le s , c o te ):
co e ff = 0 . 1
a = c o te
d = co e ff * a
f o r i i n r a n g e ( n o m b r e _ t r ia n g le s ) :
p e n ta g o n e (a )
d = co e ff * a
fo rw a rd ( d )
a .p r im e = s q r t ( ( a -d ) * * 2 + d**2 - 2 * ( a - d ) * d * ( l - s q r t ( 5 ) ) / 4 )
a n g le = ( 1 8 0 / p i) * a c o s ( ( a _ p r im e * * 2 + a * * 2 - 2 * a * d ) / ( 2 * a _ p r im e * ( a -d ) ))
le f t ( a n g le )
a = a _ p rim e
up( )
g o t o ( - 1 9 0 , -2 1 0 )
d o w n()
s p ir a le ( 5 0 , 37 0 )
up( )
3 C o u rb e du d ra g o n
a L a c o u r b e d u d r a g o n e st u n e a u tr e a p p lic a t io n d e la r c u r s iv it .
o
c
=3 d ra g o n l. p y
Q
tH
o from math im p o r t s q r t
fNJ
from t u r t l e im p o rt *
(S)
x:
oi d e f d r a g o n _ g a u c h e ( t a ille , n iv e a u ) :
> c o lo r ( " re d " )
Q.
O if n iv e a u == 0 :
u
f o r w a r d ( t a ille )
e ls e :
le f t ( 4 5 )
d r a g o n _ g a u c h e ( t a ille / s q r t ( 2 ) , n iv e a u - 1 )
r ig h t ( 9 0 )
d r a g o n _ d r o it e ( t a ille /s q r t ( 2 ) , n iv e a u - 1 )
le f t ( 4 5 )
Rcursivit 227
d e f d r a g o n _ d r o it e ( t a ille , n iv e a u ) :
c o l o r " b lu e " )
i f n iv e a u == 0 :
f o r w a r d ( t a ille )
e ls e :
r ig h t ( 4 5 )
d r a g o n _ g a u c h e ( t a ille / s q r t ( 2 ) , n iv e a u - 1 )
l e f t (90)
d r a g o n _ d r o it e ( t a ille /s q r t ( 2 ) , n iv e a u - 1 )
r ig h t ( 4 5 )
d r a g o n _ d r o it e ( 4 0 0 , 12)
L a c o u r b e d u d r a g o n p a v e le p la n , c o m m e le m o n t r e la fig u r e s u iv a n t e
d ra g o n 2 .p y
from math im p o rt s q r t
from t u r t l e im p o rt *
d e f d r a g o n _ g a u c h e ( t a ille , n iv e a u ) :
i f n iv e a u == 0 :
TJ
O f o r w a r d ( t a ille )
c
rj e ls e :
JD le f t ( 4 5 )
t H
O d r a g o n _ g a u c h e ( t a ille / s q r t ( 2 ) , n iv e a u - 1 )
CM
r ig h t ( 9 0 )
(y)
d r a g o n _ d r o it e ( t a ille /s q r t ( 2 ) , n iv e a u - 1 )
XI
OJ le f t ( 4 5 )
>-
Q.
O d e f d r a g o n _ d r o it e ( t a ille , n iv e a u ) :
U
i f n iv e a u == 0 :
f o r w a r d ( t a ille )
e ls e :
r ig h t ( 4 5 )
d r a g o n _ g a u c h e ( t a ille / s q r t ( 2 ) , n iv e a u - 1 )
le f t ( 9 0 )
d r a g o n _ d r o it e ( t a ille /s q r t ( 2 ) , n iv e a u - 1 )
228 Programmation en Python pour les mathmatiques
r ig h t ( 4 5 )
def f ig u r e ( ):
c o lo r " re d ")
d ra g o n _ g a u c h e {2 O 0 , 10 )
u p ()
g o t o ( 0 , 0)
r ig h t ( 9 0 )
d o w n )
c o l o r " b lu e " )
d r a g o n _ g a u c h e 2 0 0 , 10 )
u p )
g o t o 0 , 0)
r ig h t 9 0 )
d o w n )
c o lo r "g re e n ")
d ra g o n _ g a u c h e 2 0 0 , 10 )
u p )
g o t o 0 , 0)
r ig h t 9 0 )
d o w n )
c o lo r "g ra y " )
d r a g o n _ g a u c h e 2 0 0 , 10 )
u p )
f ig u r e )
4 T ria n g le d e S ie rp iiis k y
UD
tH
o
rs]
XI
CTl
>-
Q.
O
u
s ie r p in s k y l.p y
I from t u r t l e im p o rt *
Rcursivit 229
d e f d r a p e a u ( lo n g u e u r , n iv e a u ) :
i f n iv e a u == 0 :
f o r w a r d ( lo n g u e u r )
e ls e ;
d r a p e a u ( lo n g u e u r /2 , n iv e a u - 1 )
le f t ( 1 2 0 )
d r a p e a u ( lo n g u e u r /2 , n iv e a u - 1 )
le f t ( 1 2 0 )
d r a p e a u ( lo n g u e u r /2 , n iv e a u - 1 )
le f t ( 1 2 0 )
f o r w a r d ( lo n g u e u r )
d e f t r ia n g le ( lo n g u e u r , n iv e a u ) :
fo r i in r a n g e ( 3 ) :
d r a p e a u ( lo n g u e u r , n iv e a u )
le f t ( 1 2 0 )
t r ia n g le ( 6 0 0 , 5)
A v e c u n p e u d e c o u le u r :
s ie r p i n s k y 2 . p y
from t u r t l e im p o rt *
d e f d r a p e a u ( lo n g u e u r , n iv e a u ) :
i f n iv e a u == 0 :
d o w n()
cap = h e a d in g i)
i f cap == 0 o r cap == 18 0 :
c o l o r r re d " )
if cap = = 60 o r cap == 2 4 0 :
c o lo r ( " g r e e n " )
if cap = = 12 0 o r cap == 30 0 :
c o l o r " b lu e " )
f o r w a r d ( lo n g u e u r )
TJ
O up( )
c
rj e ls e :
JD d r a p e a u ( lo n g u e u r /2 , n iv e a u - 1 )
t H
O le f t ( 1 2 0 )
CM
d r a p e a u ( lo n g u e u r /2 , n iv e a u - 1 )
(y)
le f t ( 1 2 0 )
XI
OJ d r a p e a u ( lo n g u e u r /2 , n iv e a u - 1 )
>- le f t ( 1 2 0 )
Q.
O f o r w a r d ( lo n g u e u r )
U
d e f t r ia n g le ( lo n g u e u r , n iv e a u ) :
fo r i in ra n g e ( 3 ) :
d r a p e a u ( lo n g u e u r , n iv e a u )
le f t ( 1 2 0 )
t r ia n g le ( 6 0 0 , 6)
230 Programmation en Python pour les mathmatiques
A B C e st u n t r ia n g le , M e st u n p o in t q u e lc o n q u e .
a) C h o is ir a u h a s a r d T u n d e s t r o is p o in t s A , B et C .
b) C o n s t r u ir e le p o in t M i m ilie u d u s e g m e n t lia n t le p o in t p r c
d e n t a u p o in t M .
c) R e c o m m e n c e r la p r e m i r e ta p e e n f a is a n t jo u e r a u p o in t M ]
le r le d u p o in t M .
O B ie n v id e m m e n t , i l fa u t p o u r s u iv r e l a lg o r it h m e a s s e z lo n g t e m p s s u r le p a p ie r p o u r o b s e r v e r
O
c
n q u e lq u e c h o s e , s a n s c o m p t e r le s s e g m e n t s [ M / M / + i ] u n iq u e m e n t u t ile s la c o n s t r u c t io n m a is
Q
kD q u i e n c o m b r e n t le d e s s in . ..
O
(N C e t a lg o r it h m e d o n n e la fig u r e s u iv a n t e , r a lis e a v e c le p r o g r a m m e s i e r p i n s k y 3 . p y . C e
(y) p r o g r a m m e f a it a p p e l u n n o u v e a u t y p e o b je t d f in i p a r le p r o g r a m m e u r p o u r r e p r s e n t e r
u n o b je t p o in t d u p la n , re p r p a r se s c o o r d o n n e s c a r t s ie n n e s et d o t d u n e c o u le u r .
ai
> s ie r p in s k y S .p y
Q .
O from math im p o rt s q r t
U
im p o r t random
from t u r t l e im p o rt *
d e lt a = -3 0 0
lo u p e = 600
c la s s p o in t ( o b je c t ) :
Rcursivit 231
...... P o in t du p la n ......
d e f m i l i e u ( s e l f , p, c o u le u r = " b la c k " ) :
s e lf .x = ( s e lf .x + p .x ) /2
s e lf .y = ( s e lf .y + p .y ) /2
s e l f . c o u l e u r = c o u le u r
d e f r o u g e ( s e lf ) :
s e l f . c o u l e u r = "re d "
def v e r t ( s e lf ):
s e l f . c o u le u r = "g re e n '
def b le u ( s e lf ) :
s e l f . c o u l e u r = " b lu e "
def c r o ix ( s e lf ):
d o w n()
fo r i in ra n g e (4 ):
fo rw a rd (3)
b a c k w a rd (3 )
l e f t (90)
upO
d e f im p r im e ( s e lf ) :
g o t o ( s e lf . x * lo u p e + d e l t a , s e lf . y * lo u p e + d e lt a )
c o l o r ( s e l f . c o u le u r )
s e l f . c r o ix ( )
TJ d ef f ig u r e ( p o in t s ) :
o
c
n a = p o in t ( 0 . 0 , 0 .0 , " re d " )
b = p o i n t ( 1 . 0 , 0 .0 , " g re e n " )
UD
t
o
H
c = p o in t ( 0 . 5 , s q rt(3 )/2 , " b lu e " )
CM
f o r i i n r a n g e ( p o in t s ) :
# o b t e n t io n a l a t o i r e du p o i n t s u iv a n t :
# m ( i + l ) = m i l i e u [ m ( i ) , a ou b ou c]
a le a = ra n d o m .ra n d ra n g e (3 )
if a le a == 0 :
232 Programmation en Python pour les mathmatiques
m . m ilie u ( a )
if a le a == 1 :
m .m ilie u ( b )
if a le a = = 2 :
m . m ilie u ( c )
# o b t e n t io n a l a t o i r e de la c o u le u r du p o i n t
a le a = ra n d o m .ra n d ra n g e (3 )
i f a le a = = 0 :
m .r o u g e ( )
i f a le a = = 1 :
m . v e r t ()
if a le a = = 2 :
m . b le u ( )
m .im p rim e ()
upO
sp e e d ( " fa s t e s t" )
f ig u r e ( 2 0 O 0 )
L e p r o g r a m m e d o n n e u n e fig u r e c o m m e la s u iv a n t e :
A
A - A
T3 5 S o m m e s d e te rm e s d u n e s u i t e g o m t r i q u e
O
c
=3
Q O n la is s e e n e x e r c ic e l c r it u r e d u n p r o g r a m m e p o u r l o b t e n t io n d e s s o m m e s p a r t ie lle s d e la
+CX3
tH
O s r ie I ( |) '.
rsj i = l
L a to r t u e L O G O d u m o d u le s t a n d a r d t u r t l e p e r m e t d e d o n n e r a is m e n t u n e in t e r p r t a
t io n g o m t r iq u e d e la r p o n s e :
03
>
Q.
O
U
Rcursivit 233
from t u r t l e im p o rt * e n d _ f illi)
c o l o r " b la c k " )
def t r ia n g le _ v e r t ( c ) : f o r i i n r a n g e B ) :
c o lo r "g re e n ") f o r w a r d ic )
b e g in _ f ill( ) le f t il2 0 )
f o r i in ra n g e (3 )
fo rw a rd (c ) d e f c o m p le t n , c ) :
le f t ( 1 2 0 ) i f n > 0:
e n d _ f i l l () t r i a n g l e _ v e r t c)
c o l o r " b la c k " ) t r ia n g le _ b la n c ic /2 )
f o r i i n r a n g e B ) f o r w a r d ic / 2 )
fo rw a rd c) t r ia n g le _ m a r r o n ic / 2 )
le f t il2 0 ) backw ard i c / 2 )
le f t 5 0 )
d e f t r ia n g le _ b la n c ic ) f o r w a r d ic / 2 )
c o l o r " w h ite " ) r ig h t 6 0 )
b e g in _ f illi) c o m p le t in - 1 , c / 2 )
f o r i i n r a n g e i3)
fo rw a rd c) u pi )
le f t il2 0 ) g o t o i-3 0 0 ,-2 4 0 )
e n d -f ill ) d o w n i)
c o l o r " b la c k " ) c o m p le t i6 , 5 1 2 )
fo r i in r a n g e B )
fo rw a rd c) n o m F ic h ie r = "somme-geom"
le f t il2 0 ) h t i)
t s = g e t s c r e e n i)
d e f t r ia n g le _ m a r r o n ic ; t s .g e t c a n v a s i) . p o s t s c r i p t if i l e =
c o l o r "m aro o n ") " { 0 } . e p s " . f o r m a t in o m F ic h ie r ) )
b e g in _ f ill ) im p o rt os
f o r i i n r a n g e B ) o s . s y s t e m i" e p s t o p d f
f o r w a r d ic ) { 0 } . e p s " . f o r m a t in o m F ic h ie r ) )
le f t il2 0 ) m a in lo o p i)
a
o
c
=3 6 E x e r c i c e s d e n t r a n e m e n t
Q
1
1 Les corrigs sont disponibles sur le site dunod.com partir de la page daccueil de louvrage.
o
r\i
xgi: P o u r c e tte s r ie d e x e r c ic e s , l o b je c t if e st d e c o n c e v o ir d e s p r o g r a m m e s r c u r s if s f a is a n t a p
s_ p e l la n o t io n d e b o u c le d it r a t io n , s a n s p o u r a u t a n t u t ilis e r le s c o n s t r u c t io n s f o r et w h i l e
>-
CL d f in ie s d a n s le la n g a g e P y t h o n .
o
u
E x e r c ic e 6 0 .
a) c r ir e u n p r o g r a m m e p r o d u is a n t u n e t a b le d e m u lt ip lic a t io n p o u r u n e n t ie r d o n n .
L u t ilis a t e u r c h o is ir a e n e n tr e l e n t ie r et le n o m b r e d e m u lt ip le s .
b) P r o p o s e r u n e v e r s io n d u p r o g r a m m e p r c d e n t d o n n a n t la m m e ta b le e n o rd r e in v e r s e
id c r o is s a n t ) .
234 Programmation en Python pour les mathmatiques
c) c r ir e u n p r o g r a m m e d e c a lc u l d e l a r r a n g e m e n t = n i n - l ) { n - 2 ) . . . { n - k + l ) , o
n e t k s o n t d e u x e n t ie r s n a t u r e ls v r if ia n t : k ^ n.
P o u r c e la , c o n s t r u ir e r c u r s iv e m e n t u n e b o u c le it r a n t u n e n t ie r n a t u r e l.
E x e r c ic e 6 1 .
C o n c e v o ir d e u x f o n c t io n s m u t u e lle m e n t r c u r s iv e s p a i r ( ) e t i m p a i r O q u i in d iq u e n t s i le u r
p a r a m t r e e n a p p e l e st u n n o m b r e p a ir o u im p a ir .
E x e r c ic e 6 2 .
E n e m p lo y a n t le m o d u le t u r t l e d e P y t h o n ,
c r ir e u n p r o g r a m m e r a lis a n t la f ig u r e c i-
c o n t r e , d a n s la q u e lle le c a r r in t r ie u r p o s
s d e u n c t d e 5 0 p ix e ls , et le s g n o m o n s
s o n t r e c t a n g le s is o c le s , d u n e p a is s e u r d e
10 p ix e ls :
E x e r c ic e 6 3 .
X d s ig n e u n n o m b r e r e l.
c r ir e , d a n s u n e f o r m e r c u r s iv e et s a n s r e c o u r ir a u x r o u t in e s s t a n d a r d d u la n g a g e , u n e f o n c
t io n q u i c a lc u le u n e a p p r o x im a t io n d e c o 5 ( x ), x t a n t e x p r im e n r a d ia n s . O n u t ilis e r a le d
v e lo p p e m e n t lim it l o rd r e 6 d e la f o n c t io n c o s in u s a u v o is in a g e d e 0.
O n p o u r r a o b s e r v e r t itre d e c o m p a r a is o n la s o r t ie a v e c c e lle d e la f o n c t io n m a t h m a t iq u e
c o s d e P y t h o n , d is p o n ib le d a n s le m o d u le s t a n d a r d m a th .
E x e r c ic e 6 4 .
O n u t ilis e r a u n iq u e m e n t le t y p e e n t ie r ( in t ) d e P y t h o n p o u r c e t e x e r c ic e . 11 s a g it d c r ir e
u n e f o n c t io n q u i r e n d la p a r t ie e n t i r e d e la r a c in e c a rr e d u n n o m b r e e n t ie r n a t u r e l.
E x e r c ic e 6 5 . ( F r a c t io n s c o n t in u e s - F p a r t ie )
P o u r le n o m b r e r a t io n n e l o n p e u t d o n n e r u n d v e lo p p e m e n t s o u s fo rm e d e f r a c t io n
"O
O c o n t in u e (to u s le s n u m r a t e u r s s o n t g a u x 1) :
c
=3
Q 111 1
= 2-b
O l "
(N 1+
1
3+
1
2+-
03 4
>.
CL
O q u e l o n c r ir a s o u s la f o r m e c o n d e n s e : [ 2 , 1 , 3 , 2 , 4 ] .
U
c r ir e u n p r o g r a m m e q u i d o n n e la r e p r s e n t a t io n e n f r a c t io n c o n t in u e d u n n o m b r e r a t io n
n e l, e n f o r m e c o n d e n s e . O n e n v is a g e r a le c a s d e s n o m b r e s n g a t ifs .
O n com p lte ra cette tude avec le c a lc u l des rduites, dans u n exercice d u ch a p itre 6.
Rcursivit 235
E x e r c ic e 6 6 .
O n se p r o p o s e d c r ir e q u e lq u e s o u t ils p o u r m a n ip u le r le t y p e l i s t s t a n d a r d d e P y t h o n :
- u n e f o n c t io n t e t e ( ) : e lle r e t o u r n e le p r e m ie r l m e n t d e la lis t e e n a r g u m e n t ;
- u n e f o n c t io n s u i t e { ) : e lle r e t o u r n e u n e n o u v e lle lis te , o b t e n u e p a r s u p p r e s s io n d e
la tte d e la lis t e e n a r g u m e n t . L a lis t e p a s s e e n a r g u m e n t d o it re s te r in t g re a p r s a p p e l
d e la f o n c t io n ;
- u n e f o n c t io n c o u p e ( ) : e lle r e t o u r n e la lis t e q u i r s u lt e d e la s u p p r e s s io n d e s n p r e
m ie r s l m e n t s , lo r s q u e la s u p p r e s s io n e st p o s s ib le ;
- u n e f o n c t io n d e b u t ( ) : e lle r e t o u r n e la lis t e d e s n p r e m ie r s l m e n t s .
def t e t e ( lis t e ) :
p a s s # code c r i r e i c i
def s u it e ( lis t e ) :
p ass
d e f c o u p e (n , l i s t e ) :
p ass
d e f debut(n, l i s t e ) :
p ass
Q u e lq u e s e x e m p le s d 'e m p lo i d e c e s p r im it iv e s e n m o d e in t e r a c t if :
> im p o r t random
> from o u t i l s im p o rt *
> hasard = [ random.randrange(50) f o r t in ra n g e (2 0 )]
> hasard
[48, 9, 16, , 38, 46, 27, 45, 11, 44,
8 47, 3, 47, 10, 12, 10, 32, 18, 13, 41]
> re ch e rc he( te te (ha sar d) , hasard)
T rue
TD > t e t e (hasard)
O 48
c
13
Q > suite(hasard)
yo [9, 16, , 38, 46, 27, 45, 11, 44, 47,
8 3, 47, 10, 12, 10, 32, 18, 13, 41]
O > debut( , hasard) 2
fM
(5) [48, 9]
XI
> coupe( , hasard) 2
Sommaire
Graphes.................................................................................................. 238
1.1 Prsentation............................................................................................. 238
1.2 Quelques questions u s u e l l e s ..................................................................239
1.3 Parcours eulriens.................................................................................... 240
Reprsentation des nombres................................................................ 243
2.1 Quelques rappels et o u t i l s ..................................................................... 244
2.2 Une premire tentative et un c h e c ......................................................246
2.3 Une seconde tentative.............................................................................. 247
2.4 Une classe pour les entiers..................................................................... 248
2.5 Une classe pour les rationnels............................................................... 252
Listes ..................................................................................................... 257
3.1 Trois versions du tri rcursif dune liste................................................257
3.2 Une classe pour encapsuler linformation.............................................260
3.3 Une classe pour la structure de q u e u e ................................................263
3.4 Une classe pour la structure de pile......................................................265
Arbres binaires....................................................................................... 266
4.1 Une classe pour la structure de nud d o u b l e ....................................266
TJ
O 4.2 Une classe pour la structure darbre binaire de r e ch erc h e .............. 272
c
rj
Calculateur............................................................................................ 275
JD
tH
5.1 Des choix de conception : composition, hritage, polymorphisme 275
O
CM
5.2 Le projet calculateur .............................................................................. 277
(y)
XI
5.3 Notations infixe, prfixe et postfixe................................................279
OJ
5.4 Grammaire et notation B N F .................................................................. 286
>-
Q. Polynmes et fractions rationnelles .................................................. 291
O
U
6.1 Prsentation du projet c a l c 3 .................................................................. 291
6.2 Exemples dutilisation de calc3 ............................................................ 292
6.3 Les types et leurs oprations.................................................................. 296
6.4 Pour aller plus loin ................................................................................. 299
Exercices dentranement...................................................................... 300
Classes 237
L a p r o g r a m m a t io n e st s o u v e n t l o c c a s io n d e m a n ip u le r d e s in f o r m a t io n s , d o n t l in t r t r s id e
d a n s le r e g r o u p e m e n t s o u s f o r m e d u n e c o lle c t io n ; le n o m b r e d l m e n t s d u n e t e lle c o lle c
t io n p e u t n e p a s tre c o n n u a v a n t l u t ilis a t io n d u p r o g r a m m e , o u d u m o in s p e u t tre a m e n
v a r ie r a u c o u r s d e l e x c u t io n d u p r o g r a m m e . L e s o b je t s d u n e te lle c o lle c t io n p e u v e n t tre
d e n a t u r e h t r o g n e o u n o n , c o m m e ils p e u v e n t tre o r g a n is s o u n o n , s e lo n d e s c r it r e s
p e r t in e n t s d f in is p a r le p r o g r a m m e u r p o u r le s b e s o in s d u p r o b l m e r s o u d re .
N o u s t r a it e r o n s d a n s c e c h a p it r e d e d o n n e s o r g a n is e s s o u s f o r m e s q u e n t ie lle d e lis te s , o u
d e d o n n e s o r g a n is e s s o u s f o r m e d a r b r e s b in a ir e s . E n p r e m i r e a p p r o c h e , n o u s d is t in g u e
r o n s d e u x u s a g e s d if f re n t s q u i c o n s t it u e r o n t u n c r it r e d e c h o ix p o u r l u n e o u l a u tr e s t r u c
t u re : lo r s q u e q u e l in s e r t io n o u la s u p p r e s s io n d u n l m e n t s e ffe c t u e n t t o u jo u r s e n m m e
p o s it io n d a n s la lis te , u n e s t r u c t u r e d e lis t e ( p ile o u file ) e st s o u v e n t a p p r o p r i e ; e n r e v a n c h e ,
s i u n b e s o in d e c o n s e r v a t io n d e l o rd r e d e s l m e n t s e st e s s e n t ie l, a p r s in s e r t io n o u s u p p r e s
s io n , u n e s t r u c t u r e d a r b r e b in a ir e d e v r a tre p r f r e .
N o u s r a p p e lo n s , c o m m e n o u s a v o n s d j p u le r e n c o n t r e r lo r s d e c h a p it r e s p r c d e n t s , q u e
la n g a g e P y t h o n f o u r n it n a t iv e m e n t le s o u t ils et s t r u c t u r e s d e d o n n e s n c e s s a ir e s l u t ilis a
t io n d e s lis te s . T o u t e f o is , la p r s e n t a t io n d e s lis t e s c o n s t it u e u n e p a r t im p o r t a n t e d e l a lg o
r it h m iq u e , et i l e st b o n d e c o n n a t r e le f o n c t io n n e m e n t in t e r n e d e c e t y p e c la s s iq u e d e s t r u c
t u re d e d o n n e s . E n f in , l t u d e d e s lis t e s p e r m e t t r a d e m ie u x a p p r h e n d e r e n s u it e la n o t io n
d a r b r e b in a ir e q u i, e lle , n e fa it p a s p a r t ie d u n o y a u d u la n g a g e .
C e c h a p it r e p r e n d p la c e d a n s u n e x p o s p lu s v a s t e s u r la n o t io n d e c la s s e , in h r e n t e la p r o
g r a m m a t io n o r ie n t e o b je t . E n effet, l im p l m e n t a t io n d e lis t e s o u s fo r m e d e c la s s e s d o b je t s
t ro u v e s a n c e s s it d a n s le s o u c i d e f o u r n ir a u p r o g r a m m e u r u n e s t r u c t u r e d e d o n n e s d o n t
l a b s t r a c t io n l u i p e r m e t d e c o n c e n t r e r s o n e ffo rt s u r le p r o b l m e r s o u d re , t o u t l u i e n o ffra n t
u n e s p a r a t io n d e s c o n c e p t s et u n b o n c o n f o r t d u t ilis a t io n et d e m a in t e n a n c e .
L o r s d e la c o n c e p t io n d e n o s c la s s e s , n o u s a u r o n s l o c c a s io n d e x a m in e r et d e m e tt r e e n u v r e
le s n o t io n s d e c o m p o s it io n et d h r ita g e .
N o u s p r e n d r o n s c o m m e f il d ir e c t e u r d e c e tte p r s e n t a t io n la r a lis a t io n d u n p e t it s y s t m e d e
c a lc u l p o u r le s n o m b r e s r a t io n n e ls d u n e p a r t , la m is e e n u v r e d u n a n n e a u d e p o ly n m e s
a c o e f f ic ie n t s d a n s Z d a u tr e p a r t .
O
c
=3
Q N o tr e t u d e d b o u c h e r a s u r la c o n c e p t io n d u n s y s t m e d e c a lc u l m a n ip u la n t u n c o r p s d e
'JD
*rH f r a c t io n s r a t io n n e lle s .
O
(N
A v a n t d e n t r e r d a n s le v i f d u s u je t , n o u s m e n t io n n o n s t o u t e fo is q u e lq u e s a v e r t is s e m e n t s :
*->
JO
ai - T o u s le s p r o g r a m m e s d e c e c h a p it r e o n t t c r it s et te st s a v e c u n e d is t r ib u t io n d e la
>-
Q. b r a n c h e 2 .6 d e P y t h o n . I ls s o n t c o m p a t ib le s a v e c le s v e r s io n s s u iv a n t e s 3 .x m a is ils n e
O
U t ir e n t n u lle m e n t a v a n ta g e d e s n o u v e lle s f o n c t io n n a lit s d u la n g a g e . E n p a r t ic u lie r , le
le c t e u r n o t e r a la c o n s e r v a t io n d e l in s t r u c t io n p r i n t e n lie u et p la c e d e la n o u v e lle
s y n t a x e p r i n t ( ) . I l y a ic i u n e s u b t ilit p o u r l in t e r p r t e u r P y t h o n q u i, e n v e r s io n s
a n t r ie u r e s , c o n s id r e le s p a r e n t h s e s s e lo n le c a s c o m m e le s ig n e d e la p r s e n c e d u n
tuple.
- E n f in , d a n s u n b u t d tu d e , n o u s n a v o n s p a s c h e r c h u t ilis e r to u te s le s p o t e n t ia lit s
d u la n g a g e q u i e n f o n t s o n o r ig in a lit . C e c h o ix e st m o t iv p a r la v o lo n t d e n e p a s
238 Programmation en Python pour les mathmatiques
F igure 6.1 - D e u x r e p r s e n t a t io n s d u m m e g r a p h e p la n a ir e ( n o n c o n n e x e )
m a s q u e r d e s a lg o r it h m e s o u d t a ils p a r F u t ilis a t io n d e p r im it iv e s p u is s a n t e s m a is d e
f a it o p a q u e s a u le c t e u r q u i s o u h a it e r a it t r a n s f r e r le s c o n c e p t s p r s e n t s v e r s u n
a u tre la n g a g e d e p r o g r a m m a t io n .
1 G ra p h e s
A v a n t d e n o u s p e n c h e r d a n s le s s e c t io n s s u iv a n t e s s u r le s n o t io n s d a r b r e et d e lis t e et q u e lq u e s -
u n e s d e le u r s a p p lic a t io n s , n o u s c o m m e n o n s ce c h a p it r e e n a b o r d a n t la n o t io n d e g r a p h e ,
q u i p e r m e t n o t a m m e n t u n e g n r a lis a t io n d e s d e u x n o t io n s p r c d e n t e s , a u s e n s o u n a r b r e
e st u n g r a p h e c o n n e x e s a n s c y c le .
S i la t h o r ie d e s g r a p h e s c o n s t it u e u n d o m a in e r c e n t a u re g a rd d e l h is t o ir e d e s m a t h m a
t iq u e s , i l n e n d e m e u r e p a s m o in s v a s t e et s o u r c e d e n o m b r e u x t r a v a u x c o n t e m p o r a in s . N o u s
lim it e r o n s d s lo r s n o t re p r o p o s l t u d e d e q u e s t io n s r e la t iv e s a u x g r a p h e s s im p le s , c e s t-
- d ir e s a n s a r te m u lt ip le n i b o u c le . N o u s c h o is is s o n s a u s s i d e r e s t e in d r e n o tre t u d e a u x
g r a p h e s n o n o r ie n t s a u x a r te s n o n p o n d r e s .
1.1 Prsentation
TJ D e u x t y p e s d e r e p r s e n t a t io n s o n t c o u r a m m e n t u t ilis s p o u r u n g r a p h e : u n e m a t r ic e d a d
O
c
rj ja c e n c e (fig u re 6 .2) et u n e lis t e d a d ja c e n c e . U n e m a t r ic e d a d ja c e n c e e st u n e m a t r ic e c a rr e
JD s y m t r iq u e ( p o u r u n g r a p h e n o n o r ie n t ) , d o n t le s l m e n t s ( d a n s n o t re c a s q u iv a le n t s d e s
tH
O b o o l e n s ) in d iq u e n t l e x is t e n c e o u n o n d u n e a r te e n tre d e u x s o m m e t s .
CM
L e p r o g r a m m e c i- a p r s illu s t r e u n e r e p r s e n t a t io n p a r lis t e d a d ja c e n c e d u g r a p h e 6 .1 :
ai lettres, py
> from graphe im p o rt *
CL
O
U
g = graphe!
{
A' [ B ', D'I,
B [ A ', C, D-, E ', ' F ' ] ,
C [ B' , F'],
D [ A' , B' , E ],
E* [ B' , D', F'],
Classes 239
p r in t ( " C h a n e s ( s ) l m e n t a ir e ( s ) e n t r e A e t F : " )
f o r c i n g .r e c h e r c h e _ c h a in e s ( " A " , " F " ) :
p r i n t (c )
p r i n t ()
p r in t ( " C h a n e s ( s ) l m e n t a ir e ( s ) e n t r e A e t G : " )
f o r c i n g . r e c h e r c h e _ c h a in e s ( " A " , " G" ) :
p r i n t (c )
L e m o d u le g r a p h e . p y q u i f o u r n it le t y p e g r a p h e n e st p a s r e p r o d u it i c i d a n s s o n in t g r a lit ,
m a is n o u s p o u v o n s o b s e r v e r s o n r s u lt a t l e x c u t io n p o u r le g r a p h e d o n n e n 6 .1 :
$ . / l e t t r e s py
C h a n e s ( s ) l m e n t a ir e ( s )
[ 'A , ' B ' , C ' , F' ]
[ A , ' B ' , D' , E', ' F' ]
[ 'A , ' B ' , E' , F ]
[ A , ' B ' , F ' ]
[ 'A , ' D' , B' , C- , 'F']
[ 'A , ' D' , B' , E- , 'F']
[ 'A , ' D' , B' , F' ]
[ A , ' D' , E' , B' , 'C, F ']
[ A , ' D' , E' , B' , 'F']
[ 'A , ' D' , E' , F ]
C h a n e s ( s ) l m e n t a ir e ( s )
a
$
O
c
D
N o u s p r o g r a m m o n s n o t re s t r u c t u r e d e g r a p h e c o m m e u n o b je t (a u s e n s d e la p r o g r a m m a
kD t io n ) d o n t l u n iq u e d o n n e in t e r n e e st u n e lis t e d a d ja c e n c e : u n e t e lle lis te e s t c o n s t it u e d e
tH
O
CM l e n s e m b le d e s s o m m e t s d u g r a p h e , et p o u r c h a q u e s o m m e t a d ja c e n t , la lis t e d e s s o m m e t s
(y) q u i l u i s o n t c o n n e c t s . N o u s c a r t o n s la r e p r s e n t a t io n p a r u n e m a t r ic e d a d ja c e n c e p o u r
xz u n e r a is o n d c o n o m ie d e m o y e n s ( p o u r le s g r a p h e s n o n c o m p le t s , le s c o e f f ic ie n t s d e la m a
CTI
>- t r ic e d a d ja c e n c e s o n t s o u v e n t e n m a jo r it n u is ) ; le p a s s a g e d u n m o d le l a u tr e c o n s t it u e
Q.
O c e p e n d a n t u n e x c e lle n t e x e r c ic e d e p r o g r a m m a t io n c o n f i a u le c te u r .
U
- U n g r a p h e e s t - il c o n n e x e ?
240 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
A B C D E F G H
i 1 i i i 1 i i
^0 1 0 1 0 0 0 0 ^ A
1 0 1 1 1 1 0 0 B
0 1 0 0 0 1 0 0 -c
1 1 0 0 1 0 0 0 D
0 1 0 1 0 1 0 0 -E
0 1 1 0 1 0 0 0 F
0 0 0 0 0 0 0 1 -G
. 0 0 0 0 0 0 1 0 J H
Nous avons ainsi constitu, dans le but de disposer doutils capables de manipuler plusieurs
graphes indpendamment les uns des autres au sein dun mme programme, une bote
outils organise sous la forme dune classe dobjet. Nous allons en dtailler les principales
mthodes :
Lexistence ventuelle de telles chanes ou cycles est assure par le thorme dEuLER - H ie r -
HOLZER. Un procd de construction de parcours eulriens est celui connu sous le nom d al
gorithme de F leu ry sur lequel nous avons bas notre mthode qui gnre un parcours eu-
lrien, chane ou cycle suivant le cas.
Nous disposons dans notre objet g ra p h e de deux mthodes e x is te n c e _ c h a in e _ E u le r ( )
et e x is te n c e _ c y c le _ E u le r{ ) pour tudier la question de lexistence. Dans laffirmative,
on utilise alors la mthode re c h e rc h e _ E u le r( ) pour la gnration dune solution au pro
blme.
g ra p h e , p y
>-
La traduction en programme Python de lalgorithme de F leu ry suit :
Q.
O g ra p h e .p y
U
def r e c h e r c h e _ E u le r (s e lf) :
""" algorithm e de F le u r y ..... .
g = s e lf
f in = (g . nom bre_aretes() == 1)
i f f in :
retu rn g.sommets!)
242 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
P = []
choix = []
fo r s in g . sommets( ) :
i f g.degre_sommet(s) % 2 == 1:
choix.append(s)
i f le n ( choix) == 0:
choix = g. sommets 0
a = c h o i x [ random.randrange(0, l e n ( c h o i x ) ) ]
w h ile not f i n :
U = g .a d ja c e n ts(a )
V = []
fo r s in u:
i f not g.est_un_pont(a, s ) :
v.append(s)
b = v [ random.randrange(0, le n ( v ) ) ]
p.append(a)
g = g . g r a p h e . r d u i t ( a , b)
a = b
f i n = (g.nombre_aretes() == 1)
p.append(a)
p . a p p e n d ( g . a d j a c e n t s ( a ) [0])
retu rn P
(y) ten u par la suppression de larte ci-dessus (et des prcdentes), avec po u r
xz som m et de d p art lextrm it de cette arte, et ainsi ju sq u puisem ent des
CTI
>- artes.
Q.
O La m thode r e c h e r c h e _ E u l e r ( ) im plm ente lalgorithm e de F l e u r y , avec u n e m odifica
U
tion dans linitialisation : on choisit d em ble u n som m et du graphe de degr impair, lorsquil
en existe, afin de construire dans ce cas un chem in eulrien. dfaut, u n som m et est choisi
alatoirem ent afin de construire u n cycle eulrien.
R em arquons q u la seconde tape, lorsque le seul choix possible est celui d u n pont, cela
signifie que le som m et de dp art est alors de degr 1, auquel cas le graphe rduit qui en rsulte
doit tre am p u t de ce som m et isol, afin de prserver la connexit.
C la sse s 243
Terminal
$ ./te s t_ g ra p h e s .p y
-- t e s t 7 .........
[''F D', 'C , B', A , G]
I . P .
-- t e s t 8 .........
[''1 1 ^ f
' O
3', '4 ',
'
t 1', 3' ]
-- t e s t 9 .........
[''1 '2 ']
-- t e s t 1 0 .........
['' c / ^
. .
a ', ' e ' ,
r f, g', a ', b' , 'c
-- t e s t 1 1 .........
[''4 ' ' 5 ' ' 1 ' ' 3 ' f f 2', 6', 1', '2 ' , '5
2 R e p r s e n ta tio n d e s n o m b re s
Nous allons construire quelques classes n u m riq u es destines reprsenter les nom bres p o u r
notre projet de systm e de calcul (quatre oprations et exponentiation) calculant convenable
-a
O m en t sur les nom bres rationnels.
c
M entionnons im m d iatem en t lexistence (depuis la version 2.6 du langage) des m odules n a
tJHD
O tifs f r a c t i o n . py et d c im a l. py , p rsents plus avant, qui am liorent la gestion des
rsl
calculs avec ce type de nom bres. Les classes p rsentes ici so n t bien sr plus m odestes, m ais
(S)
dcrites dans u n b u t d tude.
XI
CTI
>- Nous utiliserons par ailleurs des instances de classes que nous com poserons soigneusem ent
CL
O p o u r inclure une gestion des erreurs qui p eu v en t intervenir ds que nous effectuons u n e srie
U
de calculs en cascade.
En nous lim itant aux dcim aux, nous suivrons la d m arche axiom atique de co n stru ctio n des
nom bres traditionnellem ent adopte en M athm atiques, puis n ous adopterons les ides su i
vantes :
- un nombre dcimal est un rationnel dont dnominateur peut sexprimer sous la forme
2^ X5^, o P et dsignent des entiers naturels.
Ce choix peut paratre droutant, mais il est motiv par les raisons suivantes : la conception
dun langage et dun environnement de programmation se heurte toujours aux limites de
temps lexcution, et surtout de mmoire de travail. Il en rsulte des choix invitables dont
celui qui casse notre conception mathmatique moderne des nombres : nous ne pouvons re
prsenter quun nombre fini de nombres, en nature comme en quantit, dans une mmoire
de calculateur. Pire, le calculateur manipule des nombres fondamentalement cods en sys
tme binaire : les nombres machine ne reprsentent quune infime partie des nombres
mathmatiques, dont certains nont aucune reprsentation correcte possible sur un nombre
fini doctets, en dehors dapproximations.
Le langage Python en souffre comme tout autre langage, mme sil possde un avantage d
cisif dans sa capacit manipuler correctement les trs grands entiers, l o le langage C et
tant dautres se perdent ds quil sagit dajouter 1 et (2^)^ - 1 = 4294967295 (selon la norme
ANSI C99, pour un entier non sign cod sur quatre octets) ; les librairies (modules logiciels
additionnels apportant des extensions au langage de base) spcialises en calcul scientifique
ou les systmes de calcul formel prennent alors le relais dans une certaine mesure...
Nous examinerons en dtail une classe pour la reprsentation des nombres entiers, ainsi
quune classe pour les nombres rationnels.
Nous prvoyons pour de tels nombres les quatre oprations et lexponentiation, ainsi que
la possibilit pour le systme dvaluer les expressions o senchanent les diffrentes opra
tions. Nous devrons envisager les situations pour lesquelles le systme sera plac devant lva
luation dun nombre mathmatiquement indfini, et dcider dun comportement du systme
dans un tel cas.
def t r o n c _ u n it e ( x ) :
""" fonction troncature l'u n it """
re tu rn i n t ( x )
def E ( x ) :
.... fonction p a rtie e n tire (au sens mathmatique) """
i f X < 0:
X = X - 1
re tu rn tro n c - u n ite (x )
def p a r t ie _ f r a c ( x ) :
""" fonction p a rtie fraction n aire
re tu rn (x - E ( x ) )
def p a r t ie _ d e c ( x ):
""" fonction p a rtie dcimale
re tu rn (x - t r o n c _ u n it e ( x ))
b
x = e\a +
10'
avec {a, b, n) e N^, et dans laquelle e sera gal 1 ou -1 selon que notre dcimal est respecti
vement positif ou ngatif.
def fo rm e _f (v a le u r = 0):
""" retou rne le dcimal sous forme p/q ......
i f v a le u r == 0:
re tu rn 0
e p silo n = 1
V = v a le u r
i f V < 0:
e p silo n = -1
V = -V
a = E (v ) # c f . p lu s haut
"D V = p a rtie _ d e c (v ) # idem
O
c
D
b = 0
tH c = 1
O
w h ile V > 0:
V *= 10; t = E ( v ) ; V -= t
b = b*10 + t
ai
c *= 10
>-
Q.
O
U re tu rn s t r ( e p s ilo n * ( a * c + b )) + "/" + s t r ( c )
[ Terminal ]
C la sse s 247
-23/1
-22999999999999998223643160599749535322189331O546875/1OO00OO0000\
0000000000000000000000000000000000000000
Lchec est cuisant : lalgorithme est correct, mais inutilisable! Sans entrer ici dans le dtail,
disons simplement que lerreur provient de la reprsentation interne des nombres en P y th o n
(ce dfaut existe dans la majorit des langages, pour des raisons de conception des units
logiques de calcul). Nous reviendrons sur ces questions dans un autre chapitre.
n g a tif = (v a le u r < 0)
V = v a le u r
i f n g a tif:
V = -V
retu rn s t r ( p ) + "/" + s t r ( q )
248 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
p r i n t (fo rm e _f (- 2 3 ))
p r in t (fo r m e _ f r a c (- 2 .3 ))
Pour dfinir le m odle de notre type e n t i e r , nous choisissons deux variables d instance :
Nous dfinissons ci-dessous le con stru cteu r de notre classe de reprsen tatio n d u n nom bre
entier : il sagit en fait d une classe enveloppe, qui em barque u n nom bre entier (natif du la n
gage P y th o n ) agrg avec un descripteur d tat, in d iq u an t la validit de ce nom bre.
On n otera le fait que, m m e en cas d erreur, on veille ne pas rom pre le flot d excution du
program m e : une fonction est cense toujours rendre u n rsu ltat; il ap p artien t au pro g ram
m eur de toujours contrler la qualit (validit) du rsultat retourn p ar lappel de la fonction.
D un p o in t de vue conceptuel, on pourrait aller bien plus loin q u u n sim ple in d icateu r de
validit, en laborant une structure m athm atique. Cette structure do n n erait p o u r nos p ro
gram m es une classe super-nom bre p ar ladjonction, nos nom bres m athm atiques, d un
lm ent pas-u n -n o m b re , et en dfinissant de nouvelles oprations :
TJ
O
c
rj Voici le code :
c la s s e n t ie r ;
tH
O
def __ s t r __ ( s e l f ) :
i f s e l f ___v a lid e :
retu rn s t r ( s e l f ___v a le u r)
e ls e :
retu rn " ( e n t ie r in v a lid e ) "
C la sse s 249
Il nous faut discuter un choix surprenant : la dcision de construire chaque fois un nou
veau nombre e n tie r invalide pour forcer une erreur. Une mthode plus satisfaisante met en
uvre des concepts moins simples, mais nous entranerait bien plus loin que le cadre de ce
livre. Nous pourrions ainsi dfinir ce quon appelle selon la terminologie consacre des
motifs de conception un singleton, cest--dire un objet qui ne sera instanci quune
fois seulement pour lensemble du programme. Un singleton fait office de variable globale
pour le programme : le recours aux variables globales demeure une question non tranche.
En lespce, nous pourrions crer un singleton e n tie r construit sur les valeurs ( 0, False ),
sur lequel nous retournerions une rfrence chaque fois que nous avons besoin dutiliser
un e n tie r non dfini , par exemple issu dun calcul erron.
Poursuivons ltude de notre classe e n tier par quelques mthodes :
def e s t _ v a li d e ( s e lf ) :
retu rn s e l f ___v a lid e
def v a le u r ( s e l f ) :
retu rn i n t ( s e l f .v a le u r)
Pour ce qui concerne la gestion des erreurs, nous avons simplement pris le parti dutiliser une
variable boolenne. Pour obtenir un diagnostic plus fin des erreurs (par exemple, aprs ten
tative de crer un rationnel partir dun nombre nul au cours dune succession de calculs...),
un gestionnaire derreur devrait tre implment.
Nous prsentons ensuite les mthodes pour les oprations mathmatiques :
d e f __ add__ ( s e l f , a u t r e ):
i f s e l f ___ v a lid e and a u t r e ___ v a lid e :
retu rn e n t i e r ( s e l f ___v a le u r + a u t r e ___ v a le u r)
e ls e :
retu rn e n t ie r ( 0 , F a ls e )
def neg ( s e l f ) :
i f s e l f ___ v a lid e :
O
O retu rn e n t i e r ( - s e l f ___v a le u r)
c
n e ls e :
tJHD retu rn e n t ie r O , F a ls e )
O
CM
def sub ( s e l f , a u t r e ):
(y)
retu rn s e l f ___add__ (a u t r e ____neg__ ( ) )
xz
CTI
>- On remarquera que la seconde ligne de la mthode _add __( ) ne fait curieusement pas
Q.
O appel la mthode (publique) e s t _ v a l i d e ( ) dfinie au sein de la classe, mais elle utilise
U
directement la variable dinstance s e l f __ v a lid e . Cette mthode nest pourtant pas inutile.
Cest ici quil convient de distinguer deux utilisations de la valeur de validit :
- linstance de classe inspecte elle-mme son tat de validit. Linstance a accs toutes
ses variables internes, sans droger au principe dencapsulation des donnes. De sur
crot, passer une mthode alourdirait et ralentirait inutilement le programme ;
250 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
- par ailleurs, un objet extrieur utilisant la classe peut avoir besoin de contrler la va
lidit de le n t i e r quil manipule. La protection des donnes le prive de laccs aux
membres internes de la classe e n t i e r . Cest le rle de la fonction e s t_ v a lid e { ) que
de permettre de connatre ltat de validit dune instance, tout en respectant le carac
tre priv de linformation. Ce type de fonction destin apporter, si besoin et selon le
choix du programmeur, une visibilit linformation est appel accesseur en termi
nologie objet.
Lors de la conception dune classe dobjets, il est particulirement important dtre vigilant
quant lutilisation de linformation, car plusieurs utilisateurs (un programmeur qui utilise
un module, quil en connaisse ou non les dtails ; une mthode invoque depuis une classe ou
depuis lextrieur...) peuvent avoir ou non accs aux donnes, avec des privilges diffrents.
Cest le concepteur de la classe qui doit veiller toutes les utilisations possibles (lgitimes) de
son code.
Pour lensemble de nos programmes, nous rduirons souvent notre travail en considrant la
soustraction comme addition de loppos.
def __ mul__ ( s e l f , a u t r e ):
i f s e l f ___v a lid e and a u t r e ___ v a lid e :
retu rn e n t i e r ( s e l f ___v a le u r * a u t r e ___ v a le u r)
e ls e :
retu rn e n t ie r ( 0 , F a ls e )
def __ tru e d iv __ ( s e l f , a u t r e ):
i f n o t ( s e lf ___v a lid e and a u t r e ___ v a lid e ) :
retu rn e n t ie r ( 0 , F a ls e )
i f a u t r e ___v a le u r == 0:
retu rn e n t ie r ( 0 , F a ls e )
i f ( s e l f ___ v a le u r % a u t r e ___ v a le u r) != 0:
retu rn e n t ie r ( 0 , F a ls e )
retu rn e n t i e r ( s e l f ___ v a le u r / a u t r e ___ v a le u r)
P *= a
n //= 2
a *= a
retu rn e n t ie r(p )
yrH
> > b = e n t i e r ! -4)
O > X = a ** b
fM
> p rin t (x )
(e n t ie r in v a lid e )
JZ >
DI
s_
>.
CL
O On observera ici le fonctionnement du mcanisme de la surcharge doprateur : en raison de
U
la syntaxe particulire employe pour nommer nos oprateurs arithmtiques, P y th o n incor
pore en quelque sorte son propre langage ces nouvelles dfinitions. Ce mcanisme permet
donc dcrire de faon quivalente mais bien plus commode :
Term inai]
> X = a ___add__ (b)
> X = a H- b
252 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
Enfin nous compltons le fichier en tier .p y par deux fonctions, externes la classe elle-
mme, que nous utiliserons pour notre classe rationnel :
def p g c d _n a tu re ls(a , b ):
i f b == 0:
retu rn a
e ls e :
retu rn p g cd _n a tu re ls(b , a % b)
c la s s ra tio n n e l:
i f v a lid e :
i f type(num) == i n t :
num = entier(num )
i f type(denom) == i n t :
denom = entier(denom )
i f s e l f ___v a lid e :
i f d en o m .valeu r() < 0:
num, denom = -num, -denom
d = pgcd_entiers(num , denom)
s e l f ___num, s e l f ___ denom = num / d, denom / d
e ls e :
s e l f ___num, s e l f ___ denom = e n t ie r ( 0 ) , e n t ie r ( l )
La m thode suivante perm et d o bten ir u n e rep rsen tatio n de lobjet r a t io n n e l sous la form e
d u n e chane alphanum rique :
def __ s t r __ ( s e l f ) :
""" re p r s e n ta tio n sous forme de chane ......
i f s e l f ___ v a lid e :
i f s e l f ___d en o m .valeur() == 1:
retu rn s t r ( s e l f ___num)
i f v e r i f _ e n t i e r ( s e l f ___d en o m .valeur() ) :
retu rn s t r ( s e l f ___f lo a t __ ( ) )
e ls e :
a
O retu rn s t r ( s e l f ___num) -i- "/" -i- s t r ( s e l f ___ denom)
c
=3 retu rn " (ra t io n n e l in v a lid e ) "
Q
y1
>I
O def __ f lo a t __ ( s e l f ) :
(N
""" re p r s e n ta tio n sous forme de nombre r e l machine """
i f s e l f ___v a lid e :
03 a , b = s e l f ___n u m .v a le u r() , s e l f ___ d en o m .valeu r()
s_
> retu rn ( f l o a t ( a ) / f l o a t ( b ) )
Q.
O e ls e :
U
retu rn f l o a t (0)
On rem arquera lutilisation de valeurs p ar dfaut dans le co n stru cteu r (=0 et =1). Cette faci
lit nous p erm et sans effort supplm entaire de construire p ar la suite des nom bres ratio n
nels particuliers com m e les nom bres entiers (sans besoin cette fois de prciser le d n o m i
nateur) ; lappel du con stru cteu r sans p aram tre construira donc u n e instance rep rsen tan t
notre nom bre 0 ordinaire.
254 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
On observera aussi que le constructeur possde une taille cette fois bien plus imposante :
nous devons dabord vrifier les tats de validit, puis rduire les numrateur et dnomi
nateur, normaliser le nombre rationnel en imposant un dnominateur positif. Plus impor
tant, notre constructeur la mthode i n i t ( ) est en mesure de construire un nombre
rationnel depuis le type entier natif de P y th o n , comme depuis notre propre type en tier.
Nous mettons disposition de lutilisateur de la classe une mthode permettant la consul
tation, sous forme textuelle, de la fraction considre, ainsi quune mthode_f lo a t __{)
qui dlivre une valeur numrique du rationnel, au besoin sous la forme dune approximation
ralise par P y th o n lui-mme.
En procdant ainsi, nous avons limin la possibilit de construire un nombre rationnel
valide partir dun nombre en t i e r invalide comme numrateur ou dnominateur.
Nous pouvons procder lcriture de nos oprateurs mathmatiques pour laddition et la
soustraction :
def add ( s e l f , a u t r e ):
...... somme de deux r a t io n n e ls """
i f s e l f ___v a lid e and a u t r e ___ v a lid e :
a , b = s e l f ___num, s e l f ___ denom
P, q = a u t r e ___num, a u t r e ___ denom
retu rn ra tio n n e l(a * q + b*p, b*q)
e ls e :
retu rn r a t io n n e l(0 , 1, F a ls e )
def neg ( s e l f ) :
i f s e l f ___v a lid e :
a , b = s e l f ___num, s e l f ___ denom
retu rn r a t io n n e l(- a , b)
e ls e :
retu rn r a t io n n e l(0 , 1, F a ls e )
def sub ( s e l f , a u t r e ):
re tu rn s e l f ___add__ (a u t r e ____neg__ ( ) )
a
O
c N ous don n o n s p o u r la form e le p roduit et le q u o tien t de deux objets de type r a tio n n e l
D
VD def mul ( s e l f , a u t r e ):
O i f s e l f . __ v a lid e and a u t r e .__ v a lid e :
rs]
a , b = s e l f ___num, s e l f ___ denom
(S)
p, q = a u t r e .__num, a u t r e .__ denom
ai re tu rn r a tio n n e l(a * p , b*q)
> e ls e :
CL
O retu rn r a t io n n e l(0 , 1, F a ls e )
U
def __ tru e d iv __ ( s e l f , a u t r e ):
i f s e l f ___v a lid e and a u t r e ___ v a lid e :
a , b = s e l f . __num, s e l f . __ denom
p, q = a u t r e ___num, a u t r e ___ denom
retu rn r a tio n n e l(a * q , b*p)
e ls e :
C la sse s 255
retu rn r a t io n n e l(0 , 1, F a ls e )
Il reste possible de choisir la dfinition du quotient comme produit par linverse ; il convient
de sinterroger sur la consommation de ressources, par exemple en tudiant par une srie de
tests quelle est limplmentation la plus efficace.
def __ pow__ ( s e l f , a u t r e ):
i f s e l f ___v a lid e and a u t r e ___ v a lid e :
a , b = s e l f ___num, s e l f ___ denom
P, q = a u t r e ___num, a u t r e ___ denom
i f ( a .v a le u r 0 == 0) and ( p .v a le u r () <= 0 ) :
retu rn r a t io n n e l(0 , 1, F a ls e )
i f p .v a le u r ( ) < 0:
P, a , b = -p, b, a
i f b .v a le u r !) < 0:
a , b = -a , -b
i f q .v a le u r !) == 1:
retu rn ra tio n n e l(a * * p , b**p)
retu rn r a t io n n e l(0 , 1, F a ls e )
Le lecteur pourra complter la liste des oprateurs par les mthodes qui construisent la com
paraison de deux rationnels ainsi que que dune nouvelle instance donnant le nombre in
verse ; cette dernire mthode rend possible la division comme multiplication par linverse.
Les quelques fonctions qui suivent nont pas dintrt mathmatique. Leur prsence est seule
ment motive par le respect du trs important principe dencapsulation des donnes. Aprs
tout, le conducteur na aucun besoin de connatre le fonctionnement intime et dans le dtail
du moteur de son vhicule, et il sen accommode parfaitement dans son utilisation normale.
De la mme faon, un utilisateur de la classe r a t i o n n e l se satisfait de savoir que la somme
de deux rationnels est un rationnel, avec la possibilit de contrler que la somme calcule
XJ est correcte. Cela peut paratre banal, mais cela le devient un peu moins lorsquon considre
O
c que lutilisateur de la classe nest plus un humain (en principe apte au contrle du bon d
D
roulement des calculs), mais un calculateur, qui effectuera avec docilit tout ce qui lui est
VD
demand, nonobstant labsurdit des rsultats intermdiaires.
O
rs]
(S) Un utilisateur de la classe doit tout prix viter de manipuler les donnes internes de la classe,
sous peine den casser lintgrit : le concepteur de la classe en a pris la responsabilit lors de
ai
la conception de la classe.
>
CL
O En dernier lieu, le concepteur de la classe peut, son initiative seulement, mettre disposition
U
de lutilisateur de la classe des accesseurs (il peut savrer pratique de consulter la valeur du
dnominateur) ou mme des mutateurs, bien que ces derniers portent en eux les dangers
mentionns prcdemment.
def e s t _ v a li d e ( s e lf ) :
retu rn s e l f ___v a lid e
256 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
Les quelques tests ci-dessous montrent en fait la partie visible depuis lextrieur de la
classe, par Lutilisateur de la classe r a t i o n n e l :
i f __ name__ == "____main__
a = r a t io n n e l!-23)
p r i n t (a)
b = r a t io n n e l( e n t ie r ( -2 3 ))
p r i n t (b)
c = r a t io n n e l(4 , 0)
p r i n t (c )
d = r a t io n n e l!-400, -3760)
p r i n t !d)
p r in t ! f l o a t ! d ) )
d = r a t io n n e l! e n t ie r ! -4 0 0 ), e n t i e r ! -3760))
p r in t !d )
p r in t ! f l o a t ! d ) )
X = a -I- d
p r i n t !x )
X = c + d
p r i n t !x )
X = d ** ra tio n n e l !-5 )
p r i n t !x )
XJ
O
c
D
[ Term inal]
kD -23
11
O
rs] -23
(S) ! ra tio n n e l in v a lid e )
5/47
ai
0.106382978723
>-
CL
O 5/47
U 0.106382978723
-1076/47
! ra tio n n e l in v a lid e )
73390.40224
comme une unit autonome pour implmenter le type rationnel (moyennant linclusion du
fichier dfinissant le type entier). Ce paragraphe permet dutiliser le fichier source comme
un programme autonome (par exemple pour des tests) ou comme module au service dun
programme plus consquent.
Exercice 67. tendre la classe e n tier afin que le type effectue lui-mme le contrle du d
bordement de capacit, tant fixes par le programmeur les valeurs dun plus petit et dun
plus grand entier. Entre ces deux entiers, larithmtique des quatre oprations, et lexpo
nentiation seront garanties par le type.
Exercice 68. Pour lcriture des nombres dcimaux sous la forme usuelle, nous nous sommes
reposs sur le fait que P y th o n effectue convenablement cette tche. crire un programme
P y th o n qui dlivre cette forme, partir de la donne de deux nombres entiers.
3 L is te s
- les files (ou queues, encore appeles FIFO pour first in, first out) : cette structure est une
liste squentielle approprie au traitement de ses lments selon le protocole premier
entr, premier sorti ;
- les piles (ou stacks ou LIFO) : comme le nom lindique, ce type de liste est la mtaphore
de la pile dassiettes dernier entr, premier sorti .
Remarque. Afin dviter toute confusion, le terme anglo-saxon file dsignant le plus souvent
en langage informatique un fichier de donnes, nous parlerons de queue en lieu et place de
file dans la suite du chapitre.
def i n i t i a l i s e r ( l ) :
....... rem plissage de la l i s t e avec des nombres a l a t o i r e s .......
fo r i in r a n g e ( le n ( l) ) :
l [ i ] = ra n d ra n g e (l, 100)
def m a x i_ r e c ( l) :
258 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
# une l i s t e de d i x nombres 0
l i s t e = [0 fo r i in ran g e (lO )]
in it ia lis e r (lis t e )
p r in t ( lis t e )
p r i n t (maxi_ r e c ( l i s t e ) )
C om m e on le constate, Tutilisateur possde tous les dtails d im plm entation sous les yeux.
En particulier, le d im en sio n n em en t correct de la liste et son initialisation d p en d e n t de lui.
On p eu t toutefois dlguer certains traitem en ts fastidieux au program m e, et perm ettre lu ti
lisateur de concentrer son atten tio n sur le problm e q u il cherche rsoudre, n o n sur des
dtails externes.
On observe de plus que les donnes sont spares de leur traitem ent.
D ans une seconde version, le program m e est am lior par la gestion des listes en P y th o n .
La liste est initialem ent vide, puis rem plie h a u te u r de la longueur dsire. Le program m e
com porte n anm oins toujours le dfaut de devoir d em an d er explicitem ent linitialisation de
la liste d entiers.
m a x i R e c L is t e 2 . p y
kD i f n > 0:
O l . append!ra n d ra n g e (l, 100))
rs]
i n i t i a l i s e r ( l , n-1)
(S)
ai def m a x i_ r e c (l) :
> """ recherche r c u r s i v e du maximum """
CL
O i f l e n ( l ) > 1:
U
maxi = m a x i_ r e c ( l[ : - 1 ] )
i f maxi > l [ - 1 ]:
retu rn maxi
e ls e :
retu rn l [ - l ]
e ls e :
retu rn l [ 0 ]
C la sse s 259
i f __ name__ == "____main__
l i s t e = [] # la l i s t e e s t i n i t ia le m e n t vid e
i n i t i a l i s e r ( l i s t e , 10)
p r in t ( lis t e )
p r i n t ( m a x i_ r e c ( lis t e ) )
Nous donnons enfin une version oriente objet de ce programme : son intrt rside cette
fois dans lencapsulation des donnes. Cette notion ralise le regroupement logique des don
nes et leur traitement. Du point de vue de Tutilisateur de la classe, celui-ci na aucune connais
sance des dtails dimplmentation de la liste, et peut lutiliser telle quelle. On a ainsi ajout
une couche dabstraction - une protection - puisque lutilisateur nintervient pas dans le fonc
tionnement interne de lobjet. Lors de la cration de la liste, lutilisateur se contente de spci
fier la taille de la liste des nombres alatoires.
m a x i R e c L is te s , p y
def m a x i_ r e c ( l) :
...... recherche r c u r s i v e du maximum .......
i f l e n ( l ) > 1:
maxi = m a x i_ r e c (l[ : - 1 ] )
i f maxi > l [ - 1 ] :
retu rn maxi
e ls e :
retu rn l [ - l ]
e ls e :
retu rn l [ 0 ]
c la s s t a b le ( o b je c t ) :
def in it (s e lf , t a i l l e ) :
a s e l f ___l i s t e = [ra n d ra n g e (l, 100) fo r n in r a n g e ( t a il le ) ]
O
c
D def str (s e lf ):
kD retu rn s t r ( s e l f ___l i s t e )
O
rs]
def maxim um (self) :
retu rn m a x i_ r e c (s e lf ___l i s t e )
ai
> i f __ name__ == "____main__ ":
CL
O l i s t e = ta b le (1 0 )
U
p r in t ( lis t e )
p rin t(lis te .m a x im u m ())
d e f __ St __ ( s e l f ) :
retu rn s t r ( s e l f ___donne)
Donnons quelques commentaires sur la structure de la classe. Comme pour les listes natives
de P y th o n , nous pourrons stocker dans un nud tout type dinformation, quelle quen soit
sa nature. Cette libert est prcieuse et souvent absente des autres langages.
------------------------------- [ Term inal] ------------------------------------------------------------------------------------------------------------
- nous voulons pouvoir complter la liste par adjonction dun nouvel lment, droite
ou en fin de liste pour une queue, et pour une pile le placer au sommet (empiler) ;
- pour une queue, nous souhaitons pouvoir retirer le premier lment introduit dans la
queue (le plus gauche), ou pour une structure de pile, retirer llment au sommet de
la pile (dpiler).
- enfin, nous souhaitons pouvoir consulter, sans modifier les lments dune queue ou
dune pile, le premier lment gauche ou llment au sommet de la pile.
Dans les deux listes reprsentes en figures 6.4 et 6.5, nous avons insr dans le mme ordre
squentiel les entiers 1, 2, 3, 4 et 5. Nanmoins, le premier lment lu (retir) de la file sera 1
(premier lment historiquement inscrit) ; le premier lment lu dans la pile sera le dernier
lment inscrit.
Nous ne manipulerons nos objets de type queue ou pile que par les poignes que consti
tuent les pointeurs p re m ie r, d e r n i e r et sommet :
a
O
c
D - P rem ie r nous permet de lire (et retirer) le premier lment de la queue ;
Signalons enfin que nous nous interdisons linsertion et la suppression en milieu de pile ou
de queue ; bien que cela soit possible, ces fonctionnalits prsentent peu dintrt en pratique
pour une liste squentielle. Pour ce type de manuvre, lutilisation dun arbre binaire est plus
262 P r o g r a m m a tio n e n P y th o n p o u r les m a th m a tiq u e s
3) (4
F igure 6.6 - Retrait dans u n e queue
3 ) (2 ) ( 1
F igure 6.7 - Retrait dans u n e pile
tJHD
O
CM
(y)
XI
OJ
>-
Q.
O
U
judicieuse. Nous reviendrons sur cette question dans la section rserve aux arbres binaires
de recherche.
Munis dun objet de type noeud, nous allons maintenant constituer les modles dobjet pour
les listes FIFO et LIFO. Ces objets peuvent en fait ne comporter quune seule variable dins
tance, pointant un nud et suffisante pour la manipulation de la queue ou de la pile. Par
exemple, nous choisissons un pointeur dsignant llment le plus gauche pour la queue,
ou le sommet pour une pile. Cependant, nous donnerons deux variantes dimplmentation :
- pour une queue : un pointeur sur le premier lment de la queue, ainsi quun pointeur
sur le second lment de la queue. Ce choix sexplique par le fait quon agit aux deux
extrmits de la queue (lecture au dbut, criture la fin) ;
- pour une pile : uniquement un pointeur sur le sommet de la pile. En effet, dans une pile,
les critures et lectures seffectuent toujours sur le sommet.
c la s s noeud( o b je c t ) :
""" noeud ( l i s t e simplement chane) """
def __ s t r __ ( s e l f ) :
retu rn s t r ( s e l f ___donne)
ai def g e t .s u iv a n t ( s e lf ) :
>- retu rn s e l f ___su iv a n t
Q.
O
U
def s e t _ s u iv a n t ( s e lf , s ) :
s e l f ___su iv a n t = s
c la s s q u e u e (o b je c t):
...... queue ......
def __ i n i t __ ( s e l f ) :
s e lf prem ier = None
s e lf d e rn ie r = None
d e f __ s t r __ ( s e l f ) :
s = []
n = s e l f ___premier
w h ile not (n i s None):
s.ap p end (n.g et_d o nnee())
n = n .g e t _ s u iv a n t ()
retu rn s t r ( s )
def e s t _ v id e ( s e lf ) :
retu rn ( s e l f ___premier i s None)
def e c r ir e _ d e r n ie r ( s e lf , d ):
n = noeud(d)
i f s e l f ___prem ier i s None:
s e l f ___prem ier = n
e ls e :
s e l f ___d e r n ie r . s e t_ s u iv a n t(n )
s e l f ___d e rn ie r = n
def lir e _ p r e m ie r ( s e lf ) :
i f s e l f ___prem ier i s None:
retu rn None
n = s e l f ___premier
d = n .g et_d o nnee()
s e l f ___prem ier = n .g e t _ s u iv a n t ()
n = None
re tu rn d
a
O
c
D
Q On p e u t ajouter les lignes suivantes au fichier q u e u e . py, p o u r les tests
I
O
r\i i f __ name__ == "____main__ ":
(y) q = queue()
q .e c r ir e _ d e r n ie r ( " la p in " )
CT
s_ q .e c r ir e _ d e r n ie r (" c h a s s e u r " )
>-
CL
O q .e c r ir e _ d e r n ie r (2 )
U q .e c r ir e _ d e r n ie r ( " le " )
q .e c r ir e _ d e r n ie r ( " r e to u r" )
p r in t (q )
w h ile not q .e s t _ v id e ( ) :
p r i n t (q . lir e _ p r e m ie r ( ))
C la sse s 265
pile.py
from noeud import *
c la s s p ile ( o b j e c t ) :
... . pile ....
def in it (s e lf ) :
s e l f ___sommet = None
def str (s e lf ):
s = []
n = s e l f ___sommet
w h ile not (n i s None):
s . append(n .g et_d o n n e e ())
n = n .g e t _ s u iv a n t ()
retu rn s t r ( s )
def e s t _ v id e ( s e lf ) :
retu rn ( s e l f ___sommet i s None)
def e m p ile r ( s e lf , d ):
n = noeud(d)
n . se t_ su iv a n t ( s e l f .. sommet)
s e l f ___sommet = n
def d e p il e r ( s e lf ) :
i f s e l f ___sommet i s None:
retu rn None
n = s e l f ___sommet
d = n.g et_d o nnee()
s e l f ___sommet = n . g e t_ s u iv a n t()
TJ
O n = None
c retu rn d
rj
tJH
D
i f __ name__ == "____main__ " :
O
CM P = p ile O
(y) p .em piler("G N U ")
XI
OJ p .e m p ile r(" i s " )
>- p .e m p ile r( "n o t")
Q. p .e m p ile r(" U n ix " )
O
U
p r i n t (p)
w h ile not p .e s t _ v id e ( ) :
p r in t ( p .d e p ile r ( ))
$ . /queue.py
[ 'U n ix ', 'n o t ', ' i s ' , 'GNU']
Unix
not
is
GNU
$
4 A rb re s b in a ire s
a
o Nous nous intressons ici un type particulier darbre binaire appel arbre binaire de re
c
n
cherche (voir figure 6.10), dont la structure peut voluer lors des adjonctions ou suppressions
kD de nouveaux lments, tout en restant stable selon un ordre dfini sur les nuds.
o
CM
(5)
4.1 Une classe pour la structure de nud double
Ol
v_
>- La proprit principale pour un arbre binaire de recherche est la garantie que, pour tout
Q.
O nud n de larbre, tout membre du sous-arbre gauche de n est infrieur nimporte quel
u
nud membre de nimporte quel sous-arbre du sous-arbre droit de n.
Une autre garantie non moins importante rside dans lunicit de chaque valeur dans un
arbre binaire de recherche.
De telles garanties confrent une structure dichotomique larbre. Ce type de structure est
particulirement bien adapt la recherche, linsertion et la suppression de nuds. En
C la sse s 267
noeud, py
c la s s noeud( o b je c t ) :
""" noeud double (deux f i l s ) ......
def c h e r c h e r ( s e lf , num):
""" ch e rch e r une v a le u r ......
i f num == s e l f ___num:
retu rn True
e ls e :
p r in t "(p as de doublon dans un arb re b in a ire de recherche)"
def p lu s _ g ra n d (s e lf) :
i f s e l f ___d r o it e :
retu rn s e l f ___d ro ite .p lu s _ g ra n d ()
e ls e :
retu rn s e l f ___num
# ... mthode p l u 5 ^ p e t i t ( ) . . .
def f ils _ g a u c h e ( s e lf ) :
....... a c c e sse u r f i l s gauche """
retu rn s e l f ___gauche
# . mthode f i l s ^ d r o i t e O ...
La m thode rcursive suivante p erm et le com ptage des n u d s des deux sous-arbres :
noeud,py
def n o e u d s (s e lf) :
n = 1
i f s e l f ___gauche:
n = n -H s e l f ___gauche. noeuds ( )
i f s e l f ___ d r o it e :
n = n + s e l f ___d ro ite .n o e u d s()
re tu rn n
conserver un quilibre sur les h au teu rs respectives des deux sous-arbres de chaque
n u d (on agrm ente alors chaque n u d d u n co m p teu r p o u r com penser la diffrence
des h au teu rs des deux sous-arbres). Une telle solution sera privilgie si on souhaite
prserver u n arbre binaire d u n e dgnrescence en liste, p o u r des raisons de perfor
m ance.
noeud, py
def c h e r c h e r_ p a re n t(s e lf, num)
i f num == s e l f ___num:
retu rn None
tJHD e ls e :
O retu rn s e l f . __g a u ch e .c h e rch e r.pa r e n t (num)
CM
e ls e :
(y)
i f s e l f ___d r o it e ___ num == num:
XI
OJ retu rn s e lf
>- e ls e :
Q.
O retu rn s e l f ___d r o it e .c h e r c h e r .pa rent(num)
U
TJ
O
c
rj
tJHD
O
CM
(y)
XI
OJ
>-
Q.
O
U
C la sse s 271
e ls e :
i f s e l f ___gauche i s None and s e l f ___ d ro ite i s None: # aucun f i l s
i f p a re n t___gauche i s s e l f :
p a re n t___gauche = None
e ls e :
p a re n t___d ro ite = None
e ls e :
i f s e l f ___gauche i s None or s e l f ___ d ro ite i s None: # f i l s
unique
i f s e l f ___gauche:
t = s e l f ___gauche
e ls e :
t = s e l f ___d ro ite
TJ
o
c
i f p a re n t___gauche i s s e l f :
n s = p a re n t___gauche
UD p a re n t___gauche = t
tH
o e ls e :
CM
s = p a re n t___d ro ite
(5)
p a re n t___d ro ite = t
XI
CTl s gauche = None
>- s d ro ite = None
Q.
O
U
e ls e : # deux f i l s
i f s e l f ___gauche.noeuds() > s e l f ___ d r o it e .noeuds() :
X = s e l f ___g a u ch e .p lu s_g ran d ()
e ls e :
X = s e l f ___d r o i t e .p lu s _ p e t it ( )
s e l f . sup prim er(x)
s e l f ___num = X
272 Programmation en Python pour les mathmatiques
Les mthodes suivantes permettent de prsenter les nuds sous une forme ordonne
n o e u d , py
def montrer_ordre_croissant(self):
i f s e l f __gauche:
s e l f __gauche.montrer_ordre_croissant()
p r i n t ( s e l f __num)
i f s e l f __d ro ite :
s e l f __droite.montrer_ordre_croissant()
# . . . mthode montrer^ordre.^decroissant() . . .
def _l i s t e _ o r d r e _ c r o i s s a n t ( s e l f , l i s t e ) :
i f s e l f __gauche:
self gauche liste_ordre_croissant(liste)
l i s t e . append( s e l f __num)
i f s e l f __d ro ite :
self droite liste_ordre_croissant(liste)
def l i s t e _ c r o i s s a n t e ( s e l f ):
l i s t e = []
s e l f __l i s t e _ o r d r e _ c r o i s s a n t ( l i s t e )
return l i s t e
# . . . mthode l i s t e ^ d e c r o i s s a n t e O ...
XJ
O
c
4.2 Une classe pour la structure d'arbre binaire de recherche
arbre, p y
OD
O from st ri ng import *
rs]
import random
(S)
def _i n i t _( s e l f ) :
""" c o n s t r u c t e u r .....
s e l f __racine = None
def montr e r ( s e l f ) :
Classes 273
def c h e r c h e r ( s e l f , num):
""" re ch er ch er une valeur
i f s e l f __racine:
return s e l f __racine.chercher(num)
e ls e :
return False
def i n s e r e r ( s e l f , num):
""" i n s r e r une nouvelle valeur .....
i f s e l f __racine:
s e l f __racine.insrer(num)
e ls e :
s e l f __racine = noeud(num)
self r a c i n e . set_num(x)
JD
t
O
H
e ls e :
CM
s e l f __racine.supprimer(num)
(y) e ls e :
XI
OJ p r i n t ( " (valeur i n e x i s t a n t e ) " )
>-
Q.
O def montrer_ordre_croissant(self):
U
""" montrer la l i s t e en ordre c r o i s s a n t """
i f s e l f __racine:
self racine.montrer_ordre_croissant()
e ls e :
p r i n t ( " ( l i s t e vi de)")
# . . . mthode m o n t r er - or dr e -d e cr o is s a nt () . . .
274 Programmation en Python pour les mathmatiques
def l i s t e _ c r o i s s a n t e ( s e l f ):
..... l i s t e en ordre c r o i s s a n t .....
i f s e l f __racine:
return s e l f r a c i n e . l i s t e _ c r o i s s a n t ()
e ls e :
return []
# . . . mthode l i s t e ^ d e c r o i s s a n t e ( ) . . .
def n o e ud s( se lf):
""" nombre de noeuds de l ' a r b r e .....
i f s e l f __racine:
return s e l f __r a c i n e . noeuds()
e ls e :
return 0
a.montrer!)
fi n = False
while f i n == False:
p r i n t ! " ! a ) jo u t e r ou !c )r o is s a n t ou ! d ) c r o i s s a n t " )
print!"ou !s)upprimer ou ! q ) u i t t e r ?")
"O
O ch = s t r ! i n p u t !))
c
=3 i f ch == ' a ' or ch == ' s ':
Q
JD n = i n t ! i n p u t ! ))
t H
O print " ................................................................................. "
fN
i f ch == ' a ' :
a . inserer!n)
ai i f ch == ' s ' :
>- a . supprimer!n)
CL
O a.montrer!)
U
i f ch == ' c ' :
p r i n t ! a . l i s t e _ c r o i s s a n t !))
i f ch == ' d ' :
p r i n t ! a . li s t e _ d e c r o is s a n te ! ))
i f ch == ' q ':
f i n = True
i f not !ch in "acdsq"):
Classes 275
5 C a lc u la t e u r
- la composition (ou lagrgation) dobjets est une relation entre objets du type possde
un ;
- lhritage entre objets est une relation du type est un . Lhritage permet le polymor
phism e, savoir la m anipulation dun objet sous diverses identits.
Il est souvent dlicat de dterm iner quelle est la plus judicieuse des deux possibilits pour
dfinir un nouveau type dobjet. Il est im portant davoir lesprit que lhritage m aintient
des dpendances fortes au sein dune hirarchie : un changement un niveau possde des
consquences sur toute la chane des objets, alors que la composition m aintient une certaine
sparation des rles et donc favorise lindpendance des types. Cet aspect doit tre pris en
compte dans la ralisation de programmes im portants.
Pour fixer les ides, nous prendrons l exemple dune hirarchie de quadrilatres, avec les
classes suivantes :
c la s s q u a d r i l a t e r e ( o b j e c t ) :
.... . q u a d ri l a t r e quelconque .....
a
O
c
D def _i n i t _( s e l f , a = , b = , c , d= ):
0 0 = 0 0
kD self.a = a
O self.b = b
rs]
self.c = c
self.d = d
ai s e l f . t y p e = "quadrilatre"
>
CL
O def _s t r _( s e l f ) :
U
return s e l f . t y p e
def p e r i m e t r e ( s e l f ):
return ( s e l f . a + s e l f . b + s e l f . c + s e l f . d )
p r i n t (q)
p r i n t (q . perimetre())
La classe quad r la t e re est notre classe mre, partir de laquelle nous construisons les classes
filles losange et re cta n g le . Nous parlons d'hritage simple : chacune des deux classes filles
possde une classe mre unique.
c l a s s l o s a n g e ( q u a d ri l a t e r e ) :
.... losange """
def _i n i t _( s e l f , a = ): 0
q u a d r i l a t r e __i n i t _( s e l f , a, a, a, a)
s e l f . t y p e = "losange"
def perimet r e (s e l f ):
return se lf. a + 4
Le constructeur de la classe losange fait appel au constructeur de la classe mre. Nous pou
vons noter la rcriture de la mthode pe rim et re ( ) : cette dernire est spcialise, elle se
substitue la dfinition de la mthode de mme dfinie dans la classe mre.
c la s s r e c t a n g l e ( q u a d r i l a t e r e ) :
""" r ectangl e .... .
def _i n i t _( s e l f , a = , b = ) 0 0
"O q u a d r i l a t r e __i n i t _( s e l f
O s e l f . t y p e = "rectangle"
c
-J
Q
M D # def p e r i m e t r e ( s e l f ) :
O # return ( s e l f . a + s e l f . b ) * 2
CM
(y)
4-1 i f _name_ == "_main_":
XI
CTI r = rectangle(4, 3)
\
>- p r i n t ( r)
Q.
O p r i n t ( r . p e r im e t r e ( ))
U
Le lecteur aura remarqu les lignes commentes pour la mthode de calcul du primtre : le
primtre est calcul en invoquant, soit une mthode spcialise, soit une mthode prsente
plus haut dans la hirarchie de classe.
Nous construisons m aintenant une classe hritant la fois de la classe losange et de la classe
re cta n g le , la classe c a rre :
Classes 277
def _i n i t _( s e l f , a = ): 0
# q u a d r i l a t r e __ i n i t _( s e l f , a, a, a, a) # fonctionne aussi
lo sa ng e __i n i t _( s e l f , a)
On remarquera ici les deux possibilits dcriture du constructeur : en faisant appel une
mthode de la classe quad r ila t e re ou de la classe losange.
D autre part, nous avons ici typiquement un cas dhritage en diamant , du fait de la d
claration de la classe qui mentionne les deux classes losange et re c ta n g le : quelle est la va
riable dinstance retourne lorsque nous invoquons la mthode ca r r e ___s t r ( ) ? Pour sen
convaincre, il suffit de commenter/dcommenter les deux lignes commenant par le mot-cl
c la s s .
Lintrt pour un objet dhriter dun autre objet est de bnficier de ses inform ations et m
thodes, en ayant la possibilit notamment de les complter ou de les altrer.
Un objet peut hriter des inform ations ou des mthodes de plusieurs objets, on parle alors
dhritage m ultiple ou polymorphisme.
Pour sim plifier, nous nous baserons sur une version lgre de notre calculateur dans laquelle
les nombres et les oprations scrivent tous sous la forme dun unique caractre A SC II. Nous
faisons cette rduction avec lintention de faciliter le dcoupage en units lexicales (units
inscables mathmatiquement pertinentes) de lexpression mathmatique valuer. Lhypo
thse de considrer des lexmes constitus de plusieurs caractres relve de lanalyse lexicale,
domaine non tudi ici.
A = 8 ^ 2 - 3 x (5-hI)
Larbre binaire est parfaitem ent adapt la reprsentation de la structure opratoire de lex
pression ; en particulier, il est conforme aux rgles usuelles de priorit entre oprations.
tH
(S)
- les classes numriques (entiers, rationnels) ;
ai - une structure de queue pour un parcours horizontal de lexpression ;
>
Q. - une structure de pile pour les oprateurs, puis une structure de pile pour lvaluation
O
U de lexpression ;
- une structure darbre binaire.
Nous mettrons en uvre deux stratgies pour lvaluation : une approche parles piles dop
rateurs, puis une approche base sur la rcursivit des grammaires, utilise dans la construc
tion des logiciels interprtes (Python en est un bon exemple) ou compilateurs (le langage C
est un langage en gnral com pil, mais on peut en trouver quelques interprtes).
Classes 279
On observera que, le nombre doprandes tant parfaitem ent dtermin pour un oprateur
donn, les parenthses deviennent totalement inutiles en notations prfixes et postfixes.
La prsence de parenthses est le signe du caractre rcursif de notre manire dcrire les
expressions algbriques.
unit lex. 8 2 3 5 1 -H X -
1
5 5 6
pile
2 3 3 3 3 18
8 8 4 4 4 4 4 4 -1 4
Chacun des nombres en caractres gras est obtenu par lapplication de loprateur arithm
tique lu sur les deux oprandes dpiles (pour loprateur, lordre des oprandes est lordre
inverse du dpilement) ; le rsultat est alors em pil.
Lorsque lvaluation sest droule correctement, la pile contient terme un seul nombre, qui
a
O est la valeur de lexpression.
c
Ce problme est contourn par une transform ation dcriture lors de la phase danalyse lexi
cale de lexpression. Pour cela, nous utilisons la proprit : - a = { - l ) x a . A insi, lexpression
-(x-i- 5) -I- 7 sera transforme en la liste dunits lexicales [(-1 ); x;(;x;-i-;5;);-i-;7;] dans
laquelle tous les oprateurs sont binaires.
280 Programmation en Python pour les mathmatiques
analex. py
from os import *
from re import *
from str in g import *
def a na ly s e_ le xi ca le (s )
s = s . r e p l a c e ( '[
s = s . r e p l a c e ( ']
s = s . r e p l a c e ( '{
s = s . r e p l a c e ( '}
s = s . r e p l a c e ( '/
t = s.sp lit()
s = ' ' . join(t)
s = { + s + }
s = s . replace('-' -1 *' )
s = s . r e p l a c e ( '{+ { )
s = s . r e p l a c e ( '(+ ()
JD
t H
O r = []
CM
r.append(l[ ] ) 0
(y)
moins = False
XI
OJ fo r t in l [ l : ]:
>- i f t == - :
Q.
O moins = True
U
continue
i f t == and moins == True:
moins = False
t = "- " 1
r.append(t)
Classes 281
del r [ ]0
del r [ - l ]
return r
Comme annonc, notre modle de nud pour un arbre binaire contient, en plus de linfor
mation utile, deux pointeurs vers deux sous-arbres (fils gauche et fils droit).
n o e u d 2 .p y
c l a s s noeud2(object):
..... noeud double (pour un arbre b i n a i r e ) """
ai # . . . mthode en^chaine^postfixeO . . .
s_
>.
CL
O def d on ne e(s el f):
U
return s e l f __donne
arbre, py
from st ri ng import *
def si m p l if i e r_ p a r e n t h e s e s (s ) :
i f s . s t a r t s w i t h ( ' ( ' ) and s. e n d sw i th ( ' ) ' ) :
s = s[l:- ] 1
return s
c la s s a r b r e ( o b j e c t ) :
""" arbre b i n a i r e de l ' e x p r e s s i o n .....
def _i n i t _( s e l f , e x p r e s s i o n _ in f i x e ) :
s e l f __operateurs = []
s e l f ._p i l e = []
e = analyse_le xi cal e( ex pre ssi on_ inf ix e)
for jeton in e:
i f j e t o n [ - l ] in d i g i t s :
s e l f __p i l e . append(noeud ( j e t o n ) )
2
continue
i f jeton == ' ( ' :
self ope rateu r s . append(j eto n)
continue
i f jeton == ' ) ' :
while l e n ( s e l f __operateurs) > \0
s e l f . nouvelle_operation()
s e l f __ope rat eur s. pop(- ) 1
continue
i f jeton in
TJ
O i f jeton != :
c
rj while l e n ( s e l f __operateurs) > 0 \
s e l f __racine = s e l f __ p i l e . p o p ( - l )
d r o it e = s e l f pile.pop(-l)
Classes 283
gauche = s e l f __p i l e . p o p ( - l )
noeud = noeud (sommet, gauche, droite)
2
s e l f __p i l e . append(noeud)
def p r i o r i t e ( s e l f , op);
precedence = 0
i f op == '+' or op
precedence = 1
i f op == or op or op == '/
precedence = 2
i f op == ' :
precedence = 3
return precedence
def p r e f i x e ( s e l f ):
return s e l f __r a c i n e . en_chaine_prefixe()
def i n f i x e ( s e l f ):
return s i m p l i f i e r - parentheses(s e l f r a c i n e . en_chaine_infixe())
def p o s t f i x e ( s e l f ):
return s e l f __r a c i n e . en_chaine_postfixe()
def e v a l u e r ( s e l f ):
expr = s e l f __ra cin e. en_chaine_infixe()
val = []
p = s e l f __racine.en_chaine_postfixe()
q = p.sp lit( I )
fo r n in q:
i f n [- l] in d i g i t s :
v a l . append( r a t i o n n e l ( i n t ( n ) ))
continue
i f n == '+ ':
b = v a l . pop(- ) 1
TJ a = val.pop(-l)
o
c
n r = a + b
v a l . append( r)
UD
t
o
H
continue
CM
i f n == - :
(5) b = v a l . pop(- ) 1
XI
oi a = val.pop(-l)
>- r = a - b
Q.
O v a l . append( r)
U
continue
i f n == ' * ' :
b = v a l . pop(- ) 1
a = val.pop(-l)
r = a * b
val.append(r)
continue
284 Programmation en Python pour les mathmatiques
i f n == ' : ' or n == V
b = val.pop(-l)
a = val.pop(-l)
r = a / b
v a l .append(r)
continue
i f n == " :
b = v a l . pop(- ) 1
a = val.pop(-l)
r = a ** b
v a l .append(r)
continue
return v a l . p o p ( - l )
def _i n i t _( s e l f ) :
s e l f __p i l e = []
def e m p i l e r ( s e l f , arg):
s e l f __p i l e . append(arg)
def d e p i l e r ( s e l f ):
i f l e n { s e l f __p i le ) > : 0
return s e l f __p i l e . p o p ( - l )
e ls e :
a
o return rationnel(0, 1, False)
c
3
Q
def a d d i t i o n n e r ( s e l f ):
tH
o b = self.depiler()
rsJ
a = self.depiler()
r = a + b
Oi self.empiler!r)
s_
>
CL
o # ... mthode s o u s t r a i r e O ...
u
# ... mthode m u l t i p l i e r O ...
# ... mthode e l e ve r ^p ui s sa nc e ( ) . . .
Classes 285
def r s u l t a t ( s e l f ):
return s e l f . d e p i l e r ( )
def re p o n s e ( s e lf ):
return s e l f . r s u l t a t ()
Dans le code des oprations arithm tiques prsent ci-dessus, on relvera labsence de tout
code spcifique la nature des oprandes. Ce contrle, grace la dfinition de nos objets,
est effectu au sein de chaque oprande. Nous avons ici encore un exemple typique dabs
traction, notre code fonctionne galement sans m odification sur nimporte quel type natif
supportant ces oprateurs arithm tiques.
c a l c l .p y
def tests_automatiques():
# donne 3 4 + 5 1 1 + + 7 - = 168
print("Exemple de c a lc u l :")
calculer("(3 + ) * 4+ 1) - 7")
5 ( 1
# donne 9 1 + 7 2 5 + + +
TJ
O p r i n t ( "Exemple de c a lc u l :")
c
rj calculer!" ! 9 + l ) * ! 7 + 2 * 5 ) " )
JD
t H
O # donne 3 7 : 2 7 : 5 14 : : -
CM
prin t ! "Exemple de c a lc u l :")
c a l c u l e r ! " 3/7 - 2/7 : ! 5 : 14 ) ")
xz
ai
> def le c tu re _ e x pr ():
CL
O pri nt! " " )
U
prin t ! "Calcul suivant ( l a i s s e r vide et v a l i d e r pour q u i t t e r ) : " )
return input!)
def b o u c le ! ):
expr = le c t u re _ e xp r( )
while len(expr) > : 0
expr = le c t u re _ e xp r( )
n a tu re l ::= ('0' | ' 1' | ' 2' | ' 3' | ' 4' | ' 5' | ' 6' | ' 7' 1 '8' | '9')*
Le term inal nat u r e l est construit sur la rptition ventuelle dun chiffre dcimal.
"O Cette grammaire fonctionne en quelque sorte comme un vritable pilote pour la lecture de
O
c lexpression valuer.
=3
Q
'JD Cette grammaire est volontairem ent non rcursive gauche : son intrt est une traduction
O immdiate en termes de procdures dans un langage de programmation.
(N
Nous aurions pu choisir une grammaire rcursive g a u ch e dcrivant le mme langage, avec :
xz
DI expr ::= expr "+" terme 1
>-
Q.
O expr terme \
U terme
( ...)
Classes 287
Dans cette version, nous avons choisi de crer un objet exp cession qui value une expression
selon la grammaire prsente plus haut. Chaque non-term inal de la grammaire donne donc
lieu une mthode pour son valuation.
exp ressio n , py
class expression(object):
""" expression val uer .....
def in it (self, s ) :
s e l f __source = s
s e l f __n = le n(s )
s e l f __i = 0
s e l f __e rr = 0
s e l f __val = 0
fo r ch in s e l f __source:
i f not s t r . i s s p a c e ( c h ) :
s += ch
return s
a
O def e r r e u r ( s e l f , e ) :
c
D i f s e l f __e rr == :
0
JD s e l f __er r = e
tH
O
CM
def e r r e u r _ e x i s t e ( s e l f ):
(y)
i f s e l f __e rr == : 0
ai return False
> e ls e :
CL
O return True
U
def aucune_erreur(self):
return not s e l f . e r r e u r _ e x i s t e ( )
def v a l e u r ( s e l f ):
self.evaluer()
return s e l f __val
288 Programmation en Python pour les mathmatiques
def e v a l u e r ( s e l f ):
s e l f __ch = s e l f . s u i v a n t ()
i f s e l f __ch == ' { ' :
s e l f __ch = s e l f . s u i v a n t ( )
s e l f __val = s e l f . e x p r O
s e l f __ch = s e l f . s u i v a n t ( )
i f self.__ch != :
s e l f . e r r e u r ( ) # manque une " }
2
e ls e :
s e l f . e r r e u r ( l ) # manque une "{"
def s u i v a n t ( s e l f ):
while s e l f __i < s e l f __ n:
t = s e l f __s o u r c e [ s e l f __ i]
s e l f __i += 1
i f s t r . i s s p a c e ( t ):
continue
e ls e :
return t
return ' \ 0
def p r o c ha in _ lu ( se lf ):
while s e l f __i < s e l f __ n:
t = s e l f __so u rc e [ se lf -i]
i f s t r . i s s p a c e ( t ):
s e l f __i += 1
e ls e :
return t
return ' \ 0
def s u i v a n t _ e s t ( s e l f , t ) :
i f s e l f . p r o c h a i n _ l u ( ) == t:
return True
TJ e ls e :
o
c
n return False
UD
t
o
H
# expr ;;= exprl '+' exprl \ exprl exprl \ exprl
CM
def e x p r ( s e l f ):
(5) i f s e l f . e r r e u r _ e x i s t e ( ):
XI
oi return 0
>- t = self.exprl()
Q.
O while s e l f . s u i v a n t _ e s t ( '+') or s e l f . s u i v a n t _ e s t ( '
U
s e l f __ch = s e l f . s u i v a n t ( )
i f s e l f __ch == ' + ':
s e l f __ch = s e l f . s u i v a n t ()
t += s e l f . e x p r l O
e ls e :
i f s e l f __ch == - ' :
s e l f __ch = s e l f . s u i v a n t ()
Classes 289
t -= s e l f . e x p r l O
return t
e ls e :
i f s e l f __ch == V or s e l f __ ch ==
s e l f __ch = s e l f . s u i v a n t ( )
t /= s e l f . e x p r ()
2
i f not t . e s t _ v a l i d e ( ):
s e l f . e r r e u r ( 7 ) # t e n t a t i v e de d i v i s e r par 0
return t
i f s e l f . e r r e u r _ e x i s t e ( ):
return 0
negate = False
while s e l f __ch == ' - ' :
negate = not negate
s e l f __ch = s e l f . s u i v a n t ( )
t = self.expr3()
i f negate:
return -t
e ls e :
TJ return t
o
c
n
# expr3 : : = expr4 expr2 \ expr4
UD
t
o
H
def e x p r 3 ( s e l f ):
CM
i f s e l f . e r r e u r _ e x i s t e ( ):
(5) return 0
XI
oi t = self.expr4()
>- i f s e l f . s ui va nt _e s t ( ' :
Q.
O self ch = s e l f . su iv an te )
U
self ch = s e l f . su iv an te )
k = s e l f . e x p r e) 2
i f not k.est _v a l i d e ):
s e l f . e r r e u r e s ) # exposant i n v a l i d e
t = t ** k
return t
290 Programmation en Python pour les mathmatiques
# naturel : : = ('O' | ' ! ' | '2' | '3' | '4' '5' '6 ' 7' I '8' I '9')*
def n a t u r e l ( s e l f ) :
n = i n t ( s e l f __ch)
X = s e l f . prochain_lu()
while s t r . i s d i g i t ( x ) :
n = n * 1 0 + in t( x)
s e l f __ch = s e l f . s u i v a n t ( )
X = s e l f . prochain_lu()
return n
Le program m e c a lc 2 . py
Ce programme est pratiquement identique au programme c a l c l . py, avec une diffrence no
table dans la manire dinvoquer lvaluation de lexpression. Il suffit ici de crer une crer
une instance dun objet e xp re ssio n , ce qui entrane ds la construction son valuation.
a c a lc 2 .p y
o
c
u from expression import *
Q
1
H
o def tests_automatiques():
(N
e = expression! "{ ( 3+ ) * 5
4 (1 + 1) - 7 }")
(5)
p r i n t ( "Exemple de c a lc u l e)
x:
gi p r i n t ( e . v a l e u r ! ), ' \n' ) # donne 19
>-
Q.
O e = ex pr e ss io n! "! 2 " 3 2 2 }")
U
print ! "Exemple de c a lc u l :", e)
p r i n t ( e . v a l e u r ! ) , ' \n' ) # donne 2417851639229258349412352
def le c tu re _ e x pr ( ):
printC---")
p r i n t ( "Calcul suivant ( l a i s s e r vide et v a l i d e r pour q u i t t e r ) : " )
return i n p u t 0
def b o u c le ( ):
expr = le c t u re _ e xp r( )
while len(expr) > : 0
6 P o ly n m e s e t f r a c t io n s r a t io n n e lle s
Nous avons choisi dcarter demble les nombres dcim aux (plus exactement les nombres
a
O rels reprsentables en m achine, savoir du type f lo a t). Dans la reconnaissance dune forme
c valuer, notre calculateur nadmet comme nombres que les nombres entiers relatifs en cri
D
ture usuelle (horm is dventuels chiffres 0 gauche). En revanche, le calculateur utilisera la
VD
O forme virgule pour exprim er un nombre dcim al comme le veut la typographie fran
r\i aise le cas chant.
ai D autre part, toutes les oprations doivent tre explicitem ent crites ( la diffrence de la syn
s_
>. taxe usuelle de Python, nous avons retenu le symbole daccent circonflexe seul A pour ll
CL
O vation en puissance).
U
3 7
1
y 24^
292 Programmation en Python pour les mathmatiques
^
98344960000x'^ + 84295680000x^ + 27095040000jc^+ 3870720000X + 207360000
_______________________________________________________________________________________________________________________________________________________________________________________________________
207360000
+
2517630976y4 - 1573519360y3 +368793600y2 -38416000y+ 1500625
552960000X
+
359661568y4 - 224788480y3 + 52684800y2 - 5488000y + 214375
552960000x^
+
51380224y4 -3 2 1 12640y3 + 7526400y2 -784000y + 30625
245760000x^^
+
7340032y4 - 4587520y3 + 1075200y2 - 112000y + 4375
40960000x^
1048576y4 - 655360y3 + 153600y2 - 16000y + 625
$ . / ca lc 3 .p y
calc3: 1> l/ 3 * ( l/ 2 + 1/3 + 1/4)
13/36
ai
> 6.2.2 Utilisation sous forme de module depuis un programme
CL
O
U Comme la souplesse du langage Python nous le permet, nous pouvons utiliser directement (
l'im portation prs) notre module e x p re s s io n . py prsent dans le programme c a lc 3 pour
effectuer divers calculs.
Considrons par exemple lnonc suivant :
2. la sortie est celle dlivre par le programmecalcB dans sa version en Python 2.7.
3. maxima est un logiciel libre, disponible ladresse : http://maxima, sourceforge.net.
Classes 293
Exercice 69. Soient {Un)neN et deux suites relles donnes par les dfinitions m u
tuellement rcurrentes :
uo = 2 e t vq = -3
Un+l = - U n ~ V n , \ / n ^ 0
4 5
i^n+i = - U n + -i^ n ,
a) Montrer que, pour certaines valeurs particulires de que prcisera, la suite cor
respondante est une suite gomtrique.
b) En dduire une expression indpendante de chacun des termes Un et Vn.
On laisse en exercice au lecteur le fait de dmontrer que la suite est gomtrique pour
1 3
les deux valeurs k\ = - et ko -
2 2
Afin dillustrer ru tilisatio n du module e x p re s s io n . py , nous allons voir comment nous
pouvons observer le comportement des trois suites. On peut par exemple calculer les dix pre
m iers termes de chacune des trois suites, et afficher les premiers quotients :
Solution.
exemplel.py
from modules_calc3 import *
#
# s u i t e U ( d f i n i e par rcurrence)
#
def u_suivant(u, v ) :
return (-U - v)
#
-O
O # s u i t e V ( d f i n i e par rcurrence)
c
Q
#
a = ex_t.expression("4/3").lire_valeur()
'i
H
O b = GX_t.expression("5/3").lire_valGur()
def v_suivant(u, v ) :
XI
CT gl ob al a
> gl ob al b
Q .
O return (a * u + b * v)
U
#
# s u i t e t (combinaison l i n a i r e de u e t v)
#
def t ( u, V, k ) :
return (u + k * v)
294 Programmation en Python pour les mathmatiques
#
# premiers termes
#
u_ 0= ex _t .e xp re ss io n( " " ) . l i r e _ v a l e u r ( )
2
v_ 0= e x _ t . e x p r e s s i o n ( " - 3 " ) .l i r e _ v a l e u r ( )
#
# c a l c u l e t impression des dix premiers termes de chaque s u i t e
#
def c a l c u l s ( k ) :
U, V = u_0, v_0
fo r n in range( ): 1 0
print("u_" + s t r ( n ) , u)
print("v_" + s t r ( n ) , v)
d = t ( u, V, k)
print("k_" + s t r { n ) , d)
if n > : 0
U, V = u_suivant(u, v ) , v_suivant(u, v)
#
# calculs
#
print ( " .........")
k = ex_t.expressionC'k").lire_valeur()
c a lc ul s( k)
TJ
O ca lc u ls (k )
c
=3
Q print ( " ......... ")
y>
I k = ex_t.expression("3/2").lire_valeur()
O
r\l ca lc u ls (k )
(y)
XI
DJ
>- On pourra au passage observer la forme gnrale inattendue prise par la raison de la suite
Q .
O
U
Les connaissances dalgbre linaire permettent dexam iner la situation du point de vue m a
triciel. Le traitem ent du problme fait intervenir la m atrice A :
( -1 -1
4 5
^3 3
Classes 295
On montre ci-dessous comment tablir avec la librairie c a lc 3 le polynme det (A - AI) utile
la diagonalisation de la m atrice A. Pour sim plifier le code et tenir compte du fait que c a lc3
m anipule uniquem ent des entits dont le nom est lim it une lettre unique, nous adopterons
la convention x = X dans ce qui suit.
#
# la fonction msomO c i - d es s o u s e s t c e l l e vue au c h ap i tr e 3
#
def msom(A,B):
i f lignes(A) != lignes(B) or cols(A) != cols(B):
return " T a i l l e s non compatibles"
e ls e :
return [ [ A[ i ] [ j ] + B[ i ] [ j ] f o r j in cols(A)] f o r i in lignes(A)
#
# impression de la matrice M " la maxima"
#
def montrer_matrice(M):
fo r k in M:
s = "\ t[ "
fo r a in k:
s += "\t" + s t r ( a )
p r i n t (s + "]")
#
# c o n s t r u c t io n de la matrice A
#
a i l = ex_t.expression("-l").lire_valeur()
a l = ex_t.expression("-l").lire_valeur()
2
O # c o n s t r u c t io n de la matrice B = -x *I
(N
#
X = e x _ t . e x p r e s s io n ! " x " ) . l i r e _ v a l e u r ! )
x:
OJ bll = -X
>- bl 2 = e x_ t. e xp re ss io n! " "). li re _v al eu r! )
CL
O b 2 1 = e x_ t. e xp re ss io n! " "). li re _v al eu r! )
U
b22 = -X
B = [ [ b l l , b l 2 ] , [b21, b22]]
#
# matrice S = (A - x * Id )
#
S = msom!A, B)
296 Programmation en Python pour les mathmatiques
montrer_matrice(S)
#
# dterminant de la matrice 5
#
det = S[0][0] * S [1 ][1 ] - S [0 ][1 ] * S [1 ][0]
p r i n t (det)
Le programme nous donne une vue de la m atrice A - A I et son dterminant (la sortie du
programme est sans fioritures) :
Terminal
[(-1 ) (-1)1
[4/3 5/3]
[(-1 ) X + (-1) (-1)1
[4/3 (-1) * X + 5/3]
'2 + (-2/3) * X + (-1/3)
Nous nirons pas plus loin sur cet exemple car notre propos tait de fournir une preuve de
fonctionnement du projet c a lc 3 . La bote outils du projet ne demande qu tre compl
te par son utilisateur en fonction de ses propres besoins.
Signalons enfin lexistence pour le calcul numrique et le calcul formel avec Python de
nombreux projets, dont les programmes NumPy et SymPy, conus pour Python, sans oublier
le vaste projet SAGE.
a
O
D
c 6.3 Les types et leurs oprations
KD Dans la dfinition de notre projet de calculateur, nous faisons lhypothse raisonnable que
tH
O Python m anipule convenablement les nombres entiers relatifs, y com pris les entiers de trs
CM
(y) grandes valeurs (ce qui nest hlas pas le cas dune m ajorit de langages), sans autres lim ites
JZ que celles imposes par lenvironnement dexcution de Python (consulter la documenta
ai
> tion de Python concernant les types natifs).
CL
O
U Nous donnons dans le tableau suivant les oprations internes selon le type des oprandes :
type -h - X A
entier rel. - exposant dans N
nombre rat. exposant dans Z
polynme - exposant dans N
fraction rat. exposant dans Z
Classes 297
Prcisons que, pour notre tude, non cartons les exposants non explicites.
Nous traduisons directement ces choix en donnes structures sous forme de hirarchies
dobjets.
Pour implmenter ces types, nous utiliserons les structures de donnes suivantes :
- entier : un objet du type e n tie est bas sur le type natif long. Comme les autres types,
il comporte un indicateur de validit.
- nombre rationnel : comme on sen doute, un ra tio n n e l est une paire de deux e n tie r .
Lors de sa cration, un objet ra tio n n e l est systmatiquement norm alis, cest--dire
rduit, avec le dnom inateur rendu positif. Les autres modules du programme tiennent
pour acquis quun ra tio n n e l est norm alis.
- monme : un monme peut tre vu comme un nud dans un arbre binaire de re
cherche. Plus prcism ent, un nud darbre binaire reprsentant un polynme com
porte un membre de type monome. Un monome est alors lagrgation dun coefficient (de
type ra tio n n e l) et dune chane de caractres, dveloppant en extension toutes les in
dtermines du monme.
- polynme : pour reprsenter un tel objet, nous avons retenu la structure darbre binaire
de recherche, et non celle de liste, comme on pourrait y songer premire vue. En ef
fet, nous dfinissons un ordre sur les monmes, do lintrt dun arbre binaire de
recherche. Ce type de structure facilite en effet considrablem ent la conservation de
lordre lors de linsertion ou de la suppression dun lment de larbre. On peut vi
demment obtenir une conservation de lordre des monmes sur une liste, mais au prix
dalgorithmes plus complexes ou moins efficaces. On notera au passage que nous u ti
lisons, pour la m ultiplication des polynmes, un parcours de larbre en largeur, pour
appliquer ensuite la rgle usuelle de distributivit.
- fraction rationnelle : un tel objet est constitu de deux polynmes.
- pour la lecture de lexpression, nous utiliserons une structure de queue LIFO prsente
prcdemment. Nous avons privilgi les listes natives de Python.
a - pour lvaluation de lexpression, nous avons repris lim plm entation du programme
O calc2, en la m odifiant lgrement afin de calculer demble sur des entiers ou des litt
c
D
raux, avec cette fois le type f ra c tio n comme type de base pour les calculs.
1-4
O
(N
Pour ce dernier point, nous avons effectu un nouveau choix dim plm entation. Prsentons
soiz une premire possibilit (les types ci-dessous sont factices, dans le seul but dillustration) :
>
Q. ------------------------- [ T erm inal] ------------------------------------------------------------------------------------------------------------
O > a = polynomeC'x + ") 1
U
> c = a + b
>
Du point de vue de lutilisateur des classes, nous avons dcid de dfinir nos objets pour
lutilisation suivante :
298 Programmation en Python pour les mathmatiques
[ Terminal
> a = expression("x + ") 1
> c = a + b
>
Nous avons choisi dcarter la premire im plm entation, afin de conserver des variables a et
b dclares de nature homogne. Au contraire, dans le prem ier cas, nous aurions eu grer
les nombreuses situations de conversion de types. Par exemple, pour la seule addition, nous
aurions eu exam iner nous-mmes les situations dhtrognit des arguments (cest--dire
en concevoir les mthodes) :
- sans oublier les oprations internes qui sont codes au sein de chaque type.
Les deux premires lignes ci-dessus illustrent la ncessit de dcrire la comm utativit de lad
dition dans lcriture des mthodes daddition des types dfinis par le concepteur du pro
gramme. Par exemple, les appels :
a d d it io n ( e n t ie r ( 2 ) , r a t io n n e l( l, 3 ))
a d d it io n !r a t io n n e l( l, 3 ) , e n t ie r ( 2 ) )
doivent produire la mme valeur en retour, alors que les types respectifs des deux arguments
TJ
sont distincts. Cette approche entrane un contrle de type ncessaire pour chaque argument,
O
c ainsi quune conversion si besoin. Lapproche retenue consiste quant elle considrer par
D
Q exemple 23 et x im mdiatement comme deux fractions rationnelles particulires.
kD
O Pour term iner la description de nos types de donnes, signalons que nos types numriques,
rs]
polynmes et fractions sont en outre m unis dun indicateur dtat de validit, destin :
DJ
>- a) vrifier la validit mathmatique des oprations (une tentative de division par zro ; un
Q .
O polynme est considr valide si et seulement si chaque monme est valid e...) ;
U
b) sim plifier le flot dexcution du programme en cas derreur dans un calcul (une opra
tion non dfinie par exemple).
Dans la situation o une instance mathmatiquement invalide dun objet doit tre utilise,
nous donnons des valeurs par dfaut pour cette instance (par exemple, on choisira lin s
tance ra tio n n e l ( e n t ie r ( G ) , e n t i e r ( l ) , F a ls e ) pour reprsenter un nombre rationnel
Classes 299
non dfini) : de la sorte, un objet reprsentant une valeur numrique possde toujours une
valeur, que cette dernire soit valide ou non.
Cette disposition consistant accorder la mme im portance au traitement de lerreur et aux
traitem ents mathmatiques est rapprocher de lutilisation du mcanisme dexception vu
dans les chapitres prcdents. Nous faisons ic i un autre choix, qui accorde une attention gale
au traitem ent des erreurs et des calculs, soit considrer lerreur mathmatique comme une
situation banale et pas exceptionnelle en terme de probabilit dapparition.
Par ailleurs, nous avons parfois choisi dutiliser nos propres types de donnes, l o Python
dlivre des types de nature assez proche. Les types natifs doivent tre prfrs ds quils
conviennent parfaitem ent au problme tudi. Sil est contraire, notre choix est pourtant mo
tiv par la possibilit de transfert vers dautres langages de programmation dans lesquels cer
tains types ne seraient pas dfinis au sein du langage (contrairem ent beaucoup dautres.
Python propose par exemple un type pour la notion de liste).
Signalons enfin quune notice accompagne le programme c a lcB , en prsentant les choix
retenus pour le dveloppement : elle se trouve dans larchive des programmes du livre, dispo
nible en ligne sur le site de lditeur.
Dans le projet c a lc 3 , nous en sommes rests, en ce qui concerne les exposants, aux nombres
entiers relatifs explicites ; ce qui exclut de toute valuation des constructions telles que ( 4 9 ^
o u f l" X f l^ .
kD dans ladaptation du projet c a lc2 en c a lc 3 , par quelques simples m odifications dans la tra
O duction de notre grammaire, au niveau du module e x p re s s io n . py. On sent alors toute la
rs]
puissance dabstraction fournie par les concepts de la programmation oriente objet. Ainsi
un bon dcoupage des objets, et de leurs interactions m utuelles, peut garantir quun change
ai
ment dans l im plm entation dun objet na que peu deffets de bord sur les autres objets mis
>
Q. en jeu dans le programme.
O
U
On pourra galement sintresser la drivation form elle ou au calcul intgral, ainsi quau
calcul propositionnel, en considrant un type boolen et ses oprations.
Enfin, un autre type de prolongation de ce que nous avons tudi est la ralisation dun petit
langage de programmation. L encore, on pourra considrer quune grammaire tant fixe
pour un langage (de programmation), on peut traduire laide des constructions reconnues
par ce langage, un programme en un arbre utilisable par un interprte ou un compilateur.
300 Programmation en Python pour les mathmatiques
Pour conclure, signalons que le code source complet du projet calc3 est disponible en ligne
sur le site de lditeur consacr au livre.
7 E x e r c ic e s d e n t r a n e m e n t
Les corrigs so n t disponibles sur le site du n od.com p a rtir d e la page d'accueil d e l'ouvrage.
Par dfaut le comportement de la classe m a lis te est celui dune structure de file.
On demande ensuite de crer deux classes filles maf i l e et m apile qui hritent de la classe
m a lis te , pour la spcialiser respectivement en deux structures de file et de pile.
Exercice 71. On sintresse ici lvaluation dune expression mathmatique telle que :
4 x (2 + 3 ) - 5 ,
tH
Exercice 72. (Fractions continues - 2partie) On rappelle la convention adopte pour repr
O senter les fractions continues sous forme de listes :
CM
(y) 111 1
4-1
XI = 2+
CTI
1+
>- 1
Q. 3+
O 1
U
2+ -
4
cest--dire :
111
= [2;1;3;2;4]
On demande dcrire un programme qui donne la fraction rduite dun nombre rationnel
dsign par sa reprsentation sous forme de liste dentiers.
Classes 301
F ig u re 6.15 - Un arbre quilibr en profondeur : une rotation gauche puis une rotation
droite rquilibrent Farbre en hauteur.
Exercice 73. On sintresse dans cet exercice la reprsentation dun irrationnel quadratique
du type \ , k entier naturel non carr parfait, sous la forme dune fraction continue : on sait
dans ce cas que le dveloppement est priodique.
Lalgorithme suivant permet de mener bien le calcul de la priode, partir de trois suites
rcurrentes {an)nN> i ^n) neN valeurs dans N, dfinies par :
ao = [ k\ , do = l , mo = 0
puis :
k - m ^n+l
i ^0 + ^72+1
f^ n + i ^ n d n ^ n > d fi+ i y ^n+l
dn d n+l
Les calculs successifs des triplets (m , dn, cin) aboutissent un triplet dj obtenu, auquel cas
la priode est atteinte :
\/lc ^ClQfClifCl2} - }Clp^
Par exemple, on a :
V u = [3,1,2,1,6]
y> Exercice 74. On connat lexistence darbres binaires dgnrs, qui perdent leur performance
11
O
rs] quand il sagit deffectuer un parcours. Pour viter cet inconvnient, on peut utiliser la notion
(S) darbre quilibr en profondeur, aussi appel arbre AVL (du nom de ses inventeurs Geor-
ai gii A d e l s o n -V elskii et Evguenii La n d i s ).
>
Q . Pour chaque nud, on calcule la diffrence de hauteur entre les sous-arbres gauche et droit.
O
(J Pour insrer un nouveau nud dans larbre, on impose de m aintenir une diffrence des hau
teurs valant -1 , 0 ou 1, ventuellement au moyen de rotations des sous-arbres, comme
montr sur la figure 6.15.
[Amm96] Leendert A m m e ra al :
A lg o rith m es e t stru ctu res d e d o n n es en lan gage C.
Interditions/M asson.
1996.
[Bai08] Yves B a i l l y :
In tro d u c tio n la p ro g ra m m a tio n a vec P yth o n e t C++.
Pearson.
2008.
[Boo92] Grady B o o c h :
C on ception o rien te o b je ts e t a p p lic a tio n s.
Addison Wesley.
1992.
[B ri9 l] Guy B r ia n d :
O TT et la galaxie des arctangentes.
]
[Dow08] Gilles D o w e k :
Les p rin c ip e s des lan gages d e p ro g ra m m a tio n .
ditions de lcole Polytechnique.
2008.
[DowlO] Gilles D o w e k :
Les d m o n stra tio n s e t les a lg o rith m e s : in tro d u c tio n la logiqu e e t la ca lcu labi-
lit.
Inform atique. d. de lcole polytechnique, Palaiseau.
2010.
TJ
O [Eng92] Arthur E n g e l :
c
rj
M a th m a tiq u e s lm en ta ires d'u n p o in t d e vu e a lg o rith m iq u e.
JD
tH Cedic.
O
CM 1992.
(y)
sz [FC02] Grard F leury et O livier COGis :
OJ
G raphes d eu x voix.
>-
Q. APMEP.
O
U
2002.
[Fou06] Laurent F o u s s e :
In tgration n u m riq u e a v e c erreu r b orn e en prcision arbitraire.
PhD in Computer Science, Universit Henri Poincar - Nancy 1.
h tt p :/ / k o m it e . n e t/ la u re n t/ d a ta / p ro / p u b lis / th e s e - 20070228.pdf.
2006.
304 Programmation en Python pour les mathmatiques
[Gol91] David G o l d b e r g :
What every computer scientist should know about floating point arithmetic.
A C M C o m p u tin g Surveys, 23(l):5-48, 1991.
[Gra06] Scott G r a n n e m a n :
L in u x : L!essen tiel d u code et des co m m a n d es.
Campus Press.
2006.
[Kahl4] William Ka h an :
Page personnelle.
h ttp : //\fjvM. CS . b e rk e le y . edu/~wkahan/.
2014.
TJ
O [KD98] W. Kah an et Joseph D. D arcy :
c How Javas floating-point hurts everyone everywhere.
rj
Technical report, inst-BERKELEY-M ATH-EECS, inst-BERKELEY-M ATH-
O EECS :adr.
rs]
h ttp : / / W W W . c s . b e rk e le y . edu/~wkahan/JAVAhurt. pdf.
(S)
juin 1998.
CT
> [Lan09] Hans Peter La n g t a n g e n :
CL
O A p r im e r on scie n tific p ro g ra m m in g w ith P ython.
U
Springer.
2009.
[Ste73] RH. St e r b e n z :
F lo a t in g -p o in t co m p u ta tio n .
Prentice-Hall series in automatic computation. Prentice-Hall.
h t t p : //b o o ks. google. f r/books?id=MKpQAAAAMAAJ.
1973.
[Sum08] Mark S u m m e r f ie l d :
P ro g ra m m in g in P yth o n 3 - A C o m p le te In tro d u ctio n to the P yth o n La n g u a g e .
Addison Wesley.
2008.
a
O
c [SwilO] Grard Sw i n n e n :
A p p ren d re p ro g ra m m e r en P yth o n 3.
O Eyrolles.
(N
2010.
A conventions de codage, 14
accesseur, 250 copie
affectation, 3 profonde, 25
s parallles, 5 rcursive, 25
s simultanes, 5 superficielle, 24
algorithme C ornu (spirale de ), 208
CORDIC, 130
de HRON, 122, 185 D
de H orner, 35,45,200 D e C u es , Nicolas, 149
de N ewton, 213 dictionnaire, 32,130,170, 174
d'EUCLIDE, 19 division (en base 2), 137
alias, 5, 24 d o c s t r in g , 42
approximations, 122 drivation numrique, 203
arbre binaire dveloppement asymptotique, 210
recherche, 266
ASCII, 94
encapsulation, 43
B encodage, 11
BNF, 286 ensemble, 32
BZOUT (coefficients de), 95 erreur
boolen absolue, 181
fonctionsns, 16 de troncature, 205
oprateurss, 15 relative, 181
variablene, 15 erreur de consistance, 189
boucle, 18, 28 et, 115
exceptions, 40
exponentiation rapide, 34
XJ chane de caractres, 11, 94
O
c
rj chiffrement F
LJ
kD de H il l , 93 Fibonacci (suite de), 220,222
O classe, 43 files, 257
rsj
constructeur dune , 44 flottant, 150
4 -1 drive, 46 fonction, 7
OJ instancier une , 44 rcursive, 33
s_
CL
O parente, 46 format
U commentaire, 3 CSV, 68
Complexit, 112 EPS, 70
complment 1 ,117 PDF, 70
composition, 275 formule
concatnation, 80 de R o d rig u es , 212
console, 2 dEULER-MACLAURIN, 209
constructeur, 44, 260 fractions continues, 119
IN D EX G E N E R A L 307
mthode
Ga lio n (machine de ), 58 adaptative, 215
gnrateur d'expression, 40 de dichotomie, 182, 209
graphes, de Gauss -Jordan , 87
de Gauss -Legendre, 211
H de KuNCiR, 215
historique (de la console), 3 de la photo de classe, 181
hritage, 46, 275 de la scante, 185
multiple, 47 de M o n te -Carlo , 54,55
de N ew ton , 184
I
de N ewton-C otes, 205,206
identifiant, 3
de quadrature de Gauss , 206,211
Id le , 2
de Richardson , 209,215
inclusion, 172
de R om berg , 209
interpolation polynomiale, 199
de Runge -Kutta, 193
intgration numrique, 151, 205
de Sim pson , 152,207,215
iPython, 85
deBRiGGS, 126
itrateur, 28, 39
des diffrences de N ew ton , 127
des diffrences divises, 199
lis t - c o m p r e h e n s i o n s , 30 des moindres carrs, 203
liste, 20 des rectangles, 151
par comprhension, 172 des trapzes, 151, 209
s par comprhension, 30 dEULER, 187
liste dadjacence, 238 du point fixe, 183
rgula falsi , 183
M
mantisse, 31,180 N
Markov (chanes de), 98 nombre
matrice, 78 (pseudo-)alatoire, 53
dadjacence, 238 complexe, 144
inverse, 88 en notation scientifique, 31, 61, 180
a oprations lmentaires, 87 entier, 112
O
c
13 module, 51 irrationnel, 124
JD
tH Q U
O
CM queues, 257 urne, 164
(y) qu icksort, 37
-M
XI V
U i
> .
R variable, 3
Q. relations binaires, 170
O dinstance, 43
U
rduites (dune fraction continue), 121 locale, 9
R unge (phnomne de ), 201, 206 vectorisation, 74,196
VON K och (flocon de ), 57
S
Sage, 132
saucissonnage, 21
schma numrique
Index des commandes
A finally, 41 N
allclose, 78 float, 31, 38, 61,246 np.eye(n), 79
append, 26, 176 float(in f), 175 numpy, 84, 103
array, 103 float_info, 150
assert, 81 for, 28,171 O
format, 12 open, 64, 69
B from, 52 operator, 83
bin, 38 ord, 38
bool, 38 G os, 66
get, 175, 176 ou
C getcontextO.prec, 156 115
chr, 38, 94
class, 44, 146 H P
clock, 60 help, 37 plot, 73
close, 64 print, 2
complex, 38 I pylab, 103
copy, 171 id, 171
count, 164 if, 14 R
Cython, 85, 162 import, 52, 126 raise, 41
imread, 104 randint, 164
D in, 27 random, 53, 178
decalage input, 13 range, 28
, 118 int, 31, 38 read, 65
, 107,118 isinstance, 38 readlines, 65
decimal, 61, 156, 246 iter, 97 return, 80
deepcopy, 171, 174 reverse, 167
*Q def, 7 J
o del, 27 S
c. join, 80, 94
3 self, 44
diet, 32, 38, 176
KD
dtype, 84 K set, 32, 38,170
o key, 176 shape, 84
rsj
E shuffle, 178
4-< elif, 17 L sort, 167
JZ
cn
else, 15, 41 lambda, 42 split, 66, 102
Q. epsilon, 150 len, 27 str, 32, 38
O
U sum, 83
&, 115 less, 38
eval, 13 list, 32, 38, 83, 235 sys, 63, 180
except, 41 sys.argv, 63
exec, 14 M sys.path, 53
map, 82
F math, 53 T
False, 15 min, 176 time, 60
310 Programmation en Python pour les mathmatiques
timeit, 85 W Y
True, 15 while, 18 yield, 80
try, 41
with, 66
tuple, 32,38
turtle, 56,232 write, 64 Z
type, 13, 84 writelines, 64 zeros, 84