Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Tp1 33 (Tres Important)

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 196

TP d’informatique PCSI

Table des matières

TP 1 : Introduction à P YTHON et S PYDER, variables et fonctions 5

TP 2 : Nombres et calculs avec P YTHON 9

TP : Rattrapage des TP 1 et 2 15

TP 3 : Boucles for 19

TP 4 : Instructions conditionnelles 25

TP 5 : Boucles while 29

TP 6 : Sommes et produits 33

TP 7 : Listes 41

TP 8 : Listes (2) et preuves de programmes 49

TP 9 : Simulation d’un système en physique, chimie, SII 53

TP 10 : Listes (3) et complexité 59

TP 11 : Chaînes de caractères 67

TP 12 : Gestion des fichiers 75

TP 13 : Tableaux à 2 dimensions, images et calcul matriciel 81

TP 14 : Présentation générale de S CILAB 87

TP 15 : Représentations graphiques 91

TP 16 : Approximations de racines et d’intégrales (1) 97

TP 17 : Approximations de racines et d’intégrales (2) 103

TP 18 : Approximations de racines et d’intégrales (3) 109

TP 19 : Équations différentielles d’ordre 1 113

TP 20 : Méthode d’Euler 119

TP 21 : Calcul matriciel et systèmes linéaires 125


TP 22 : Systèmes d’équations 135

TP 23 : Systèmes d’équations différentielles 141

TP 24 : Équations différentielles d’ordre 2 149

TP 25 : Régressions linéaires 155

TP 26 : Calcul numérique – TP noté 159

TP 27 : Introduction à la structure de graphe 161

TP 28 : Introduction aux BDD 165

TP 29 : Interroger une BDD 169

TP 30 : Exemple d’utilisation d’une BDD 177

TP 31 : Ave Cesar (zud bdrzq) 183

TP 32 : Dépouillement d’élections 187

TP 33 : Quelques exercices du site http://www.france-ioi.org/ 193


TP 1 : Introduction à Python et Spyder, variables et fonctions

Mise en place de l’environnement Spyder

• Lancer P YTHON (x,y) ;

• Cliquer sur l’icône S PYDER et attendre que S PYDER apparaisse (c’est un peu long) ;
• Aller dans Affichage/Fenêtres et barres d’outils et selectionner (uniquement) :

3 Éditeur
3 Explorateur de variables
3 Consoles
3 Barre d’outil fichiers
3 Barre d’outil exécution

• Aller dans Outils/Préférences :


— Dans l’onglet Répertoire de travail global, sélectionner Le répertoire suivant, puis définir
un nouveau répertoire TPinfo dans Mes documents,
— Dans l’onglet Éditeur/Affichage, choisir une police de taille minimale 11 et choisir le
thème de coloration syntaxique Scintilla,
— Dans l’onglet Console/Affichage, choisir une police de taille minimale 11,
— Dans l’onglet Console/Options avancées, sélectionner Script PythonStartup par défaut ;
• Aller dans Fichier/Enregistrer la session et quitter, choisir spyder.session comme nom de
fichier et l’enregistrer dans le répertoire Mes documents ;
B Si vous vous connectez sur un autre ordinateur, vous ne retrouverez pas votre configuration
de S PYDER mais vous pourrez la récupérer à partir de Fichier/Charger une session en allant
chercher le fichier spyder.session dans Mes documents ;
• Relancer S PYDER ;
• Lancer Firefox, aller sur http://alexandre.boisseau.free.fr, choisir Informatique
PCSI 1 et enregistrer la page dans les signets ;
• Dans Documentations, choisir P YTHON et enregistrer la page dans les signets.
Les exercices
¦ À traiter dans l’ordre. Le symbole . indique une question qui ne fait pas appel à l’ordinateur (à
résoudre avec papier et crayon).

Exercice 1 ( P YTHON comme une calculatrice) : Taper les commandes suivantes dans une console
(ouvrir une nouvelle console si-besoin) et noter ce qui se passe (le symbole ↵ désigne la touche
Entrée, par la suite on ne l’indiquera plus) :

5+3↵
2-9↵
7+3*4↵
(7+3)*4↵
3**3↵
3**0.5↵
5/2↵ BL’opération / appliquée à des entiers réalise une division entière

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp1.pdf
5.0/2↵
5/2.0↵
float(5)/2↵
4*2.5/3↵

Les commandes suivantes définissent et utilisent des variables (regarder ce qui se passe dans l’ex-
plorateur de variable au fur et à mesure) :

x=10↵
x=x+1↵
largeur=20↵
hauteur=5*9.3↵
v=largeur*hauteur↵
print v↵
largeur=10↵
print v↵

Astuce : x=x+1 peut aussi s’écrire x+=1. Pour finir, tester les commandes :

type(largeur)↵
type(hauteur)↵
type(v)↵

Exercice 2 (Un premier programme : aire d’un disque) :


(a) Aller dans le menu Fichier puis Nouveau fichier. Taper le programme suivant dans l’éditeur
(laisser tel quel les lignes écrites au début du fichier par S PYDER) :

from math import pi


r=input("Entrez le rayon du disque : ")
s=pi*r**2
print "L’aire du disque est", s

Enregistrer le programme (menu Fichier) dans le répertoire approprié et en lui donnant un


nom pertinent. Lancer le programme (F5) et sélectionner les choix suivants :
• Exécuter dans un nouvel interpréteur P YTHON dédié ;
• Intéragir avec l’interpréteur P YTHON après l’exécution.
BÀ retenir : ce sont les choix que l’on fera systématiquement.
(b) Que représentent les variables r et s ? Que font les commandes input et print ? Supprimer
la ligne from math import pi et lancer à nouveau le programme, que se passe-t-il ?

Exercice 3 (Une première fonction : canette optimale) : On considère un cylindre de hauteur h et de


rayon r . On note S sa surface (c’est la somme de la surface latérale et de la surface des deux disques).
(a) Créer un nouveau programme qui demande h et r et qui calcule, puis affiche, la surface du
cylindre de rayon r et de hauteur h. Enregistrer ce programme (en lui donnant un nom appro-
prié) puis l’exécuter.
(b) Modifier le programme précédent pour qu’il demande h mais plus r : r est calculé en fonction
de h de sorte que le volume du cylindre soit 0.33.
(c) Tester ce programme pour quelques valeurs de r .
(d) En faisant quelques essais, trouver la hauteur d’un cylindre de 33 cl dont la surface est mini-
male (indication : chercher entre 7 et 8 et obtenir une précision d’un chiffre après la virgule).
(e) On peut présenter les calculs précédents sous forme d’une fonction :

from math import *


def surf_canette(h):
# h : hauteur de la canette (cm)
# Résultat : surface de la canette de hauteur h, rayon r
# r choisi de sorte que le volume soit 330 cm^3=33cl
v=330
r=sqrt(v/pi/h)
return 2*pi*r**2+2*pi*r*h

Écrire cette fonction dans un nouveau programme, l’enregistrer sous un nom approprié puis
l’exécuter. Taper ensuite dans la console :

surf_canette(5) ¦ Astuce : dans une console, appuyer sur la touche ↑ (flèche vers
surf_canette(6) le haut) permet de répéter (et éventuellement modifier) les com-
surf_canette(7) mandes entrées précédemment.
surf_canette(8)
surf_canette(9)

Retrouver avec quelques essais dans la console la valeur de h pour laquelle la surface est mi-
nimale.
(f) . Justifier mathématiquement la valeur obtenue à la question précédente.

¦ Pour représenter graphiquement une fonction, par exemple la fonction surf_canette précé-
dente sur l’intervalle [1, 15], on utilisera les commandes suivantes (dont la signification sera vue
ultérieurement) :

800
import numpy as np
import matplotlib.pyplot as plt 700

hv=np.linspace(1,15,100) 600

plt.plot(hv,[surf_canette(h) for h in hv]) 500

400

300
plt.show()
200
0 2 4 6 8 10 12 14 16
TP 2 : Nombres et calculs avec Python

¦ Avant tout :

• Lancer S PYDER directement avec l’icône sur le bureau ;


• Retrouver votre configuration de la semaine dernière avec Fichier/Charger une session en al-
lant chercher le fichier spyder.session dans Mes documents.

Exercice 1 Quelques calculs avec le module math : On utilisera en général ce module en écrivant :

from math import *

au début d’un programme ou dans une console. On a ainsi accès directement à toutes les fonctions
du module math, par exemple :

print pi, sin(pi),cos(pi)


print e, exp(1), log(e)

Utiliser les fonctions du module math pour traiter les calculs des questions suivantes.
(a) Datation au carbone 14. À la mort d’un être vivant, le carbone 14 présent dans son organisme
se désintègre au fil des années de sorte que, si p est la proportion de C 14 restante au bout de
N années, alors N = −8310 ln(p).
• Écrire une fonction datation_C14(p) qui calcule N en fonction de p.
• La momie Ötzi retrouvée dans un glacier en 1991 contenait 52.8% du C 14 initial à 1%
près. Donner un encadrement de son âge.
• L’Australopithecus afarensis Lucy, découverte en 1974 a un âge estimé à 4.4 millions d’an-
nées. Estimer la proportion de C 14 restante. A-t-on pu effectuer la datation du squelette
au C 14 ?
(b) Calculs de distances. Un bateau navigue en suivant un certain cap. À un instant donné, le ba-
teau est en position B 1 et le commandant repère un récif R sous un angle de 22◦ . Un mile plus
loin, en position B 2 , le commandant repère ce même récif R sous un angle de 34◦ . Calculer la
distance H R (distance entre le récif et la trajectoire).

22◦ 34◦
B1 B2 H Trajectoire
1 mile

tan(22◦ )
On pourra commencer par calculer la distance : B 2 H = .
tan(34◦ ) − tan(22◦ )
BLes fonctions trigonométriques sin, cos, tan de P YTHON travaillent en radians et non en
degrés.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp2.pdf
Exercice 2 Nombres complexes avec P YTHON et module cmath : On peut définir et calculer avec
des nombres complexes. Un nombre complexe z = a + ib se note a+bj ou complex(a,b) avec
P YTHON. Attention : le complexe i se note ici complex(0,1) ou 0+1j ou plus simplement 1j.
(a) Tester dans une console les commandes suivantes :

z1=2+1j z1.real
z2=complex(1,2) z1.imag
z1+z2 z1.conjugate()
z1*z2
z1/z2 BIl y a bien des parenthèses après
z1**2 conjugate (et pas après real et imag).

(b) Chercher dans la documentation en ligne de P YTHON le module cmath et regarder les diffé-
rentes fonctions proposées. À quoi correspondent les fonctions abs, phase, polar et rect ?
(c) Écrire sous forme algébrique les nombres complexes :

1 − 2i 2+i (1 − 4i)(1 − i)
, ,
3+i 2−i (1 + i)2

Déterminer également le module et un argument de chacun de ces nombres.


(d) On considère les nombres a = 3, b = 6 et c = 8 + i. Vérifier numériquement, avec P YTHON, que
arg(c) + arg(c − a) + arg(c − b) = π/4.

Exercice 3 Comprendre et modifier un programme : On considère la fonction suivante :

def ecriture_base_10(n):
if n==0:
print 0
else:
print n%10
ecriture_base_10(n/10)

(a) Taper ce programme dans l’éditeur et l’enregistrer sous un nom pertinent.


(b) Lancer le programme puis faire quelques tests dans la console (essayer par exemple dans la
console ecriture_base_10(209), essayer ensuite avec d’autres nombres).
(c) Que réalise la fonction ecriture_base_10 ?
(d) En s’inspirant de cette fonction, écrire une fonction qui réalise la décomposition en binaire
(base 2).
(e) Modifier les deux fonctions précédentes pour qu’elles affichent les chiffres de la décomposi-
tion « de la gauche vers la droite. »

Exercice 4 Quelques calculs en base 10 et en base 2 :


(a) . Quel est le plus grand nombre que l’on peut écrire avec (au plus) p chiffres en base 10 ?
(b) . Quel est le plus petit nombre qui s’écrit avec exactement p chiffres en base 10 ?
(c) . Soit n un entier et p le nombre de chiffres dans l’écriture de n en base 10. Déterminer un
encadrement de n à l’aide de p puis en déduire un encadrement de p à l’aide de ln(n).
(d) . Reprendre les questions précédentes en base 2.

Exercice 5 Les nombres flottants : Un nombre flottant x est représenté dans l’ordinateur sous la
forme :

x = m · 2p
où m et p sont des entiers relatifs (il y a de plus quelques conditions sur m et p). . Le nombre 0.25
peut-il se représenter exactement sous cette forme ? . Montrer que le nombre 0.1 ne peut pas être
représenté exactement sous cette forme. Ceci explique que même un calcul simple comme 0.1 + 0.2
présente déjà des problèmes d’approximation.
TP 2 : Nombres et calculs avec Python

Éléments de correction
Ex. 3 : Pour afficher les chiffres de la décomposition de la gauche vers la droite :

def ecriture_base_10_gauche(n):
if n==0:
print 0
else:
ecriture_base_10_gauche(n/10)
print n%10
Par exemple :

ecriture_base_10_gauche(209)

0 2 0 9
Pour avoir des décompositions en binaire, on remplace les 10 par des 2 dans les programmes précé-
dents.

Ex. 4 : (a) Le plus grand nombre que l’on peut écrire avec au plus p chiffres en base 10 est :

99 · · · 9 = 10p − 1
p chiffres

Par exemple le plus grand nombre qui s’écrit avec 3 chiffres en base 10 est 999 = 1000 − 1 =
103 − 1.
(b) Le plus petit nombre qui s’écrit avec exactement p chiffres en base 10 est :

100 · · · 0 = 10p−1
p chiffres

Par exemple le plus petit nombre qui s’écrit avec 3 chiffres en base 10 est 100 = 102 .
(c) Si n s’écrit avec p chiffres en base 10, alors d’après ce qui précède 10p−1 É n É 10p − 1, ou
encore :

10p−1 É n < 10p

On applique la fonction ln (strictement croissante) :

(p − 1) ln(10) É ln(n) < p ln(10)

puis on divise par ln(10) (qui est strictement positif) :

ln(n)
p −1 É <p
ln(10)
On en déduit l’encadrement de p :

ln(n) ln(n)
<pÉ +1
ln(10) ln(10)
(d) Dans le cas de la base 2 :
• Le plus grand nombre qui s’écrit avec p chiffres en base 2 est 2p − 1 ;
• Le plus petit nombre qui s’écrit avec exactement p chiffres en base 2 est 2p−1 ;
• Si un entier n s’écrit avec exactement p chiffres en base 2, alors 2p−1 É n É 2p − 1 ou
encore 2p−1 É n < 2p ;
• En appliquant la fonction ln, on obtient (p − 1) ln(2) É ln(n) < p ln(2) et on en déduit :

ln(n) ln(n)
<pÉ +1
ln(2) ln(2)

Ex. 5 : Le nombre 0.25 est égal à 1/4, on a donc 0.25 = 2−2 . Par conséquent, 0.25 peut s’écrire sous
la forme m · 2p avec m = 1 et p = −2. Pour montrer que 0.1 ne peut pas s’écrire exactement sous
la forme m · 2p , on fait un raisonnement par l’absurde. On suppose donc que le nombre 0.1 peut
s’écrire 0.1 = m · 2p avec m et p des entiers. Alors m est un entier strictement positif, donc m Ê 1.
Comme 0.1 < 1, on a nécessairement p < 0 (car si o avait p Ê 0, on aurait 2p Ê 1 et m ·2p Ê 1). Notons
q = −p de sorte que q > 0. L’égalité 0.1 = m · 2p peut également s’écrire 2q = 10m. On en déduit que
le nombre 2q doit être divisible par 5, or ceci est impossible. On donne deux justifications possibles :
— On remarque qu’une puissance de 2 a nécessairement pour dernier chiffre 2, 4, 6 ou 8 (excepté
20 ) alors qu’un nombre divisible par 5 a pour dernier chiffre 0 un 5. Ainsi, une puissance de 2
n’est jamais divisible par 5 ;
— Le seul facteur premier qui apparait dans la décomposition de 2q est 2 alors que le nombre 5
apparait dans la décomposition en facteurs premiers de 10m. Par conséquent 2q ne peut pas
être égal à10m.
On en déduit donc que 0.1 ne peut pas s’écrire sous la forme m · 2p . Par conséquent, le nombre 0.1
ne peut pas être représenté de manière exacte par un flottant dans l’ordinateur.
TP : Rattrapage des TP 1 et 2
Mise en place de l’environnement Spyder

• Lancer P YTHON (x,y) ;

• Cliquer sur l’icône S PYDER et attendre que S PYDER apparaisse (c’est un peu long) ;
• Aller dans Affichage/Fenêtres et barres d’outils et selectionner (uniquement) :

3 Éditeur
3 Explorateur de variables
3 Consoles
3 Barre d’outil fichiers
3 Barre d’outil exécution

• Aller dans Outils/Préférences :


— Dans l’onglet Répertoire de travail global, sélectionner Le répertoire suivant, puis définir
un nouveau répertoire TPinfo dans Mes documents,
— Dans l’onglet Éditeur/Affichage, choisir une police de taille minimale 11 et choisir le
thème de coloration syntaxique Scintilla,
— Dans l’onglet Console/Affichage, choisir une police de taille minimale 11,
— Dans l’onglet Console/Options avancées, sélectionner Script PythonStartup par défaut ;
• Aller dans Fichier/Enregistrer la session et quitter, choisir spyder.session comme nom de
fichier et l’enregistrer dans le répertoire Mes documents ;
B Si vous vous connectez sur un autre ordinateur, vous ne retrouverez pas votre configuration
de S PYDER mais vous pourrez la récupérer à partir de Fichier/Charger une session en allant
chercher le fichier spyder.session dans Mes documents ;
• Relancer S PYDER ;
• Lancer Firefox, aller sur http://alexandre.boisseau.free.fr, choisir Informatique
PCSI 1 et enregistrer la page dans les signets ;
• Dans Documentations, choisir P YTHON et enregistrer la page dans les signets.
Les exercices
¦ À traiter dans l’ordre. Le symbole . indique une question qui ne fait pas appel à l’ordinateur (à
résoudre avec papier et crayon).

Exercice 1 ( P YTHON comme une calculatrice) : Taper les commandes suivantes dans une console
(ouvrir une nouvelle console si-besoin) et noter ce qui se passe (le symbole ↵ désigne la touche
Entrée, par la suite on ne l’indiquera plus) :

5+3↵
2-9↵
7+3*4↵
(7+3)*4↵
3**3↵
3**0.5↵
5/2↵ BL’opération / appliquée à des entiers réalise une division entière
5.0/2↵
5/2.0↵
float(5)/2↵
4*2.5/3↵

Les commandes suivantes définissent et utilisent des variables (regarder ce qui se passe dans l’ex-
plorateur de variable au fur et à mesure) :

x=10↵
x=x+1↵
largeur=20↵
hauteur=5*9.3↵
v=largeur*hauteur↵
print v↵
largeur=10↵
print v↵

Astuce : x=x+1 peut aussi s’écrire x+=1. Pour finir, tester les commandes :

type(largeur)↵
type(hauteur)↵
type(v)↵

Exercice 2 (Un premier programme : aire d’un disque) :


(a) Aller dans le menu Fichier puis Nouveau fichier. Taper le programme suivant dans l’éditeur
(laisser tel quel les lignes écrites au début du fichier par S PYDER) :

from math import pi


r=input("Entrez le rayon du disque : ")
s=pi*r**2
print "L’aire du disque est", s

Enregistrer le programme (menu Fichier) dans le répertoire approprié et en lui donnant un


nom pertinent. Lancer le programme (F5) et sélectionner les choix suivants :
• Exécuter dans un nouvel interpréteur P YTHON dédié ;
• Intéragir avec l’interpréteur P YTHON après l’exécution.
BÀ retenir : ce sont les choix que l’on fera systématiquement.
(b) Que représentent les variables r et s ? Que font les commandes input et print ? Supprimer
la ligne from math import pi et lancer à nouveau le programme, que se passe-t-il ?

Exercice 3 Quelques calculs avec le module math : On utilisera en général ce module en écrivant :

from math import *

au début d’un programme ou dans une console. On a ainsi accès directement à toutes les fonctions
du module math, par exemple :
print pi, sin(pi),cos(pi)
print e, exp(1), log(e)

Utiliser les fonctions du module math pour traiter les calculs des questions suivantes.
(a) Datation au carbone 14. À la mort d’un être vivant, le carbone 14 présent dans son organisme
se désintègre au fil des années de sorte que, si p est la proportion de C 14 restante au bout de
N années, alors N = −8310 ln(p).
• Écrire une fonction datation_C14(p) qui calcule N en fonction de p.
• La momie Ötzi retrouvée dans un glacier en 1991 contenait 52.8% du C 14 initial à 1%
près. Donner un encadrement de son âge.
• L’Australopithecus afarensis Lucy, découverte en 1974 a un âge estimé à 4.4 millions d’an-
nées. Estimer la proportion de C 14 restante. A-t-on pu effectuer la datation du squelette
au C 14 ?
(b) Calculs de distances. Un bateau navigue en suivant un certain cap. À un instant donné, le ba-
teau est en position B 1 et le commandant repère un récif R sous un angle de 22◦ . Un mile plus
loin, en position B 2 , le commandant repère ce même récif R sous un angle de 34◦ . Calculer la
distance H R (distance entre le récif et la trajectoire).

22◦ 34◦
B1 B2 H Trajectoire
1 mile

On pourra commencer par calculer la distance :

tan(22◦ )
B2 H =
tan(34◦ ) − tan(22◦ )

BLes fonctions trigonométriques sin, cos, tan de P YTHON travaillent en radians et non en
degrés.

Exercice 4 Nombres complexes avec P YTHON et module cmath : On peut définir et calculer avec
des nombres complexes. Un nombre complexe z = a + ib se note a+bj ou complex(a,b) avec
P YTHON. Attention : le complexe i se note ici complex(0,1) ou 0+1j ou plus simplement 1j.
(a) Tester dans une console les commandes suivantes :

z1=2+1j
z2=complex(1,2)
z1+z2
z1*z2
z1/z2
z1**2
z1.real
z1.imag
z1.conjugate()

BIl y a bien des parenthèses après conjugate (et pas après real et imag).
(b) Chercher dans la documentation en ligne de P YTHON le module cmath et regarder les diffé-
rentes fonctions proposées. À quoi correspondent les fonctions abs, phase, polar et rect ?
(c) Écrire sous forme algébrique les nombres complexes :

1 − 2i 2+i (1 − 4i)(1 − i)
, ,
3+i 2−i (1 + i)2

Déterminer également le module et un argument de chacun de ces nombres.


(d) On considère les nombres a = 3, b = 6 et c = 8 + i. Vérifier numériquement, avec P YTHON, que
arg(c) + arg(c − a) + arg(c − b) = π/4.
TP 3 : Boucles for

Remarques.
• Ce TP consiste à programmer différentes suites ; on insiste sur ce concept car les algorithmes
numériques que l’on verra au deuxième semestre consistent en général à définir une suite et
à calculer ses termes ;
• Vouc pourrez utiliser un seul fichier pour écrire toutes les fonctions demandées dans les exer-
cices qui suivent car toutes les suites considérées portent un nom différent ;
• On vous demande explicitement dans chaque exercice de vérifier votre programme en calcu-
lant les premières valeurs de la suite, à l’avenir il faudrait penser à faire vous même ce type de
vérification. 

Exercice 1 Suite un+1 = f (u n ) : On considère la suite (u n ) définie par :

u0 = 1
u n (6 − u n2 )
∀n ∈ N, u n+1 =
4

(a) . Calculer u 1 (sans l’ordinateur).


(b) Écrire une fonction u(n) qui calcule u n en fonction de n.
(c) Vérifier que u(1) donne bien la valeur calculéepà la première question et vérifier que, pour n
assez grand, u(n) est une valeur approchée de 2.

Exercice 2 Suite v n+1 = f (n, v n ) : On considère la suite (v n ) définie par :

v0 = 0
(−1)n
∀n ∈ N, v n+1 = v n +
n +1

(a) . Calculer v 1 et v 2 (sans l’ordinateur).


(b) Écrire une fonction v(n) qui calcule v n en fonction de n.
(c) Vérifier que v(1) et v(2) donnent bien les valeurs calculées à la première question et vérifier
que, pour n assez grand, v(n) est une valeur approchée de ln(2).

Exercice 3 Somme des termes d’une suite : On considère la suite (w n ) définie par :

w0 = 1
wn
∀n ∈ N, w n+1 = −
(2n + 1)(2n + 2)

(a) . Calculer w 1 et w 0 + w 1 (sans l’ordinateur).


(b) Écrire une fonction w(n) qui calcule w n en fonction de n.
(c) Écrire une fonction s(n) qui calcule la somme w 0 + · · · + w n en fonction de n.
(d) Vérifier que s(1) donne bien la valeur w 0 +w 1 calculée à la première question et vérifier que,
pour n assez grand, s(n) est une valeur approchée de cos(1).

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp3.pdf
Exercice 4 Suite a n+2 = f (an , an−1 ) : On considère la suite (an ) définie par :

a0 = 0
a1 = 1
∀n ∈ N, a n+2 = a n+1 + a n

(a) . Calculer a 1 , a 2 , a 3 (sans l’ordinateur).


(b) Écrire une fonction a(n) qui calcule a n en fonction de n.
(c) Vérifier que a(1), a(2), a(3) donnent bien les valeurs calculées à la première question et
p
vérifier que, pour n assez grand, a n+1 /a n est une valeur approchée de (1 + 5)/2.

Représentations graphiques
p
¦ Pour représenter graphiquement une suite, par exemple la suite (u n ) définie par u n = n/en pour
0 É n É 10, on utilisera les commandes suivantes (dont la signification sera vue ultérieurement) :

import matplotlib.pyplot as plt 0.40

0.35

from math import *


0.30

def u(n): 0.25

return n**0.5/exp(n) 0.20

plt.plot([u(n) for n in range(11)],’.’) 0.15

0.10

0.05

plt.show() 0.00
0 2 4 6 8 10

Exercice 5 :
(a) Représenter graphiquement les premiers termes de la suite (u n ) de l’exercice 1.
(b) Quelle(s) propriété(s) sur la suite (u n ) peut-on conjecturer ?
(c) . Le démontrer.
TP 3 : Boucles for

Éléments de correction
Ex. 1 :

def u(n):
u=1
for k in range(n):
u=u*(6-u**2)/4.0
return u
print u(1)
print u(100)

1.25 1.41421356237

Ex. 2 :

from math import *


def v(n):
v=0
for k in range(n):
v=v+float((-1)**k)/(k+1)
return v
print v(1), v(2), v(1000), log(2)

1.0 0.5 0.69264743056 0.69314718056

Ex. 3 :

from math import *


def w(n):
w=1
for k in range(n):
w=-float(w)/(2*k+1)/(2*k+2)
return w
def s(n):
s=0
for k in range(0,n+1):
s=s+w(k)
return s
print s(100), cos(1)

0.540302305868 0.540302305868
Cette manière de faire, pour la fonction s, n’est pas très efficace. En effet, pour calculer s(100) par
exemple, il faut successivement calculer w(0), w(1), etc. jusqu’à w(100). Or, le calcul de w(k)
demande k étapes de calcul et le calcul de s(100) demande alors 1 + 2 + · · · + 100 étapes de calcul.
Plus généralement, le calcul de s(n) demande :

n(n + 1)
1+2+···+n =
2

étapes de calcul. On peut réécrire la fonction s en reprenant à l’intérieur le calcul des w k :


def s(n):
w=1
s=1
for k in range(n):
w=-float(w)/(2*k+1)/(2*k+2)
s=s+w
return s
print s(100), cos(1)

0.540302305868 0.540302305868
Maintenant, le calcul de s(n) demande n étapes de calcul (ce qui est plus efficace que n(n + 1)/2).

Ex. 4 :

def a(n):
a=0
b=1
for k in range(n):
c=a+b
a=b
b=c
return a
print a(0),a(1),a(2),a(3)
print float(a(100))/a(99), (1+5**0.5)/2

0 1 1 2 1.61803398875 1.61803398875
Autre possibilité plus dans l’esprit de P YTHON :

def a(n):
a=0
b=1
for k in range(n):
(a,b)=(b,a+b)
return a
print a(0),a(1),a(2),a(3)
print float(a(100))/a(99), (1+5**0.5)/2

0 1 1 2 1.61803398875 1.61803398875

Ex. 5 :

import matplotlib.pyplot as plt 1.45

1.40

plt.plot([u(n) for n in range(11)],’.’) 1.35

1.30

1.25

plt.show() 1.20

1.15

1.10

1.05

1.00
0 2 4 6 8 10
La suite (u n ) semble croissante. Pour le vérifier, on calcule pour n ∈ N :

u n (6 − u n2 ) u n (6 − u n2 ) − 4u n 2u n − u n2 u n (2 − u n2 )
u n+1 − u n = − un = = =
4 4 4 4

Il faut alors connaitre le signe de u n (2 −pu n2 ). Toujours d’après la représentation graphique, il semble
que u n soit toujours compris pentre 0 et 2. Démontrons-le par récurrence en posant l’hypothèse de
récurrence H (n) : 0 É u n É 2. p
• H (0) est vraie car u 0 = 1 et 0 É 1 É 2 ;
• Soit n ∈ N et supposons H (n) vraie. Par définition de u n+1 , on peut écrire :

u n (6 − u n2 ) x(6 − x 2 )
u n+1 = = f (u n ) en définissant la fonction f : x 7→
4 4
On étudie rapidement la fonction f , elle est dérivable sur R et :

3
∀x ∈ R, f 0 (x) = (2 − x 2 )
4
On obtient alors le tableau de variations de f :
p p
x −∞ − 2 0 2 +∞
0
f (x) (−) 0 (+) 0 (−)
p p
f (x) +∞ & − 2 % 0 % 2 & −∞
p p
Par hypothèse de récurrence, 0 É upn É 2 et la fonction f est croissante p sur l’intervalle
p [0, 2].
Par conséquentpf (0) É f (u n ) É f ( 2), or f (0) = 0, f (u n ) = u n+1 et f ( 2) = 2. On en déduit
que 0 É u n+1 É 2, donc H (n + 1) est vraie ; p
• Par récurrence, H (n) est vraie quel que soit n ∈ N, c’est à dire : ∀n ∈ N, 0 É u n É 2.
Pour n ∈ N, on a alorspu n Ê 0 et 2 − u n2 Ê 0, donc u n+1 − u n Ê 0 et la suite (u n ) est croissante. Elle est
de plus majorée (par 2), donc elle converge. On note ` sa limite, on sait que :

u n (6 − u n2 )
∀n ∈ N, u n+1 =
4
et en faisant tendre n vers +∞, on obtient :

`(6 − `2 )
`=
4
p
En simplifiant,
p on obtient 2` − `3 = 0 c’est à dire `(2 − `2 ) = 0. Par conséquent, ` = 0 ou ` = 2 ou
` = − 2. Notons que comme la suite p(u n ) est croissante et u 0 = 1, on a nécessairement ` Ê 1, la seule
valeur possible pour ` est donc ` = 2.
TP 4 : Instructions conditionnelles
B Penser à :
• Démarrer chaque exercice en ouvrant un nouveau fichier dans l’éditeur (menu Fichier / Nou-
veau Fichier) ;
• Sauvegarder immédiatement ce nouveau fichier (menu Fichier / Enregistrer sous) en lui don-
nant un nom approprié. Pour vous aider, des noms sont suggérés pour chaque exercice.

Applications directes
Exercice 1 Une suite chaotique / suite_chaotique.py : On considère la suite (u n ) définie par :
u 0 = 0.1; ∀n ∈ N, u n+1 = 3u n si 3u n < 1
3u n − 1 si 1 É 3u n < 2
3u n − 2 sinon

(a) Écrire une fonction u(n) qui calcule les termes de cette suite. Vérifier que u(10) est proche
de 0.9. Noter la valeur de u(1000).
(b) On prend maintenant u 0 = 0.1 + 10−10 . Calculer à nouveau u(1000).
On dit que le système décrit par la suite (u n ) est chaotique : de petites variations sur la condition
initiale peuvent conduire à des variations importantes à long terme.
Exercice 2 Une fonction / fonction_triangle.py : On considère la fonction f dont la repré-
sentation graphique est la suivante :

(a) Définir cette fonction f(x). Vérifier en calculant


1
quelques valeurs particulières de f .
(b) Représenter graphiquement la fonction f sur l’inter-
valle [−2, 3] ; on donne pour cela les commandes :
−1 O 2

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,3,100)
plt.plot(x,[f(xi) for xi in x])
plt.show()

Mise en œuvre
Exercice 3 Méthode Rde Monte Carlo / monte_carlo.py : On veut déterminer une valeur appro-
b
chée d’une intégrale a f (t ) dt où f est une fonction continue et positive sur l’intervalle [a, b]. On
suppose de plus que l’on connait un réel m tel que : ∀x ∈ [a, b], f (x) É m.
La méthode de Monte Carlo consiste à tirer aléatoirement des valeurs
x ∈ [a, b] et y ∈ [0, m] ; si on effectue ainsi N tirage aléatoires et si m
P designe le nombre de ces tirages pour lesquels y É f (x), alors on
Rb
obtient une valeur approchée de a f (x) dx avec :
Z b P
f (x) dx ' (b − a)m
a N

(ci-contre un exemple de fonction f et des tirages aléatoires, les


a b
points vérifient la condition y É f (x) et les croix ne la vérifient pas).

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp4.pdf
(a) Écrire une fonction monte_carlo(f,a,b,m,N) qui calcule l’approximation de l’intégrale
de f sur [a, b] en appliquant cette méthode. Quelques indications :
• Dans cette fonction, on devra répéter N fois l’opération qui consiste à faire un tirage
aléatoire de x et y ;
• Une fois ce tirage effectué, on testera si la condition y É f (x) est satisfaite ou pas et on
augmentera la valeur de P en conséquence ;
• À la fin de la fonction, on renverra la valeur appropriée ;
• Pour tirer aléatoirement un nombre dans l’intervalle [a, b], on écrira au début du pro-
gramme :

from random import uniform

puis pour faire un tirage de x entre a et b on utilisera :

x=uniform(a,b)

(b) On va tester la fonction précédente sur quelques exemples.


• Considérons tout d’abord la fonction f : x 7→ x sur l’intervalle [0, 1]. Que doit-on trouver
Rb
pour a f (t ) dt ? Vérifier en tapant (dans une console, après avoir lancé le programme) :

monte_carlo(lambda x:x,0,1,2,1000)

Remarques : on a choisi de prendre m = 2, par ailleurs l’expression lambda x:x est


une manière rapide de désigner en P YTHON la fonction x 7→ x.
• Que doit-on obtenir avec :

monte_carlo(lambda x:x**2,0,1,2,1000)

Vérifier que le résultat attendu est correct.


• Proposer un troisième exemple pour vérifier.
(c) Une application. L’orbite d’écrite par une planète autour du soleil est (en première approxi-
mation) une ellipse.
On peut démontrer que la longueur de cette
trajectoire est :
r2
Z 2π q
r1 `= r 12 sin2 t + r 22 cos2 t dt
0

Utiliser la fonction précédente pour déterminer la longueur de l’orbite de Mercure avec les
données numériques : r 1 = 57,9 · 106 km et r 2 = 56,7 · 106 km. Faire de même avec Pluton :
r 1 = 5900,0 · 106 km et r 2 = 5715,7 · 106 km. Pour vérifier les résultats obtenus, on pourra com-
parer avec le périmètre des cercles de rayons respectifs r 1 et r 2 .
TP 4 : Instructions conditionnelles

Éléments de correction

Ex. 1 : Pour simplifier on définit une fonction u(u0,n) :

def u(u0,n):
u=u0
for k in range(n):
if 3*u<1:
u=3*u
elif 1<=3*u<2:
u=3*u-1
else:
u=3*u-2
return u
print u(0.1,10)

0.9

print u(0.1,1000), u(0.1+10**(-10),1000)

0.289955755927 0.820641585216

Ex. 2 : Sur l’intervalle [−1, 0], la fonction f est égale à la fonction affine x 7→ x + 1 et sur l’intervalle
[0, 2], f est égale à la fonction affine x 7→ 1 − x/2.

def f(x):
if -1<=x<=0:
return x+1
elif 0<x<=2:
return 1-float(x)/2
else:
return 0
print f(-2), f(-0.5), f(0), f(0.5), f(1), f(2)

0 0.5 1 0.75 0.5 0.0


Représentation graphique :

import numpy as np 1.0

import matplotlib.pyplot as plt 0.8

x=np.linspace(-2,3,100)
0.6

plt.plot(x,[f(xi) for xi in x])


0.4

0.2

plt.show()
0.0
−2 −1 0 1 2 3

Ex. 3 :
from random import uniform
def monte_carlo(f,a,b,m,N):
P=0
for k in range(N):
x=uniform(a,b)
y=uniform(0,m)
if y<=f(x):
P=P+1
return m*(b-a)*float(P)/N
R1
Pour 0 x dx, on doit trouver une valeur proche de 1/2. Vérification :

print monte_carlo(lambda x:x,0,1,2,1000)

0.46
R1
Pour 0 x 2 dx, on doit trouver une valeur proche de 1/3 :

print monte_carlo(lambda x:x**2,0,1,2,1000)

0.368 Rπ
Un troisième exemple avec le calcul de 0 sin x dx qui doit donner une valeur proche de 2 :

from math import *


print monte_carlo(lambda t:sin(t),0,pi,2,1000)

1.89123877746
Calcul de la longueur de l’orbite de Mercure :

r1=5900
r2=5715.7
(on prend comme unité de longueur le million de kilomètres). On considère la fonction f : t 7→
q
r 12 sin2 t + r 22 cos2 t , on remarque que :
q
∀t ∈ R, 0 É f (t ) É r 12 + r 22
q
La fonction f est bien positive et on peut prendre m = r 12 + r 22 . On calcule la longueur de l’orbite :

f=lambda t:sqrt(r1**2*sin(t)**2+r2**2*cos(t)**2)
m=sqrt(r1**2+r2**2)
print monte_carlo(f,0,2*pi,m,10000)

36330.8769882
On vérifie en comparant avec les périmètres des cercles de rayons r 1 et r 2 :

print 2*pi*r1, 2*pi*r2

37070.7933124 35912.8022602
La longueur de l’orbite obtenue numériquement est bien comprise entre ces deux périmètres. On
procède de même pour Pluton.
TP 5 : Boucles while

B Penser à :
• Démarrer chaque exercice en ouvrant un nouveau fichier dans l’éditeur ;
• Sauvegarder immédiatement ce nouveau fichier en lui donnant le nom proposé dans l’énoncé.

Applications directes
Exercice 1 Algorithme de Babylone / babylone.py : On considère la suite (u n ) définie par :

u0 = 2
1 2
µ ¶
∀n ∈ N, u n+1 = un +
2 un
p
On admet que la suite (u n ) est décroissante et converge vers 2.
(a) On pose np= 10. Calculer u n en utilisant une boucle for. Vérifier que le résultat obtenu est
proche de 2.
(b) On pose ε = 10−2 . En utilisant une boucle while, calculer le premier terme de la suite pour
lequel (u n − ε)2 É 2.
(c) Réécrire les deux programmes des questions précédentes pour les présenter sous forme de
deux fonctions :
— Une fonction u(n) qui calcule u n à partir de n ;
— Une fonction approx(epsilon) qui calcule le premier terme de la suite (u n ) pour
lequel (u-epsilon)**2<=2.

Mise en œuvre
Exercice 2 Mise en place complète d’un algorithme numérique / eqkepler.py : On s’intéresse à
l’équation de Képler qui intervient dans des calculs astronomiques :

x − e sin x = m (E )

L’inconnue est x et e et m sont deux paramètres réels avec 0 < e < 1. On considère la fonction

f : R → R
x 7→ x − e sin x − m

(a) . Étudier les variations de f .


(b) . Justifier que l’équation (E ) possède une unique solution, on la notera α.
(c) . Définir une fonction g telle que l’équation (E ) puisse s’écrire sous la forme g (x) = x.
L’idée pour déterminer une valeur approchée de α consiste à poser x 0 = m et définir à partir de cette
valeur une suite (x n ) en posant :

∀n ∈ N, x n+1 = g (x n )

(d) Écrire une fonction approx(e,m,n) qui calcule x n pour les valeurs de e, m et n données.
Vérifier que approx(0.5,1,10) est proche de 1.5.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp5.pdf
(e) . Vérifier que, pour n ∈ N :
Z xn
g 0 (x) dx = x n+1 − α
α

et en déduire que |x n+1 − α| É e|x n − α|.


(f) . Démontrer que : ∀n ∈ N, |x n − α| É e n |x 0 − α|.
(g) . En déduire que la suite (x n ) converge et déterminer sa limite.
(h) . Soit ε > 0. Démontrer que si f (x n − ε) É 0 et f (x n + ε) Ê 0, alors |x n − α| É ε.
(i) Définir une fonction eqkepler(e,m,epsilon) qui détermine une valeur approché de
l’équation (E ) à ε près en utilisant la suite (x n ).
(j) Nous allons maintenant tester ce programme : choisir pour cela des valeurs de e et m ainsi
qu’une valeur de ε « assez petite » et appeler a=eqkepler(e,m,epsilon). Vérifier alors
que la valeur de a obtenue est bien approximativement une solution de x − e sin(x) = m.

Notes
¦ L’équation de Képler apparait lorsque l’on cherche à déterminer la position P (t ) d’une planète ou
d’un corps en orbite du soleil en fonction du temps. Un tel corps suit une trajectoire elliptique dont
le soleil occupe l’un des foyers (noté S sur le dessin ci-dessous).
Au temps t 0 , le corps occupe la position de l’orbite où il est le plus
proche du soleil (noté P (t 0 ) sur le dessin, ce point est appelé périhélie
P (t ) de l’orbite). Si on note r (t ) la distance entre S et P (t ), on a la relation :
r (t ) d × (1 + e)
r (t ) = cos(E )−e
S P (t 0 ) 1 + e × 1−e cos(E )

où d est la distance SP (t 0 ) et E est la solution de l’équation :

2π(t − t 0 )
x − e sin(x) = (T est la période de révoution du corps céleste)
T
On voit ainsi apparaitre l’équation de Képler.

¦ Pour obtenir une valeur approché de la solution de l’équation x − e sin(x) = m, on a écrit cette
équation sous la forme x = g (x) en posant g (x) = e sin(x)+m. On a ensuite défini une suite (x n ) telle
que x n+1 = g (x n ). L’idée générale qui explique cette construction est que si on arrive à démontrer
que la suite (x n ) converge vers une limite `, alors on aura :

g (x n ) = e sin(x n ) + m −−−−−→ e sin(`) + m


n→+∞
et g (x n ) = x n+1 −−−−−→ `
n→+∞

Par unicité de la limite, on a alors e sin(`)+m = ` et ainsi ` est solution de l’équation x −e sin(x) = m.
TP 5 : Boucles while

Éléments de correction
Ex. 1 : (a) On définit n = 100 puis on calcule u 100 avec une boucle for :

n=10
u=2
for k in range(n):
u=0.5*(u+2.0/u)
print u

1.41421356237
(b) On définit ε = 10−4 puis on calcule le terme u n recherché à l’aide d’une boucle while :

epsilon=1e-2
u=2
while (u-epsilon)**2>2:
u=0.5*(u+2.0/u)
print u

1.41666666667
(c) Il y a très peu de modifications à effectuer pour présenter les programmes précédents sous
formes de fonctions :

def u(n):
u=2
for k in range(n):
u=0.5*(u+2.0/u)
return u
def approx(epsilon):
u=2
while (u-epsilon)**2>2:
u=0.5*(u+2.0/u)
return u
Pour calculer u 10 :

print u(10)

1.41421356237
p
Pour obtenir une valeur approchée de 2 à 10−2 près :

print approx(1e-2)

1.41666666667

Ex. 2 : (a) • La fonction f est définie et dérivable sur R ;


• ∀x ∈ R, f 0 (x) = 1 − e cos x > 0 (car 0 < e < 1) ;
• La fonction f est continue et strictement croissante sur R ;
• ∀x ∈ R, x − m − e É f (x) É x − m + e donc f (x) −−−−−→ +∞ et f (x) −−−−−→ −∞ ;
x→+∞ x→−∞
• Théorème de la bijection : la fonction f réalise une bijection de R sur R, donc l’équation
(E ) admet une unique solution.
(b) On définit g : x 7→ m + e sin x, l’équation (E ) est équivalente à g (x) = x.
(c)
from math import *
def approx(e,m,n):
x=m
for k in range(n):
x=e*sin(x)+m
return x
print approx(0.5,1,10)

1.49870113352
(d) Pour n ∈ N :
Z xn ¤x
g 0 (x) dx = g (x) αn = g (x n ) − g (α) = x n+1 − α
£
α
0
Par ailleurs, on a |g (x)| É e pour tout x, donc :
¯Z x ¯
¯ n 0
|x n+1 − α| = ¯
¯
¯ g (x) dx ¯¯ É e |x n − e|
e
(e) Par récurrence avec la question précédente : ∀n ∈ N, |x n − α| É e n |x 0 − α|.
(f) Comme 0 < e < 1, on a e n −−−−−→ 0 et par encadrement x n −−−−−→ α.
n→+∞ n→+∞
(g) Supposons f (x n − ε) É 0 et f (x n + ε) Ê 0. La fonction f est continue, donc d’après le théo-
rème des valeurs intermédiaires, f s’annule sur l’intervalle [x n − ε, x n + ε]. Par conséquent
α ∈ [x n − ε, x n + ε] et ainsi |x n − α| É ε. Notons également que comme x n −−−−−→ α, il existe
n→+∞
nécessairement un entier n tel que x n − ε É α et x n + ε Ê α. Conséquence : on peut utiliser la
condition f (x n − ε) É 0 et f (x n + ε) Ê 0 comme condition d’arrêt. À REFORMULER.
(h)

from math import *


def eqkepler(e,m,epsilon):
f=lambda x:x-e*sin(x)-m
x=m
while not(f(x-epsilon)<=0 and f(x+epsilon)>=0):
x=m+e*sin(x)
return x
(i) Pour m = 2 et e = 0.5 :

m=2
e=0.5
a=eqkepler(e,m,1e-4)
print a
print a-e*sin(a)-m

2.35417205822 -9.56465070927e-05
On trouve bien une valeur proche de 0. Pour m = 10 et e = 0.9 :

m=10
e=0.9
a=eqkepler(e,m,1e-4)
print a
print a-e*sin(a)-m

9.72984542447 0.000167196589832
TP 6 : Sommes et produits
B• Penser à ouvrir un nouveau fichier pour chaque exercice et à l’enregister immédiatement en
lui donnent le nom proposé dans l’énoncé.
• On documentera chaque fonction écrite en expliquant en une ligne ce qu’elle calcule (comme
on l’a vu en cours).
Exercice 1 Somme des carrés / somme_carres.py : Le programme suivant calcule et affiche la
valeur de la somme

s=0
10
2 for k in range(1,11):
X
k
k=1 s=s+k**2
print s

(a) Écrire et tester ce programme. Pourquoi range(1,11) et pas range(1,10) ou range(10) ?


Pourquoi pas range(11) ?
(b) Modifier ce programme afin d’écrire une fonction somme_carres(n) qui calcule la somme
Pn
k=1
k 2 . Tester cette fonction avec quelques valeurs simples de n.
(c) Écrire une nouvelle fonction produit_carres(n) qui calcule le produit nk=1 k 2 . Tester
Q

cette fonction avec quelques valeurs simples de n.

Exercice 2 Paradoxe des anniversaires / anniversaires.py : La probabilité p n qu’au moins deux


étudiants d’une classe de n étudiants aient leur anniversaire le même jour de l’année est donnée par
la formule :
n−1
Y
µ
k

pn = 1 − 1−
k=1 365

(a) Écrire une fonction probabilite(n) qui calcule p n .


(b) Calculer p 35 .

Exercice 3 Sommes doubles / sommes_doubles.py : Le programme suivant calcule et affiche la


valeur de la somme

X s=0
ij for i in range(1,11):
1Éi , j É10
for j in range(1,11):
s=s+i*j
print s

X X i
Pour n ∈ N∗ , on définit les sommes S n = min(i , j ) et Tn = .
1Éi , j Én 1Éi É j Én j +1
(a) Écrire deux fonctions S(n) et T(n) qui calculent respectivement S n et Tn (on pourra utiliser
la fonction min qui existe dans P YTHON).
(b) Tester ces fonctions en vérifiant, pour quelques valeurs de n, les égalités :

n(n + 1)(2n + 1) n(n + 1)


Sn = ; Tn =
6 4

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp6.pdf
Exercice 4 Approximation de fonctions / approx_exp.py : Pour x ∈ R et N ∈ N, on pose :

XN xn
A exp (N , x) =
n=0 n!

(a) Écrire une fonction Aexp(N,x) qui calcule A exp (N , x). Vérifier que Aexp(10,1) est une
valeur approchée de exp(1).
(b) Représenter les fonctions x 7→ ex et x 7→ A exp (3, x) sur l’intervalle [−2, 2] sur le même dessin.
On donne pour cela les commandes :

from math import *


import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,2,100)
plt.plot(x,[exp(xi) for xi in x])
plt.plot(x,[Aexp(3,xi) for xi in x])
plt.show()

(c) Représenter les fonctions x 7→ ex et x 7→ A exp (10, x) sur l’intervalle [−2, 2] sur le même dessin.
Nom :

Manipuler l’environnement de développement

Nommer correctement le programme 1


Exécuter le programme 1
Tester le programme dans la console 1

Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1

Algorithmique et programmation

Utiliser une boucle for, une boucle while, une condition 3


Utiliser le bon range, la bonne condition 3
La structure générale du programme est correcte 3
Comprendre un programme existant, le modifier 3
Tester le programme (interpréter les réponses, les messages d’erreur éventuels) 3
Le programme fonctionne correctement (ou : savoir le corriger) 3

Nom :

Manipuler l’environnement de développement

Nommer correctement le programme 1


Exécuter le programme 1
Tester le programme dans la console 1

Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1

Algorithmique et programmation

Utiliser une boucle for, une boucle while, une condition 3


Utiliser le bon range, la bonne condition 3
La structure générale du programme est correcte 3
Comprendre un programme existant, le modifier 3
Tester le programme (interpréter les réponses, les messages d’erreur éventuels) 3
Le programme fonctionne correctement (ou : savoir le corriger) 3
TP 6 : Sommes et produits

Éléments de correction
Ex. 1 :

def somme_carres(n):
"""Calcule 1^2+2^2+...+n^2"""
s=0
for k in range(1,n+1):
s=s+k**2
return s
print somme_carres(3)

14

def produit_carres(n):
"""Calcule 1^2*2^2*...*n^2"""
s=1
for k in range(1,n+1):
s=s*k**2
return s
print produit_carres(3)

36

Ex. 2 :

def probabilite(n):
"""Calcule la probabilité que parmi n personnes,
deux aient leur anniversaire le même jour"""
p=1
for k in range(1,n): # Dans le produit, k va de 1 jusqu’à n-1
p=p*(1-float(k)/365)
# p contient le produit (1-1/365)*...*(1-(n-1)/365)
return 1-p
print probabilite(35)

0.814383238875

Ex. 3 :

def S(n):
"""Calcule la somme des min(i,j) pour 1<=i,j<=n"""
s=0
for i in range(1,n+1):
for j in range(1,n+1):
s=s+min(i,j)
return s
print S(10), 10*(10+1)*(2*10+1)/6

385 385
def T(n):
"""Calcule la somme des i/(j+1) pour 1<=i<=j<=n"""
s=0
for i in range(1,n+1):
for j in range(i,n+1):
s=s+float(i)/(j+1)
return s
print T(10), float(10*(10+1))/4

27.5 27.5

Deuxième méthode pour T(n) :

def T(n):
"""Calcule la somme des i/(j+1) pour 1<=i<=j<=n"""
s=0
for i in range(1,n+1):
for j in range(1,n+1):
if i<=j:
s=s+float(i)/(j+1)
return s
print T(10), float(10*(10+1))/4

27.5 27.5

Ex. 4 :

from math import *


def Aexp(N,x):
"""Calcule x^0/0!+x^1/1!+...+x^N/N!"""
s=0
for n in range(N+1):
s=s+float(x**n)/factorial(n)
return s
print Aexp(10,1)

2.71828180115

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,2,100)
plt.plot(x,[exp(xi) for xi in x])
plt.plot(x,[Aexp(3,xi) for xi in x])
8

−1
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0

x=np.linspace(-2,2,100)
plt.plot(x,[exp(xi) for xi in x])
plt.plot(x,[Aexp(10,xi) for xi in x])

0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
TP 7 : Listes
B• Penser à ouvrir un nouveau fichier pour chaque exercice et à l’enregister immédiatement en
lui donnant un nom approprié.
• On documentera chaque fonction écrite en expliquant en une ligne ce qu’elle calcule.
• Penser à tester les fonctions sur des exemples simples.

Applications directes

Exercice 1 Calculs sur des listes : On pensera à tester les fonctions suivantes sur des exemples
simples.
(a) Écrire une fonction somme(L) qui calcule la somme des éléments de la liste L (si cette liste
est vide, le résultat renvoyé devra être 0).
(b) Écrire une fonction moyenne(L) qui calcule la moyenne des éléments de la liste L (cette liste
ne devra pas être vide).
(c) Écrire une fonction variance(L) qui calcule la variance de la liste L définie par :

1 n−1
(L[k] − m)2
X
variance(L) =
n k=0

où n est la longueur de la liste L.

Exercice 2 Sélection des éléments d’une liste : Écrire une fonction selectionner(L,a,b) qui
construit une nouvelle liste obtenue en ne gardant que les éléments de L qui sont compris (au sens
large) entre a et b (on supposera a É b).

Exercice 3 Liste des termes d’une suite : On considère la suite (u n ) définie par :

u0 = 1
p
∀n ∈ N, u n+1 = 1 + u n

(a) Écrire une fonction liste_termes(n) qui construit la liste contenant u 0 , u 1 , . . . , u n .


(b) Modifier la fonction précédente pour l’écrire sous la forme liste_termes(u0,n) afin de
pouvoir changer la valeur de u 0 .

Mise en œuvre

Exercice 4 Indice du maximum et loi du déplacement de Wien :


(a) On considère une liste X de taille n. Écrire une fonction indice_max(X) qui retourne un
entier k tel que X [k] soit le maximum de X [0], . . . , X [n − 1].
(b) Une application. On donne ci-dessous le spectre d’émission du soleil 1

1. Il ne s’agit pas des données brutes, on a éliminé quelques irrégularités.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp7.pdf
Spectre d'émission du soleil
2.0

1.5

1.0

φ (W ·m−2 ·nm−1 )

0.5

0.0

−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
λ (nm)

Les données numériques correspondant à ces points se trouvent dans deux listes, une liste
Lambda pour les abscisses et une liste Phi pour les ordonnées. On pourra obtenir ces deux
listes par copier coller depuis l’adresse :

http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/donneesTP7ex4.html

Déterminer l’indice k tel que Phi[k] soit maximal puis déterminer Lambda_max=Lambda[k].
On peut alors obtenir une valeur approchée de la température T de la surface du soleil en uti-
lisant la loi du déplacement de Wien :

2.898 · 106
T=
λmax

(λmax est en nanomètres et T en kelvin).


¦ Le spectre (hors atmosphère), brut de décoffrage :

2.5

2.0

1.5

1.0

0.5

0.0
0 500 1000 1500 2000 2500 3000 3500 4000

¦ On régularise le spectre en réalisant une approximation polynomiale (commande polyfit, avec


Python comme avec Matlab) :

2.5

2.0

1.5

1.0

0.5

0.0

−0.5
0 500 1000 1500 2000 2500 3000 3500 4000

Les abscisses des « points rouges » sont eregistrées dans une liste Lambda et les ordonnées corres-
pondantes dans une liste Phi. On cherche Lambda[k] tel que Phi[k] soit maximal.
¦ On considère une liste :

X = [x 0 , x 1 , . . . , x n−1 ]

On réalise une fonction indice_max(X) qui calcule la valeur k telle que x k soit le maximum de
x 0 , . . . , x n−1 .

def indice_max(X):
"""
Calcule k tel que X[k] soit maximal
X : liste non vide
"""
k=0
for i in range(1,len(X)):
if X[i]>X[k]:
k=i
return k

¦ On peut alors déterminer la température T de la face externe du soleil par application de la loi de
Wien : on note λmax la valeur Lambda[k] avec k=indice_max(Phi) et on calcule

2.898 · 106
T=
λmax

(λmax est exprimée en nm et T en K).

lambda_max=Lambda[indice_max(Phi)]
print "Température :", 2.898e6/lambda_max, "K"

Température : 5733.45323741 K

¦ Pour finir on superpose les mesures ainsi que l’approximation effectuée à la représentation gra-
phique de la luminance du corps noir à 5733 K (en appliquant un facteur d’échelle) :

from math import *


def corps_noir(T,lo):
"""
Luminance du corps noir à la température T
pour la longueur d’onde lo (nm)
avec un facteur d’échelle r=1.91/2.56e13
"""
lo=lo*1e-9 # On remet en mètres
h=6.62e-34
c=2.99e8
k=1.38e-23
r=1.91/2.56e13
return r*2*h*c**2/lo**5/(exp(h*c/(k*lo*T))-1)
plt.plot(X,Y)
plt.plot(Lambda,[corps_noir(5733,l) for l in Lambda],linewidth=2)
plt.plot(Lambda,Phi,linewidth=2)
plt.legend(["Mesures","Corps noir","Approximation"])
2.5
Mesures
Corps noir
Approximation
2.0

1.5

1.0

0.5

0.0

−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
TP 7 : Listes

Éléments de correction
Ex. 1 :

def somme(L):
s=0
for x in L:
s=s+x
return s
def moyenne(L):
return float(somme(L))/len(L)
def variance(L):
m=moyenne(L)
s=0
for x in L:
s=s+(x-m)**2
return float(s)/len(L)
T=[1,2]
print somme(T), moyenne(T), variance(T)

3 1.5 0.25

Ex. 2 :

def selection(L,a,b):
"""
Je suppose a<=b
"""
M=[]
for x in L:
if a<=x<=b:
M.append(x)
return M

Ex. 3 : Directement sous la forme liste_termes(u0,n) :

def liste_termes(u0,n):
u=u0
L=[u]
for i in range(n):
u=(1+u)**0.5
L.append(u)
return L
print liste_termes(1,10)

[1, 1.4142135623730951, 1.5537739740300374, 1.5980531824786175, 1.6118477541252516,


1.616121206508117, 1.6174427985273905, 1.617851290609675, 1.6179775309347393,
1.6180165422314876, 1.6180285974702324]
Autre possibilité :
def liste_termes(u0,n):
L=[u0]
for i in range(n):
L.append((1+L[-1])**0.5)
# Rappel : L[-1] est le dernier terme de la liste L
return L
print liste_termes(1,10)

[1, 1.4142135623730951, 1.5537739740300374, 1.5980531824786175, 1.6118477541252516,


1.616121206508117, 1.6174427985273905, 1.617851290609675, 1.6179775309347393,
1.6180165422314876, 1.6180285974702324]

Ex. 4 :

Lambda=[...]
Phi=[...]

def indice_max(X):
"""
Calcule k tel que X[k] soit maximal
X : liste non vide
"""
k=0
for i in range(1,len(X)):
if X[i]>X[k]:
k=i
return k
lambda_max=Lambda[indice_max(Phi)]
print "Temp. :", 2.898e6/lambda_max, "K"

Temp. : 5733.45323741 K
TP 8 : Listes (2) et preuves de programmes
Exercice 1 :
(a) Écrire une fonction nocc(x,L) qui calcule le nombre de fois où x apparait dans la liste L.
On utilisera une boucle while et on donnera un invariant de boucle permettant de démontrer
que cette fonction est correcte.
(b) Écrire une fonction majoritaire(L) qui détermine un élément x qui soit majoritaire dans
L (autrement dit qui apparait plus souvent dans L que tout autre élément de L). On utilisera
une boucle while et on donnera un invariant de boucle permettant de démontrer que cette fonc-
tion est correcte.

Exercice 2 Indice du maximum et loi du déplacement de Wien :


(a) On considère une liste X de taille n. Écrire une fonction indice_max(X) qui retourne un
entier k tel que X [k] soit le maximum de X [0], . . . , X [n − 1].
(b) Une application. On donne ci-dessous le spectre d’émission du soleil 1

Spectre d'émission du soleil


2.0

1.5

1.0
φ (W ·m−2 ·nm−1 )

0.5

0.0

−0.5
0 500 1000 1500 2000 2500 3000 3500 4000
λ (nm)

Les données numériques correspondant à ces points se trouvent dans deux listes, une liste
Lambda pour les abscisses et une liste Phi pour les ordonnées. On pourra obtenir ces deux
listes par copier coller depuis l’adresse :

http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/donneesTP8ex2.html

Déterminer l’indice k tel que Phi[k] soit maximal puis déterminer Lambda_max=Lambda[k].
On peut alors obtenir une valeur approchée de la température T de la surface du soleil en uti-
lisant la loi du déplacement de Wien :

2.898 · 106
T=
λmax

(λmax est en nanomètres et T en kelvin).


(c) Réécrire la fonction indice_max de manière à utiliser une boucle while. Donner alors un
invariant de boucle permettant de montrer que cette fonction est correcte.

1. Il ne s’agit pas des données brutes, on a éliminé quelques irrégularités.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp8.pdf
TP 8 : Listes (2) et preuves de programmes

Éléments de correction
Ex. 1 :

def nocc(x,L):
"""
Calcule le nombre d’apparitions de x dans L
"""
n=0
i=0
while i<len(L): # len(L)-i est >=0 et strict. déc.
if L[i]==x:
n=n+1
i=i+1
# Invariant de boucle : n=nocc(x,L[0..i])
return n
def majoritaire(L):
"""
Détermine _un_ élément majoritaire de L
"""
xmaj=L[0]
nmaj=nocc(xmaj,L)
i=1
while i<len(L): # len(L)-i est >=0 et strict. déc.
if nocc(L[i],L)>nmaj:
xmaj=L[i]
nmaj=nocc(xmaj,L)
i=i+1
# Invariant de boucle : xmaj est l’élément de L[0:i]
# qui apparait le plus souvent dans L
return xmaj

Ex. 2 :

Lambda=[...]
Phi=[...]

def indice_max(X):
"""
Calcule k tel que X[k] soit maximal
X : liste non vide
"""
k=0
for i in range(1,len(X)):
if X[i]>X[k]:
k=i
return k
lambda_max=Lambda[indice_max(Phi)]
print "Temp. :", 2.898e6/lambda_max, "K"
Temp. : 5733.45323741 K
TP 9 : Simulation d’un système en physique, chimie, SII

B • Vous utiliserez un fichier différent pour chacun des deux exercices.


• Dans ce TP, nous n’aurons pas besoin d’écrire de fonctions (voir au besoin le résumé de cours).

Exercice 1 SII / Moteur à courant continu : On alimente un moteur initialement à l’arrêt par une
tension constante U = 10 V. La vitesse de rotation w du moteur est solution de l’équation différen-
tielle :

dw Ke Kc Kc
µ ¶
J + + f w(t ) = U
dt R R
avec w(0) = 0

où :
• J est l’inertie du moteur, J = 5.5 · 10−5 kg · m2 ;
• R est la résistance électrique du système, R = 5.2 Ω ;
• K c et K e sont des constantes, K c = 0.24 N · m · A−1 et K e = 0.24 V · rad−1 · s ;
• f est un coefficient caractérisant les forces de frottement, f = 0.05 N · m · s · rad−1 .
On notera cette équation différentielle sous la forme :

dw 1 Kc Ke
µ ¶
= aw(t ) + b avec a = − +f
dt J R
KcU
b=
JR

On réalise une simulation avec N = 100 étapes de calcul et un pas de temps ∆t = 10−4 s.
(a) Définir les différentes constantes intervenant dans le problème.
(b) Définir la liste t = [t 0 , . . . , t N −1 ] avec t i = i ∆t ainsi qu’une liste w de taille N , dont tous les
termes sont pour l’instant nuls (et qui contiendra, une fois les calculs effectués, les valeurs
w(t 0 ), . . . , w(t N −1 )).
(c) À partir de l’équation différentielle, déterminer comment on va définir w[i +1] à partir de w[i ].
(d) Écrire la boucle réalisant ce calcul.
(e) Représenter graphiquement w en fonction de t avec :

import matplotlib.pyplot as plt


plt.plot(t,w)
plt.xlabel("t")
plt.ylabel("w")
plt.title("Vitesse de rotation du moteur")
plt.show()

(f) Vérifier (numériquement) que la vitesse du moteur tend vers une limite pour t assez grand et
que cette limite est −b/a.
(g) On pose w 0 = −b/a (vitesse limite du moteur). Écrire une boucle while permettant de déter-
miner la plus petite valeur de k telle que w[k] Ê 0.95w 0 . Déterminer le temps t [k] correspon-
dant. Que représente t [k] ?

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp9.pdf
Exercice 2 Chimie / Réaction d’ordre 1 : On considère la réaction de décomposition des ions per-
oxodisulfate :
1
S 2O 82− + H2O = 2SO 42− + O 2 + 2H +
2

On note C la concentration en S 2O 82− . L’évolution de cette concentration est décrite par l’équation
différentielle :
dC
= −kC
dt

avec k = 5.0 · 10−3 min−1 et C 0 = 10−2 mol · L−1 . On réalise une simulation avec le pas de temps
∆t = 0.1 s et N = 2500 étapes de calcul.
(a) Définir les différentes constantes intervenant dans le problème.
(b) Définir les listes t = [t 0 , . . . , t N −1 ] avec t i = i ∆t et C la liste de taille N dont tous les termes sont
pour l’instant nuls.
(c) À partir de l’équation différentielle, déterminer comment on va définir C [i +1] à partir de C [i ].
(d) Écrire la boucle réalisant ce calcul.
(e) Représenter graphiquement C en fonction de t avec :

import matplotlib.pyplot as plt


plt.plot(t,C)
plt.show()

(f) On donne les mesures suivantes :

t (min) 0 50 100 150 200 250


C (mol · L−1 ) 10−2 7.8 · 10−3 6.05 · 10−3 4.72 · 10−3 3.68 · 10−3 2.86 · 10−3

Définir les listes t_mes et C_mes correspondant à ces valeurs puis représenter simultané-
ment les valeurs mesurées et les valeurs calculées avec :

plt.plot(t,C)
plt.plot(t_mes,C_mes,’+’,markersize=12)
plt.legend(["Calculs","Mesures"])
plt.title("C en fonction de t")
plt.xlabel("t")
plt.ylabel("C")
plt.show()

Notes
¦ Pour que les valeurs obtenues par la simulation soit pertinentes, il faut que le pas de temps ∆t soit
choisi judicieusement. Disons simplement que ∆t doit être « petit » devant le temps de réaction du
système. Ceci a pour conséquence qu’il faut déjà avoir une certaine connaissance du système avant
de le simuler.

¦ Cette méthode de résolution approchée d’une équation différentielle est appelée méthode d’Euler.
TP 9 : Simulation d’un système en physique, chimie, SII

Éléments de correction

Ex. 1 :

import matplotlib.pyplot as plt

# Constantes du problème

U=10.0
J=5.5e-5
R=5.2
Kc=0.24
Ke=0.24
f=0.05
a=-1.0/J*(Kc*Ke/R+f)
b=Kc*U/(J*R)

# Paramètres de la simulation

N=100
Delta_t=1e-4

t=[i*Delta_t for i in range(N)]


w=[0]*N

L’équation différentielle permet d’écrire (sachant que t [i + 1] − t [i ] est « petit ») :

w[i + 1] − w[i ]
' aw[i ] + b
t [i + 1] − t [i ]

de sorte que l’on définit w[i + 1] par :

∀i ∈ ‚0, N − 2ƒ, w[i + 1] = w[i ] + (t [i + 1] − t [i ])(aw[i ] + b)

for i in range(N-1):
w[i+1]=w[i]+(t[i+1]-t[i])*(a*w[i]+b)

Représentation graphique :

plt.plot(t,w)
plt.xlabel("$t$")
plt.ylabel("$w$")
plt.title("Vitesse de rotation du moteur")
Vitesse de rotation du moteur
8

4
w

0
0.000 0.002 0.004 0.006 0.008 0.010
t

w0=-b/a
k=0
while w[k]<0.95*w0:
k=k+1
print w0, w[k], t[k]

7.55667506297 7.20255155066 0.0026


On a trouvé t [k] = 2.6 · 10−3 s, c’est le temps qu’il faut au moteur pour atteindre 95% de sa vitesse
limite.

Ex. 2 :

import matplotlib.pyplot as plt

# Paramètres de la simulation

Delta_t=0.1
N=2500

t=[i*Delta_t for i in range(N)]


C=[0]*N

# Constantes du problème

k=5.0e-3
C[0]=1e-2
Comme t [i + 1] − t [i ] est « petit », l’équation différentielle donne :

C [i + 1] −C [i ]
' −kC [i ]
t [i + 1] − t [i ]

de sorte que l’on définit C [i + 1] à partir de C [i ] par :

∀i ∈ ‚0, N − 2ƒ, C [i + 1] = C [i ] − k(t [i + 1] − t [i ])C [i ]

for i in range(N-1):
C[i+1]=C[i]-k*(t[i+1]-t[i])*C[i]
Représentation graphique :

t_mes=[0,50,100,150,200,250]
C_mes=[1e-2,7.8e-3,6.05e-3,4.72e-3,3.68e-3,2.86e-3]
plt.plot(t,C)
plt.plot(t_mes,C_mes,’+’,markersize=12)
plt.legend(["Calculs","Mesures"])
plt.title("C en fonction de t")
plt.xlabel("t")
plt.ylabel("C")

0.010
C en fonction de t
Calculs
Mesures
0.009

0.008

0.007

0.006
C

0.005

0.004

0.003

0.002
0 50 100 150 200 250
t
TP 10 : Listes (3) et complexité
Exercice 1 Somme pondérée : On considère deux listes N et C de même taille n. On veut calculer
la somme pondérée s :

s = C [0]N [0] + · · · +C [n − 1]N [n − 1]

(a) Écrire la fonction somme_ponderee(N,C) qui réalise ce calcul.


(b) Tester cette fonction sur des exemples simples et pertinents.
(c) Déterminer un ordre de grandeur du temps d’exécution de cette fonction, en fonction de n.

Exercice 2 Suite de Syracuse : On rappelle la définition de la suite de Syracuse : u 0 est un entier


positif et
un
∀n ∈ N, u n+1 = si u n est pair
2
= 3u n + 1 si u n est impair

(a) Lorsque u 0 = 5, calculer u 1 , u 2 , u 3 , u 4 .


(b) Écrire une fonction syracuse(u0,n) qui construit la liste [u 0 , u 1 , . . . , u n ] correspondant à
cette suite.
(c) Tester cette fonction sur des exemples pertinents.
(d) Déterminer un ordre de grandeur du temps d’exécution de cette fonction, en fonction de n.

Exercice 3 Le problème du sac à dos : On considère n objets numérotés de 0 à n − 1. Chacun de ces


objets possède une masse M k et une valeur Vk qui seront représentées en P YTHON par deux listes :

M = [M 0 , M 1 , . . . , M n−1 ]
V = [V0 ,V1 , . . . ,Vn−1 ]

toutes deux de même taille n. On veut ranger certains de ces objets dans un sac pouvant contenir
une masse totale maximale M max de manière à ce que la valeur totale soit la plus grande possible.
Une sélection d’objets est une liste :

S = [S 0 , S 1 , . . . , S n−1 ]

de taille n telle que chaque élément S k est égal à 0 ou 1 (1 signifiant que l’on prend l’objet k et 0
signifiant qu’on ne le prend pas). Pour tester les fonctions, on pourra utiliser les valeurs suivantes :

M = [12, 2, 1, 4, 3]
V = [4, 2, 1, 10, 2]
M max = 15

(a) Écrire une fonction valeur_selection(V,S) qui calcule la valeur totale des objets de la
sélection S (pour la liste de valeurs V ). Donner un ordre de grandeur du temps d’exécution de
cette fonction, en fonction de n.
(b) Écrire une fonction masse_selection(M,S) qui calcule la masse totale des objets de la
sélection S (pour la liste de masses M ). Donner un ordre de grandeur du temps d’exécution
de cette fonction, en fonction de n.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp10.pdf
(c) On considère la fonction suivante :

def selections(n):
S=[]
for k in range(2**n):
L=[]
x=k
for i in range(n):
L.append(x%2)
x=x/2
S.append(L)
return S
Elle retourne la liste de toutes les sélections possibles pour n objets. Par exemple :

print selections(3)

[[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 0, 1], [1, 0, 1], [0,
1, 1], [1, 1, 1]]
Donner un ordre de grandeur du temps d’exécution de cette fonction, en fonction de n.
(d) Écrire une fonction selection_maximale(Mmax,V,M) (utilisant la fonction donnée à la
question précédente), qui retourne une sélection des n objets dont la masse totale est infé-
rieure à M max et dont la valeur totale est la plus grande possible. Donner un ordre de grandeur
du temps d’exécution de cette fonction, en fonction de n.
Nom :

Manipuler l’environnement de développement

Nommer correctement le programme 1


Exécuter le programme 1
Tester le programme dans la console 1

Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1

Algorithmique et programmation

Utiliser une boucle for, une boucle while, une condition 3


Utiliser le bon range, la bonne condition 3
La structure générale du programme est correcte 3
Comprendre un programme existant, l’utiliser, le modifier 3
Tester le programme (interpréter les réponses, les messages d’erreur éventuels) 3
Le programme fonctionne correctement (ou : savoir le corriger) 3
Évaluer le temps d’exécution d’un programme 3

Nom :

Manipuler l’environnement de développement

Nommer correctement le programme 1


Exécuter le programme 1
Tester le programme dans la console 1

Écrire du code
Mettre des commentaires 1
Nommer les variables 1
Écrire une fonction 1
Gérer l’indentation 1

Algorithmique et programmation

Utiliser une boucle for, une boucle while, une condition 3


Utiliser le bon range, la bonne condition 3
La structure générale du programme est correcte 3
Comprendre un programme existant, l’utiliser, le modifier 3
Tester le programme (interpréter les réponses, les messages d’erreur éventuels) 3
Le programme fonctionne correctement (ou : savoir le corriger) 3
Évaluer le temps d’exécution d’un programme 3
TP 10 : Listes (3) et complexité

Éléments de correction

Ex. 1 :

def somme_ponderee(N,C):
"""
Calcule la somme N[0]*C[0]+...+N[n-1]*C[n-1]
C et N : listes de même taille
"""
s=0
for i in range(len(N)):
s=s+C[i]*N[i]
return s
print somme_ponderee([1,1,1],[1,-1,1])

1
Temps d’exécution : Tsomme_ponderee (n) = O(n).

Ex. 2 : Pour u0 = 5, on trouve u 1 = 16 puis u 2 = 8, u 3 = 4, u 4 = 2, u 5 = 1, u 6 = 4, etc.

def syracuse(u0,n):
"""
Construit la liste [u0,u1,...,un]
constituée des (n+1) premiers termes de la suite de Syracuse
partant de u0
"""
u=u0
L=[u0]
for k in range(n):
if u%2==0:
u=u/2
else:
u=3*u+1
L.append(u)
return L
print syracuse(5,6)

[5, 16, 8, 4, 2, 1, 4]
Le temps d’exécution est un O(n). Remarque : si on définit une fonction qui calcule u n puis on
l’utilise ensuite pour construire la liste, on obtient un temps d’exéction en O(n 2 ).

Ex. 3 : Les valeurs utilisées pour les exemples :

ex_M=[12,2,1,4,3]
ex_V=[4,2,1,10,2]
ex_Mmax=15
def valeur_selection(V,S):
"""
Calcule la valeur de la sélection définie par S
"""
v=0
for i in range(len(S)):
if S[i]==1:
v=v+V[i]
return v
print valeur_selection(ex_V,[1,0,0,0,1])

def masse_selection(M,S):
"""
Calcule la masse totale de la sélection définie par S
"""
m=0
for i in range(len(S)):
if S[i]==1:
m=m+M[i]
return m
print masse_selection(ex_M,[1,0,0,0,1])

15

Remarque. Ces deux fonctions sont identiques (c’est même la fonction somme_ponderee de
l’exercice 1). Leur temps d’exécution est un O(n). 

def selections(n):
S=[]
for k in range(2**n):
L=[]
x=k
for i in range(n):
L.append(x%2)
x=x/2
S.append(L)
return S

Le temps d’exécution de cette fonction est un O(n2n ). On supposera que la sélection [0, . . . , 0] est
toujours valide.
def selection_maximale(Mmax,V,M):
n=len(V)
Smax=[0]*n
vmax=0
for S in selections(n):
if valeur_selection(V,S)>vmax and masse_selection(M,S)<=Mmax:
Smax=S
vmax=valeur_selection(V,Smax)
return Smax
print selection_maximale(ex_Mmax,ex_V,ex_M)

[0, 1, 1, 1, 1]
Le temps d’exécution est un O(n2n ).
TP 11 : Chaînes de caractères

B BBUn exemple du résumé de cours 11 est faux. La version corrigée est la suivante (les chan-
gements sont indiqués en gras, la version sur le site web est correcte) :

Exemple Python. Les chaînes de caractères interviennent typiquement lorsqu’il faut demander
des informations à l’utilisateur par l’intermédaire du clavier. Le programme suivant demande un
nombre (entier) et affiche le carré de ce nombre :

x=int(raw_input("Entrez un nombre : ")) # Cette ligne est changée


print "Le carré de ce nombre est %i" % i**2

Noter que le programme produira une erreur si on entre, par exemple, un nombre flottant tel que
1.2. 

B Les différents exercices sont liés. On pourra donc utiliser un seul fichier pour la totalité du TP.

Applications directes
Exercice 1 : On considère deux chaînes de caractères txt et mot et on veut déterminer à quelles
positions on retrouve mot dans txt en convenant qu’un point dans mot peut désigner n’importe
quel caractère dans txt. Par exemple si :

txt = "abcabbab"
mot = "ab."

alors mot apparait dans txt aux positions 0 et 3. Adapter la fonction positions(txt,mot) vue
en cours pour qu’elle réponde à ce problème. Vérifier son fonctionnement sur quelques exemples
pertinents.

Exercice 2 : Modifier la fonction précédente pour réaliser une nouvelle fonction nbocc(txt,mot)
qui renvoie le nombre de fois où mot apparait dans txt (avec les conventions de l’exercice précé-
dent). Vérifier son fonctionnement sur quelques exemples pertinents. Remarque : on veut simple-
ment compter le nombre de fois où mot apparait dans txt, il sera donc inutile de créer une liste conte-
nant les positions où mot apparait.

Mise en œuvre
Exercice 3 Séquences exceptionnelles dans des chaînes d’ADN : Une chaîne d’ADN (on dira aussi
séquence) est une chaîne de caractères dans laquelle apparaissent uniquement les lettres a, t, c, g.
On appelle nucléotides les quatre chaînes de caractères "a", "t", "c" et "g".
(a) Étant donnée une chaîne d’ADN (notée simplement adn) et un nucléotide n, on note ϕadn (n)
la proportion de n dans adn (c’est à dire le nombre de fois où n apparait dans adn divisé par
le nombre de caractères de la chaîne adn). Écrire une fonction phi(adn,n) qui réalise ce
calcul (on utilisera la fonction nbocc de l’exercice précédent). Faire quelques tests en utilisant
la chaîne d’ADN :

adn = "ttcagttgtgaatgaatgga"

Donner un ordre de grandeur du temps d’exécution de cette fonction, en fonction de N (lon-


gueur de la chaîne adn).

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp11.pdf
(b) Si n 1 et n 2 sont deux nucléotides, on note τadn (n 1 , n 2 ) le nombre de fois où apparait la chaîne
n 1 + n 2 dans adn divisé par le nombre de fois où apparait n 1 + "." (le point désignant n’im-
porte quelle lettre, on reprend les conventions des exercices précédents). Écrire une fonction
tau(adn,n1,n2) qui réalise ce calcul (on utilisera la fonction nbocc de l’exercice pré-
cédent). Faire quelques tests. Donner un ordre de grandeur du temps d’exécution de cette
fonction, en fonction de N (longueur de la chaîne adn).
(c) Étant donnée une chaîne de nucléotides ch de longueur `, on appelle fréquence théorique
d’apparition de ch dans adn le nombre :

ϕadn (ch[0]) × τadn (ch[0], ch[1]) × · · · × τadn (ch[` − 2], ch[` − 1])

On appelle fréquence observée d’apparition de ch dans adn le nombre de fois où ch apparait


dans adn divisé par m − ` + 1 où m est la longueur de adn. Définir les fonctions calculant les
fréquences théorique et observée, notées freq_th(adn,s) et freq_obs(adn,s)
(d) Définir la fonction delta(adn,s) différence de freq_obs(adn,s) et freq_th(adn,s).
Calculer delta(adn,"aaa"), delta(adn,"tta") et delta(adn,"gaa") avec la chaine
ADN de l’exemple donné plus haut.
(e) Récupérer la liste de toutes les séquences de nucléotides de longueur 3 par copier coller à
partir de :

http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/Sequences3.html

Parmi ces séquences, déterminer celle pour laquelle delta est le plus grand.
(f) Reprendre la question précédente sur une séquence ADN réelle : le gène Antennapedia de la
drosophile. Pour cela, télécharger le fichier :

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/
Antennapedia-adn.txt

et l’enregistrer dans le même répertoire que votre programme P YTHON. Utiliser ensuite les
commandes :

f=open(’Antennapedia-adn.txt’,’r’)
adn=f.readline().replace("\n","")
f.close()

La chaîne adn contient alors le contenu du fichier (4111 nucléotides).

Notes
¦ Dans une chaîne d’ADN donnée, les généticiens étudient spécifiquement les chaînes de nucléo-
tides qui apparaissent significativement plus souvent que leur fréquence théorique d’apparition. Le
programme réalisé ici n’est pas du tout efficace : on recalcule πadn (n) et τadn (n 1 , n 2 ) de nombreuses
fois alors qu’il serait beaucoup plus efficace de faire le calcul une fois pour toutes.
Nom :

Manipuler l’environnement de développement

Nommer correctement le programme 1


Tester le programme dans la console 1

Écrire du code
Mettre des commentaires 1
Écrire une fonction 1
Gérer l’indentation 1

Algorithmique et programmation

La structure générale du programme est correcte 3


Utiliser le bon range, la bonne condition 3
Comprendre un programme existant, l’utiliser, le modifier 3
Tester le programme (interpréter les réponses, les messages d’erreur éventuels) 3
Le programme fonctionne correctement (ou : savoir le corriger) 3

Nom :

Manipuler l’environnement de développement

Nommer correctement le programme 1


Tester le programme dans la console 1

Écrire du code
Mettre des commentaires 1
Écrire une fonction 1
Gérer l’indentation 1

Algorithmique et programmation

La structure générale du programme est correcte 3


Utiliser le bon range, la bonne condition 3
Comprendre un programme existant, l’utiliser, le modifier 3
Tester le programme (interpréter les réponses, les messages d’erreur éventuels) 3
Le programme fonctionne correctement (ou : savoir le corriger) 3
TP 11 : Chaînes de caractères

Éléments de correction
Ex. 1 :

def positions(txt,mot):
"""
La liste des positions où mot apparait dans txt
mot est une chaine de caractères dans laquelle ’.’ désigne
un caractère quelconque
"""
Pos=[]
for i in range(len(txt)-len(mot)+1):
nb_egaux=0
for j in range(len(mot)):
if mot[j]=="." or mot[j]==txt[i+j]:
nb_egaux=nb_egaux+1
if nb_egaux==len(mot):
Pos.append(i)
return Pos
print positions("abcabbac","ab.")

[0, 3]

Ex. 2 :

def nbocc(txt,mot):
"""
Le nombre de fois où mot apparait dans txt
mot est une chaine de caractères dans laquelle ’.’ désigne
un caractère quelconque
"""
n=0
for i in range(len(txt)-len(mot)+1):
nb_egaux=0
for j in range(len(mot)):
if mot[j]=="." or mot[j]==txt[i+j]:
nb_egaux=nb_egaux+1
if nb_egaux==len(mot):
n=n+1
return n
print nbocc("abcabbac","ab.")

Ex. 3 :

# Les exemples :

adn_exemple="ttcagttgtgaatgaatgga"
f=open(’/home/ba/Enseignement/PC/Python/Data/Antennapedia-adn.txt’,’r’)
adn_antennapedia=f.readline().replace("\n","")
f.close()
def phi(adn,n):
"""
adn : chaine de caractères non vide
n : nucléotide (chaine d’un seul caractère)
Résultat : fréquence de n dans adn
"""
return float(nbocc(adn,n))/len(adn)
print phi(adn_exemple,"a")

0.3

def tau(adn,n1,n2):
"""
adn : chaine de caractères non vide
n1,n2 : nucléotides (chaines d’un caractère)
Résultat : fréquence de n1n2 dans adn
"""
return float(nbocc(adn,n1+n2))/nbocc(adn,n1+".")
print tau(adn_exemple,"a","t")

0.4

def freq_th(adn,ch):
"""
adn,ch : chaines de caractères non vides
Résultat : fréquence théorique d’apparition de ch
dans la séquence adn
"""
f=phi(adn,ch[0])
for i in range(0,len(ch)-1):
f=f*tau(adn,ch[i],ch[i+1])
return f
def freq_obs(adn,ch):
"""
adn,ch : chaines de caractères non vides
Résultat : fréquence observée d’apparition de ch
dans la séquence adn
"""
return float(nbocc(adn,ch))/(len(adn)-len(ch)+1)
def delta(adn,ch):
"""
adn,ch : chaines de caractères non vides
Résultat : différence entre les fréquences observée et théorique
"""
return freq_obs(adn,ch)-freq_th(adn,ch)

Sequences3=[’ttt’,’ttc’,’ttg’,’tta’,’tct’,...]
def max_delta(adn,mots):
"""
Résultat : élément de la liste de mots pour lequel
la différence entre fréquences observée et théorique
est maximale ainsi que la valeur de la différence
"""
s0=mots[0]
m0=delta(adn,s0)
for i in range(1,len(mots)):
s=mots[i]
m=delta(adn,s)
if m>m0:
m0=m
s0=s
return (s0,m0)
# Séquence de taille 3 pour laquelle delta_freq est maximal
print max_delta(adn_exemple,Sequences3)

(’aat’, 0.0631111111111111)

#print max_delta(adn_antennapedia,Sequences3)
TP 12 : Gestion des fichiers

Exercice 1 Conversion d’un fichier : Placer le fichier Antennapedia-formate.txt dans les


même répertoire que vos programmes P YTHON. Ce fichier contient la séquence des nucléotides du
gène Antennapedia de la drosophile avec la présentation suivante (on donne uniquement les pre-
mières lignes) :

1 ttcagttgtg aatgaatgga cgtgccaaat agacgtgccg ccgccgctcg attcgcactt


61 tgctttcggt tttgccgtcg tttcacgcgt ttagttccgt tcggttcatt cccagttctt
121 aaataccgga cgtaaaaata cactctaacg gtcccgcgaa gaaaaagata aagacatctc
...

(a) Écrire un programme P YTHON qui ouvre ce fichier et construit une chaîne de caractères à
partir des différentes lignes en ne gardant que l’information sur les nucléotides (on enlère les
nombres, les espaces, etc. on ne garde en fait que les lettres a, t, c, g).
(b) Compléter le programme pour qu’il enregistre cette chaîne de caractères dans un nouveau
fichier nommé Antennapediat-brut.txt.
Rappel : on peut parcourir une chaîne de caractères de la même manière qu’une liste. Exemple :

>>> s="abc"
>>> for c in s:
... print c
...
a
b
c

Exercice 2 Écrire une image au format PBM : On considère une image rectangulaire constituée
uniquement de pixels (points) noirs et blancs. La largeur de l’image est de ` pixels et et hauteur est
de n pixels. Cette image sera représentée par une liste P YTHON et on désire l’enregistrer dans un
fichier en utilisant le format PBM. Par exemple :
L’image : La liste P YTHON : Le fichier PBM correspondant :

L=[[1,1,0,0], P1
[0,1,1,0], 4 3
[0,0,1,1]] 1 1 0 0
0 1 1 0
(largeur 4 et hauteur 3).
0 0 1 1
Un fichier au format PBM est construit de la manière suivante : la première ligne est la chaîne de ca-
ractères "P1", la deuxième donne la largeur et la hauteur de l’image (séparées par un espace) et
chaque ligne suivante correspond à une ligne de l’image en donnant les couleurs de pixels (1 pour
noir et 0 pour blanc), séparées par des espaces également.
Écrire une fonction ecrire_pbm(L,nom) qui construit le fichier nommé nom à partir de la liste
L en respectant le format PBM.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp12.pdf
Exercice 3 Compter les mots :
(a) Écrire une fonction nombre_mots(s) qui compte combien de mots il y a dans la chaîne
de caractères s. Note : pour simplifier cette première question, on supposera que la chaîne de
caractère s est composée uniquement de mots séparés par un espace simple, par exemple

s = "Une phrase simple"

(b) Utiliser cette fonction pour compter combien de mots comporte le premier chapitre de L’Île
Mystérieuse de Jules Verne (fichier IleMysterieuseChap1.txt).
(c) On veut reprendre la fonction nombre_mots de la première question pour qu’elle fonctionne
dans un cas plus général. On définit pour cela la liste :

Separateurs=[" ",",",";",".","!","?",":","(",")","-","\n"]

("\n" est le caractère « retour à la ligne »). Si s est une chaîne de caractères, on appelle mot de
s toute chaîne non vide, contenue dans s et délimitée par deux éléments de la liste ci-dessus.
Modifier la fonction nombre_mots pour qu’elle compte les mots de s avec cette nouvelle
définition.
TP 12 : Gestion des fichiers

Éléments de correction
Ex. 1 :

FICHIER=’Antennapedia-formate.txt’
FICHIERADN=’Antennapedia-brut.txt’

f=open(FICHIER,’r’)
adn=""
s=f.readline()
while s!="":
for i in range(len(s)):
if s[i] in [’a’,’t’,’c’,’g’]:
adn=adn+s[i]
s=f.readline()
f.close()
print adn[0:20]+"..."

ttcagttgtgaatgaatgga...

f=open(FICHIERADN,’w’)
f.write(adn)
f.close()

Ex. 2 :

def ecrire_pbm(L,nom):
f=open(nom,’w’)
f.write("P1\n")
# Largeur de l’image = len(L[0])
# Hauteur de l’image = len(L)
# Une possibilité pour l’écrire :
f.write("%i %i\n" % (len(L[0]),len(L)))
# Autre possibilité :
# f.write(str(len(L[0]))+" "+str(len(L))+"\n")
for ligne in L:
for pixel in ligne :
f.write(str(pixel)+" ")
f.write("\n")
f.close()
ecrire_pbm([[1,1,0,0],[0,1,1,0],[0,0,1,1]],’test.pbm’)

Le contenu du fichier :

P1
4 3
1 1 0 0
0 1 1 0
0 0 1 1
Ex. 3 : (a) Vu les conditions données dans l’énoncé, le nombre de mots dans une chaîne de ca-
ractères est égal au nombre d’espaces plus 1.

def nombre_mots(s):
n=0
for i in range(len(s)):
if s[i]==" ":
n=n+1
return n+1
print nombre_mots("Une phrase simple")

3
(b) Il suffit maintenant de prendre le fichier ligne à ligne et totaliser le nombre de mots de chaque
ligne :

FICHIER="IleMysterieuseChap1.txt"

f=open(FICHIER,’r’)
N=0
s=f.readline()
while s!="":
N=N+nombre_mots(s)
s=f.readline()
f.close()
print N

1996
(c) On va modifier la fonction nombre_mots pour que son fonctionnement soit plus réaliste.
On utilise une chaîne de caractères intermédiaire notée ch_int. On parcourt la chaîne s et,
si le caractère rencontré n’est pas un séparateur, on l’ajoute à ch_int. Si le caractère rencon-
tré est un séparateur, on regarde le contenu de la chaîne ch_int qui contient les caractères
rencontrés depuis le dernier séparateur. Si cette chaîne est vide, c’est que l’on se trouve entre
deux séparateurs adjacents et il ne faut pas augmenter le nombre de mots. Si elle n’est pas
vide, alors on augmente le nombre de mots et on vide la chaine ch_int.

def nombre_mots(s):
Separateurs=[" ",",",";",".","!","?",":","(",")","-","\n"]
ch_int=""
n=0
for i in range(len(s)):
if s[i] in Separateurs:
if ch_int!="":
n=n+1
ch_int=""
else:
ch_int=ch_int+s[i]
return n
print nombre_mots(" Une chaine, sans doute... plus complexe !\n")
6

f=open(FICHIER,’r’)
N=0
s=f.readline()
while s!="":
N=N+nombre_mots(s)
s=f.readline()
f.close()
print N

2095
TP 13 : Tableaux à 2 dimensions, images et calcul matriciel

Exercice 1 Calcul matriciel, systèmes : On pourra traiter cet exercice directement dans la console.
£ 1 −2 ¤ 1
(a) Définir avec N UMPY la matrice A = et le vecteur x = . Calculer A −1 ainsi que le
£ ¤
1 1 −1
produit Ax.
(b) On considère le système :

 x + 2y + 3z = 6
4x + 5y + 6z = 15
7x + 8y + 9z = 24

Traduire matriciellement ce système. Avec P YTHON et N UMPY : inverser la matrice du système


puis le résoudre.

Traitement d’images
¦ On commencera par récupérer un exemple d’image :

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/papillon.txt

(à enregistrer dans le même répertoire que vos programmes P YTHON). Tous les exercices de ce TP
pourront être traités dans le même fichier où l’on commencera par entrer les commandes :

import numpy as np
import matplotlib.pyplot as plt
def afficher_image(A):
plt.xticks([])
plt.yticks([])
plt.imshow(A,cmap=plt.cm.gray)
plt.show()

On utilisera comme exemple l’image associée au fichier papillon.txt que l’on vient de téléchar-
ger :

Papillon=np.fromfile("papillon.txt",float,-1," ").reshape(240,320)

Vérifier que tout se passe bien en ajoutant la ligne :

afficher_image(Papillon)

Exécuter le programme, l’image du papillon doit s’afficher. Fermer la fenêtre correspondante et pas-
ser aux exercices.

Exercice 2 Transformations géométriques sur une image :


(a) Écrire une fonction miroir_vert(A) qui construit et renvoie une nouvelle image B de
même taille que A et telle que :

B [i , j ] = A[i , m − j − 1]

Par exemple :

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp13.pdf
Papillon Miroir vertical

On commencera par écrire dans la fonction (n,m)=A.shape afin que n représente le nombre
de lignes de A et m le nombre de colonnes. On définira ensuite B=np.zeros((n,m)) afin
de construire un tableau B de même taille que A et dont tous les coefficients sont nuls. On
définira alors B [i , j ] avec la relation ci-dessus en utilisant deux boucles.
(b) Définir de même la fonction miroir_horiz(A) :
Papillon Miroir horizontal

Exercice 3 Détection des contours : On présente ici une méthode simple permettant de mettre en
évidence les contours dans une image. Pour une image contenue dans un tableau A, on construit
un nouveau tableau D de même taille que A et tel que :
q
D[i , j ] = 255 − (A[i , j − 1] − A[i , j + 1])2 + (A[i − 1, j ] − A[i + 1, j ])2

Écrire une fonction detecter_contours(A) qui construit ce tableau. Exemple :


Papillon Contours

Exercice 4 Histogramme d’une image : L’histogramme d’une image représentée par un tableau A
est la liste H de taille 256 telle que H [i ] est égal au nombre de cases de valeur i dans A. Écrire une
fonction histogramme(A) qui construit et retourne la liste H . On pourra ensuite effectuer le tracé
de l’histogramme avec (par exemple) :

2500
plt.plot(histogramme(Papillon))
2000

1500

1000

500

0
0 50 100 150 200 250 300
TP 13 : Tableaux à 2 dimensions, images et calcul matriciel

Éléments de correction
Ex. 1 :

>>> import numpy as np


>>> A=np.array([[1,-2],[1,1]])
>>> x=np.array([1,-1])
>>> np.linalg.inv(A)
array([[ 0.33333333, 0.66666667],
[-0.33333333, 0.33333333]])
>>> np.dot(A,x)
array([3, 0])

On peut aussi écrire :

>>> import numpy as np


>>> A=np.array([[1,-2],[1,1]])
>>> x=np.array([[1],[-1]])
>>> np.linalg.inv(A)
array([[ 0.33333333, 0.66666667],
[-0.33333333, 0.33333333]])
>>> np.dot(A,x)
array([[3],
[0]])

hxi
Résolution du système A y =b :
z

>>> import numpy as np


>>> A=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> np.linalg.inv(A)
array([[ 3.15221191e+15, -6.30442381e+15, 3.15221191e+15],
[ -6.30442381e+15, 1.26088476e+16, -6.30442381e+15],
[ 3.15221191e+15, -6.30442381e+15, 3.15221191e+15]])
>>> b=np.array([6,15,24])
>>> np.dot(np.linalg.inv(A),b)
array([ 21., -6., -6.])

Ex. 2 :

def miroir_vert(A):
(n,m)=A.shape
B=np.zeros((n,m))
for i in range(n):
for j in range(m):
B[i,j]=A[i,m-j-1]
return B
def miroir_horiz(A):
(n,m)=A.shape
B=np.zeros((n,m))
for i in range(n):
for j in range(m):
B[i,j]=A[n-i-1,j]
return B

Ex. 3 :

import numpy as np
import matplotlib.pyplot as plt
Papillon=np.fromfile("/home/ba/Enseignement/PC/Python/Data/papillon.txt",float,
def detecter_contours(A):
(n,m)=A.shape
D=np.zeros((n,m))
for i in range(1,n-1):
for j in range(1,m-1):
D[i,j]=255-((A[i,j-1]-A[i,j+1])**2+(A[i-1,j]-A[i+1,j])**2)**0.5
return D
plt.subplot(1,2,1)
plt.xticks([])
plt.yticks([])
plt.imshow(Papillon,cmap=plt.cm.gray)
plt.title(’Papillon’)
plt.subplot(1,2,2)
plt.xticks([])
plt.yticks([])
plt.imshow(detecter_contours(Papillon),cmap=plt.cm.gray)
plt.title(’Contours’)

Papillon Contours

On peut même améliorer le rendu en assombrissant l’image comme vu en classe :


plt.subplot(1,2,1)
plt.xticks([])
plt.yticks([])
plt.imshow(Papillon,cmap=plt.cm.gray)
plt.title(’Papillon’)
plt.subplot(1,2,2)
plt.xticks([])
plt.yticks([])
plt.imshow(detecter_contours(Papillon)**2/255,cmap=plt.cm.gray)
plt.title(’Contours’)

Papillon Contours

Ex. 4 :

def histogramme(A):
(n,m)=A.shape
H=[0]*256
for i in range(n):
for j in range(m):
H[int(A[i,j])] += 1
return H
TP 14 : Présentation générale de Scilab

Remarque. Le logiciel S CILAB est un logiciel spécialisé dans le calcul numérique. Conformément
au programme, la partie calcul numérique (correspondant au second semestre) peut être mise en
œuvre aussi bien avec P YTHON qu’avec S CILAB. On donne ici une présentation rapide de S CILAB. 

Mise en place de l’environnement Scilab

• Lancer S CILAB ;
• Fermer le Navigateur de fichiers et l’Historique des commandes ; ne conserver que les fenêtres
Console et Navigateur de variables.

Premiers calculs avec la console Scilab

¦ Entrer les commandes ci-contre dans la console et observer les résultats


--> 2+%pi↵
obtenus.
--> (1+%e)/2↵
--> %eps↵ Remarques.
--> 1+%eps↵ • Le symbole --> est l’invite de la console. Il ne faut pas le taper et par
--> %i^2↵ la suite, on ne l’indiquera plus.
--> (1-%i)^2↵ • Le symbole ↵ désigne la touche Entrée, par la suite on ne l’indiquera
--> exp(3)↵ plus non plus.
--> %e^3↵ • La variable ans contient le résultat du dernier calcul.
--> cos(%pi)↵ B Noter que la division est la vraie division (exacte).
--> sin(%pi)↵ B Le calcul de puissances se fait avec l’opérateur ^ (contrairement à
--> 2/3↵
** en P YTHON). 

Remarque. S CILAB accepte également la notation ** à la place de ^. Cependant, on verra plus loin
la notation .^ avec S CILAB qui ne peut pas être remplacée par .**. 

a=2 ¦ Entrer les commandes ci-contre dans la console et observer les résultats
a=a+1 obtenus.
A=2*%pi
Remarques.
a+A
• On peut supprimer la variable a en écrivant clear a. On sup-
ans+a
prime toutes les variables en écrivant clear sans plus de précision.
a=1.2e-3
B S CILAB fait la distinction entre majuscules et minuscules (tout
a=rand()
comme P YTHON). 

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp14.pdf
x=[1 2 3 4] Construction de vecteurs / listes
x=[1,2,3,4] ¦ On considère :
y=[1;2;3;4]
x’ x = [ 1 2 3 4 ] ∈ M1,4 (R); z = [ 1 3 5 7 9 ] ∈ M1,5 (R)
1
y’ ·1¸ 0
x(1) y= 2 ∈ M4,1 (R); t =  ...  ∈ M20,1 (R)
3
4 0
y(1) 1
x(2)=3
y(2)=3 Entrer les commandes ci-contre dans la console et observer les résultats
x(2:3) obtenus.
z=[1:2:9]
Remarques.
t(1)=1
• La virgule (ou un espace) sépare deux coefficients sur une même
t(20)=1
ligne, le point virgule permet de passer à la ligne suivante.
t
• La transposée de x (notation mathématique x > ) est notée x’.
length(x)
• La construction a:k:b construit la ligne dont les coefficients sont
length(t)
a, a + k, a + 2k, etc. tant que les valeurs obtenues sont É b.
B Contrairement à P YTHON, les numérotations commencent à 1. 

eye(4,4) Construction de matrices / tableaux


ones(4,2) ¦ On considère
zeros(4,2) h1 2 3i
A=[1,2,3;4,5,6;7,8,9] A= 456 ∈ M3 (R)
789
A(2,3)
A(2,:) Entrer les commandes ci-contre dans la console et observer les
A(:,3) résultats obtenus.
A(2:3,2:3)
A’ Remarques.
• Le coefficient (i , j ) de A est noté A(i,j).
zeros(A)
• La notation A(i,:) désigne la i -ème ligne de A et
ones(A)
eye(A) A(:,j) est la j -ème colonne.
B Contrairement à P YTHON, les numérotations com-
B=rand(A)
mencent à 1. 
size(A)

x=[1;1] Calculs matriciels


A=[1,2;3,4] ¦ Entrer les commandes ci-contre dans la console et observer les résultats
A*x obtenus.
A*A
A.*A Remarques.
A^2 B L’opération .* est le produit terme à terme, l’opération * désigne le
A.^2 vrai produit matriciel.
eye(2,2)./A B De même, A.^2 représente A.*A et A^2 correspond à A*A.
A+1 B La notation ./ est la division terme à terme.
x+1 B Pour une matrice A, la notation A +1 n’a pas de sens mathématique
x.^2 (elle n’est pas homogène) mais pour S CILAB elle représente la ma-
inv(A) trice obtenue en ajoutant 1 à chaque coefficient de A. 
A^(-1)
Application aux systèmes linéaires
Exercice 1 : On considère le système :


 x −y +z −t =1
x + y − z − t = −1

(S )

 x +y +z −t =0
x −y −z +t =2

(a) Définir dans S CILAB les· matrices A ∈ M4 (R) et B ∈ M4,1 (R) telles que le système (S ) s’écrive
x ¸
y
AX = B en posant X = z .
t
(b) Définir dans S CILAB la matrice U = A −1 .
(c) Calculer avec S CILAB les produits AU et U A.
(d) Résoudre le système (S ).

Calculs avec des nombres complexes


¦ Entrer les commandes ci-dessous dans la console et observer les résultats obtenus.

z1=2+%i z1^2 exp(%pi)


z2=1+2*%i real(z1) exp(%i*%pi/2)
z1+z2 imag(z1) %e^(%i*%pi/2)
z1*z2 abs(z1)
z1/z2 conj(z1)

Utilisation de SciNotes
• Aller dans le menu Applications et choisir Sci-
function y=u(n)
Notes.
y=1
• Dans la fenêtre S CI N OTES, entrer le pro-
for k=1:n
gramme ci-contre ;
y=(y+1)^0.5
• Dans le menu Fichiers, choisir Enregistrer le
end
fichier dans... et enregistrer le fichier dans le
endfunction
répertoire TPinfo, par exemple sous le nom
clf()
dessin_suite.sce ;
plot(0:10,feval(0:10,u),’bo’)
• Dans le menu Exécuter, choisir Enregistrer le
title("Suite u")
fichier et exécuter (enregister le fichier dans le
xlabel("n")
répertoire TPinfo, par exemple sous le nom
ylabel("u")
dessin_suite.sce) ;
• On doit alors obtenir une représentation gra-
phique du type :

Suite u
1.7

1.65

1.6

1.55

1.5

1.45

1.4

1.35
u

1.3

1.25

1.2

1.15

1.1

1.05

1
0 1 2 3 4 5 6 7 8 9 10
n
TP 15 : Représentations graphiques
Exercice 1 Comparer une fonction et ses DL :
(a) Représenter sur le même graphique la fonction exp (en trait plein) ainsi que les fonctions x 7→
1 + x et x 7→ 1 + x + x 2 /2 (en pointillés) sur l’intervalle [−2, 2].
(b) De même, représenter sur le même graphique la fonction cos ainsi que son DL2 (0) et son
DL4 (0) sur l’intervalle [−π, π].

Exercice 2 Visualiser le rôle d’un paramètre : On considère l’équation différentielle du second ordre
sous forme canonique :

1 d2 u c 2ξ du c
+ + uc = 0
ω20 dt 2 ω0 dt

avec w 0 = 104 rad · s−1 . On considère une solution :

u c (t ) = A cos(ωa t ) exp(−ξω0 t )

avec A = 1 V et ωa = ω0 1 − ξ2 (régime peudopériodique). Représenter la fonction u c pour ξ =


p

0.1, 0.2, . . . , 0.9 sur [0, 4T ] avec T = 2π/ω0 . La première courbe (ξ = 0.1) sera tracée en bleu, la dernière
(ξ = 0.9) en rouge et les autres en vert. Préciser les axes (et les unités).

Exercice 3 Comparer un modèle et des mesures : On considère la réaction de décomposition des


ions peroxodisulfate :
1
S 2O 82− + H2O = 2SO 42− + O 2 + 2H +
2
On note A la concentration en S 2O 82− et B la concentration en SO 42− . L’évolution de ces concentra-
tions est modélisée par les fonctions :

A : t 7→ C 0 e−kt
B : t 7→ 2(C 0 − A(t ))

avec k = 5.0 · 10−3 min−1 et C 0 = 10−2 mol · L−1 . On réalise par ailleurs les mesures suivantes :

t (min) 0 50 100 150 200 250


A (mol · L ) 10−2
−1
7.8 · 10−3 6.05 · 10−3 4.72 · 10−3 3.68 · 10−3 2.86 · 10−3

Représenter sur le même dessin les courbes théoriques pour A et B ainsi que les valeurs expérimen-
tales.

Exercice 4 Conjecturer un résultat : On considère les suites (S n ), (u n ) et (v n ) définies par :


Xn (−1)k+1
∀n Ê 1, S n = p
k=1 k
u n = S 2n
v n = S 2n+1

(a) Définir ces trois suites et représenter sur le même dessin les premiers termes des suites (u n )
et (v n ).
(b) Quelles propriétés observe-t-on sur les suites (u n ) et (v n ) ? Les démontrer.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp15.pdf
TP 15 : Représentations graphiques

Éléments de correction

Ex. 1 :

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-2,2,100)
plt.plot(x,np.exp(x),’r-’)
plt.plot(x,1+x,’b--’)
plt.plot(x,1+x+(x**2)/2,’b--’)
plt.xlabel("x")
plt.ylabel("y")
plt.legend(["exp(x)","DL_1(0)","DL_2(0)"],loc="upper left")

8
exp(x)
7 DL_1(0)
DL_2(0)
6

4
y

−1
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x

import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(-np.pi,np.pi,100)
plt.plot(x,np.cos(x),’r-’)
plt.plot(x,1-(x**2)/2,’b--’)
plt.plot(x,1-(x**2)/2+(x**4)/24,’b--’)
plt.xlabel("x")
plt.ylabel("y")
plt.legend(["cos(x)","DL_2(0)","DL_4(0)"],loc="lower left")
1

−1

−2

−3
cos(x)
DL_2(0)
DL_4(0)
−4
−4 −3 −2 −1 0 1 2 3 4
x

Ex. 2 :

import numpy as np
import matplotlib.pyplot as plt
w_0=1e4
A=1
T=2*np.pi/w_0
t=np.linspace(0,4*T,100)
# La première courbe (xi=0.1)
xi=0.1
w_a=w_0*np.sqrt(1-xi**2)
plt.plot(t,A*np.cos(w_a*t)*np.exp(-xi*w_0*t),’b-’)
# La dernière courbe (xi=0.9)
xi=0.9
w_a=w_0*np.sqrt(1-xi**2)
plt.plot(t,A*np.cos(w_a*t)*np.exp(-xi*w_0*t),’r-’)
plt.legend(["x1=0.1","xi=0.9"])
# Les autres courbes
for xi in [0.2,0.3,0.4,0.5,0.6,0.7,0.8]:
w_a=w_0*np.sqrt(1-xi**2)
plt.plot(t,A*np.cos(w_a*t)*np.exp(-xi*w_0*t),’g-’)
plt.xlabel("t (s)")
plt.ylabel("u_c (V)")
1.0
x1=0.1
0.8
xi=0.9

0.6

0.4

0.2
u_c (V)

0.0

−0.2

−0.4

−0.6

−0.8
0.0000 0.0005 0.0010 0.0015 0.0020 0.0025 0.0030
t (s)

Ex. 3 :

import numpy as np
import matplotlib.pyplot as plt
t_mes=[0,50,100,150,200,250]
A_mes=[1e-2,7.8e-3,6.05e-3,4.72e-3,3.68e-3,2.86e-3]
C_0=1e-2
k=5e-3
t=np.linspace(0,250,100)
plt.plot(t,C_0*np.exp(-k*t),’b-’)
plt.plot(t,2*C_0*(1-np.exp(-k*t)),’r-’)
plt.plot(t_mes,A_mes,’b+’)
plt.legend(["A (modele)","B (modele)","A (mesures)"],loc="upper left")
plt.xlabel("t (min)")
plt.ylabel("Concentration (mol/L)")

0.016
A (modele)
B (modele)
0.014 A (mesures)

0.012

0.010
Concentration (mol/L)

0.008

0.006

0.004

0.002

0.000
0 50 100 150 200 250
t (min)

Ex. 4 :
import matplotlib.pyplot as plt
def S(n):
s=0
for k in range(1,n+1):
s=s+float((-1)**(k+1))/(k**0.5)
return s
def u(n):
return S(2*n)
def v(n):
return S(2*n+1)
plt.plot(range(1,15),[u(k) for k in range(1,15)],’bo’)
plt.plot(range(1,15),[v(k) for k in range(1,15)],’ro’)
plt.legend(["u_n","v_n"])
plt.xlabel("n")

0.9
u_n
v_n
0.8

0.7

0.6

0.5

0.4

0.3

0.2
0 2 4 6 8 10 12 14
n

Les propriétés visibles (à démontrer) :


• La suite (u n ) est croissante ;
• La suite (v n ) est décroissante ;
• Pour tout n Ê 1 : u n É v n .
TP 16 : Approximations de racines et d’intégrales (1)
¦ On rappelle les fonctions newton(f,f_prim,x0,n) et newton_eps(f,f_prim,x0,eps)
vues en classe :

def newton(f,f_prim,x0,n): def newton_eps(f,f_prim,x0,eps):


""" """
f : fonction considérée f : fonction considérée
f_prim : dérivée de f f_prim : dérivée de f
x0 : valeur de départ x0 : valeur de départ
pour la suite pour la suite
n : nombre d’itérations eps : précision souhaitée
""" """
x=x0 x=x0
for k in range(0,n): while f(x-eps)*f(x+eps)>0:
x=x-f(x)*1.0/f_prim(x) x=x-f(x)*1.0/f_prim(x)
return x return x
On pourra récupérer le code depuis :
http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/newton.html

Exercice 1 Utilisation sur un exemple : On considère l’équation de Képler (TP 5) :


x − e sin(x) = m
d’inconnue x dans le cas particulier où e = 1/2 et m = 1. On définit la fonction :
1
f : x 7→ x − sin(x) − 1
2
Une étude de fonction (que l’on ne demande pas de faire) permet de démontrer que l’équation
f (x) = 0 possède une unique solution α sur R.
(a) Représenter la fonction f sur l’intervalle [1, 2].
(b) Utiliser la fonction newton_eps pour déterminer une valeur approchée de α à 10−3 près.
(c) Résoudre cette même équation avec la fonction fsolve de S CIPY et comparer les résultats
obtenus.

Exercice 2 Programmer une méthode d’approximation : On présente la méthode des cordes. On


considère une fonction f définie sur un intervalle I et qui s’annule pour une valeur α ∈ I . Connais-
sant une approximation x n de α ainsi qu’une valeur a ∈ I fixée, on obtient une approximation plus
précise x n+1 par la construction suivante :

x n+1
xn α a

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp16.pdf
(a) Vérifier que la droite d’équation :

f (x n ) − f (a)
y= (x − a) + f (a)
xn − a

passe par les points de coordonnées (a, f (a)) et (x n , f (x n )).


(b) Vérifier que le point d’intersection de cette droite avec l’axe des abscisses est le point d’abs-
cisse :
xn − a
x n+1 = a − f (a)
f (x n ) − f (a)

La méthode des cordes consiste à définir la suite (x n ) à partir d’une valeur x 0 en utilisant la relation
précédente. Sous certaines conditions, cette suite converge vers une solution de l’équation f (x) = 0.
(c) Programmer une fonction cordes(f,a,x0,n) qui réalise cette méthode d’approximation.
(d) Utiliser cette fonction pour déterminer une valeur approchée de la solution de l’équation de
l’exercice précédent.

Exercice 3 Mise en défaut de la méthode de Newton : On considère les fonctions :

f : x 7→ xe−x
x
g : x 7→
1 + x2

(a) Représenter la fonction f sur l’intervalle [−1, 5].


(b) On applique la méthode de Newton à la fonction f à partir de x 0 = 1.5. Calculer les premières
valeurs obtenues. Que peut-on conjecturer sur le comportement de la méthode de Newton
dans ce cas ?
(c) Représenter la fonction g sur l’intervalle [−2, 2].
p
(d) On applique la méthode de Newton à la fonction g à partir de 1/ 3. Calculer les premières
valeurs obtenues. Que peut-on conjecturer sur le comportement de la méthode de Newton
dans ce cas ?
TP 16 : Approximations de racines et d’intégrales (1)

Éléments de correction
Ex. 1 : On définit la fonction f et on réalise sa représentation graphique de f sur [1, 2] :

import numpy as np
import matplotlib.pyplot as plt
def f(x):
return x-np.sin(x)/2-1

Remarque : en définissant f avec la fonction sin de N UMPY, cette fonction pourra s’appliquer aussi
bien à des nombres qu’à des tableaux. Représentation graphique :

x=np.linspace(1,2,100)
plt.plot(x,f(x),’b-’)
plt.axhline(y=0,color=’k’)

0.6

0.4

0.2

0.0

−0.2

−0.4

−0.6
1.0 1.2 1.4 1.6 1.8 2.0 2.2

La fonction f s’annule sur [1, 2]. On applique la méthode de Newton en prenant x 0 = 2 (par exemple)
et on note alpha_1 l’approximation obtenue :

alpha_1=newton_eps(f,lambda x:1-np.cos(x)/2,2,1e-3)
print alpha_1

1.49932951966
Vérifions que f (α) est effectivement proche de 0 avec l’approximation obtenue :

print f(alpha_1)

0.000605852416689
Avec la fonction fsolve :

from scipy.optimize import fsolve


print fsolve(f,2)

[ 1.49870113]
L’approximation est du même ordre que celle obtenue par la méthode de Newton (à 10−3 près).
Ex. 2 : On vérifie facilement que la droite passe bien par les points (a, f (a)) et (x n , f (x n )). Le point
d’intersection de cette droite avec l’axe des abscisse a pour coordonnées (x n+1 , 0) avec :

f (x n ) − f (a)
0= (x n+1 − a) + f (a)
xn − a

et on en déduit que :

xn − a
x n+1 = a − f (a)
f (x n ) − f (a)

def cordes(f,a,x0,n):
x=x0
for k in range(n):
x=a-float(f(a)*(x-a))/(f(x)-f(a))
return x

On applique la méthode des cordes à la fonction f de l’exercice précédent en prenant a = 2 et x 0 = 1,


on réalise 5 étapes de calcul (par exemple) et on note alpha_2 l’approximation obtenue :

alpha_2=cordes(f,2,1,5)
print alpha_2

1.49869031762
On remarque que pour les approximations obtenues, f (α1 ) et f (α2 ) sont de signes contraires :

print f(alpha_1)*f(alpha_2)

-6.31681113462e-09
Par conséquent, la solution α de l’équation f (x) = 0 est encadrée par α1 et α2 .

Ex. 3 :

def f(x):
return x*np.exp(-x)
def f1(x):
return (1-x)*np.exp(-x)
x=np.linspace(-1,5,100)
plt.plot(x,f(x),’b-’)
plt.axhline(y=0,color=’k’)
plt.axvline(x=0,color=’k’)
0.5

0.0

−0.5

−1.0

−1.5

−2.0

−2.5

−3.0
−1 0 1 2 3 4 5

print [newton(f,f1,1.5,k) for k in range(1,11)]

[4.5, 5.7857142857142856, 6.9946695095948828, 8.1614843771033296, 9.3011202329319342


10.421585901653708, 11.527725145135475, 12.622712427403389, 13.708750863460901,
14.787436802837927]

def g(x):
return x*1.0/(1+x**2)
def g1(x):
return (1-x**2)*1.0/(1+x**2)**2
x=np.linspace(-2,2,100)
plt.plot(x,g(x),’b-’)
plt.axhline(y=0,color=’k’)
plt.axvline(x=0,color=’k’)

0.6

0.4

0.2

0.0

−0.2

−0.4

−0.6
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0

print [newton(g,g1,3**(-0.5),k) for k in range(1,11)]


[-0.5773502691896255, 0.5773502691896248, -0.577350269189622, 0.5773502691896106,
-0.5773502691895656, 0.5773502691893848, -0.5773502691886618, 0.5773502691857701,
-0.5773502691742034, 0.5773502691279362]
TP 17 : Approximations de racines et d’intégrales (2)

Exercice 1 Oscillateur anharmonique : Un ressort de longueur à vide `0 et de constante de raideur


k est placé dans un plan horizontal. L’une de ses extrémités est accrochée à un point fixe A, l’autre
est accrochée à un petit anneau assimilé à un point matériel M de masse m, glissant sans frottement
sur l’axe Ox.

y
A

O M x

La fonction énergie potentielle est liée au ressort uniquement et a pour expression :

1 ³p 2 ´2
E p (x) = k L + x 2 − `0
2
³p ´2
on posera également f (x) = L 2 + x 2 − `0

Les abscisses des points d’équilibre stables du système correspondent aux minimums locaux de la
fonction E p ou, de manière équivalente, de la fonction f . On prendra `0 = 1 pour la suite.
(a) Vérifier que :

³p ´
dE p kx L 2 + x 2 − `0
= p
dx L2 + x 2

³p ´
On définit dans la suite g (x) = x L 2 + x 2 − `0 .
(b) On suppose ici que L = 0.5. Représenter graphiquement la fonction f sur l’intervalle [−2, 2].
Déterminer les abscisses des minimums locaux de E p .
(c) On suppose ici que L = 1.5. Représenter graphiquement la fonction f sur l’intervalle [−2, 2].
Déterminer les abscisses des minimums locaux de E p .
(d) Sur le même graphique, représenter les fonctions f pour L ∈ {0.1, 0.2, 0.3, . . . , 1.8, 1.9, 2.0} (on
représentera en bleu les courbes pour L < 1, en vert les courbes pour L > 1 et en rouge la
courbe pour L = 1). Commenter.

Exercice 2 Comparaison des différentes méthodes : On considère les fonctions :

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp17.pdf
def newton_eps(f,f_prim,x0,eps): def dichotomie(f,a,b,epsilon):
x=x0 N=0
N=0 while (b-a)>epsilon:
while f(x-eps)*f(x+eps)>0: c=float(a+b)/2
x=x-f(x)*1.0/f_prim(x) if f(a)*f(c)<=0:
N=N+1 b=c
return (x,N) else:
a=c
N=N+1
return (float(a+b)/2,N)

On pourra récupérer le code depuis :

http:
//alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/dicho_newton_eps.html

(a) Expliquer en quoi ces fonctions diffèrent de celles étudiées en cours.


(b) On considère l’équation x 2 − 2 = 0. Remplir le tableau suivant en donnant les valeurs de N
obtenues pour chaque fonction suivant la précision ε demandée :

Dichotomie Newton
ε = 10 −2

ε = 10−3
ε = 10−4
ε = 10−5
ε = 10−10

(on prendra x 0 = 2 comme point de départ dans la méthode de Newton et pour la méthode de
dichotomie on utilisera l’intervalle [1, 2]).

Exercice 3 Comparaison avec la méthode des cordes : On reprend la méthode des cordes (TP 16).
Partant de deux valeurs x 0 et a, on définit la suite (x n ) en posant :
xn − a
x n+1 = a − f (a)
f (x n ) − f (a)

(a) Programmer une fonction cordes_eps(f,a,x0,eps) qui met en œuvre cette méthode
d’approximation et renvoie le couple (x, N ) où x est l’approximation obtenue et N le nombre
d’étapes de calcul effectuées.
(b) Comparer cette méthode avec les méthodes de dichotomie et de Newton en reprenant l’exemple
de l’exercice précédent.
TP 17 : Approximations de racines et d’intégrales (2)

Éléments de correction

Ex. 1:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve

L=0.5
x=np.linspace(-2,2,100)
plt.plot(x,(np.sqrt(L**2+x**2)-1)**2,’b-’)
plt.xlabel(’x’)
plt.ylabel(’f(x)’)
plt.title(’Fonction f pour L=0.5’)

Fonction f pour L=0.5


1.2

1.0

0.8
f(x)

0.6

0.4

0.2

0.0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x

Pour obtenir les abscisses des minimums locaux, on détermine les solutions de l’équation g (x) = 0
(les solutions non nulles car f présente un maximum local en 0). En fait les deux abscisses cherchées
sont opposées et il suffit de déterminer celle qui est strictement positive :

print fsolve(lambda x:(np.sqrt(L**2+x**2)-1)**2,1)

[ 0.8660254]
Pour L = 1.5 :

L=2.5
plt.plot(x,(np.sqrt(L**2+x**2)-1)**2,’b-’)
plt.xlabel(’x’)
plt.ylabel(’f(x)’)
plt.title(’Fonction f pour L=1.5’)
Fonction f pour L=1.5
5.0

4.5

4.0

f(x)
3.5

3.0

2.5

2.0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0
x

Il y a un seul minimum local et il a pour abscisse 0.

for L in np.linspace(0.1,2,20):
if L<1:
style=’b-’
elif L>1:
style=’g-’
else:
style=’r-’
plt.plot(x,(np.sqrt(L**2+x**2)-1)**2,style)
plt.xlabel(’x’)
plt.ylabel(’f(x)’)

3.5

3.0

2.5

2.0
f(x)

1.5

1.0

0.5

0.0
−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0

Ex. 2 :
def f(x):
return x**2-2
def f1(x):
return 2*x
for eps in [1e-2,1e-3,1e-4,1e-5,1e-10]:
print newton_eps(f,f1,2,eps)[1]
print dichotomie(f,1,2,eps)[1]
print "\n"

2 7

3 10

3 14

3 17

4 34

import matplotlib.pyplot as plt


k=range(11)
plt.plot(k,[newton_eps(f,f1,2,10**(-p))[1] for p in k],’ro’)
plt.plot(k,[dichotomie(f,1,2,10**(-p))[1] for p in k],’bo’)
plt.xlabel("k")
plt.ylabel("N")
plt.title(u"Nombre d’itérations pour une précision de 10**(-k)")
plt.legend(["Newton","Dichotomie"],loc="upper left")

35
Nombre d'itérations pour une précision de 10**(-k)
Newton
Dichotomie
30

25

20
N

15

10

0
0 2 4 6 8 10
k
Ex.
def3 : cordes_eps(f,a,x0,eps):
x=x0
N=0
while f(x-eps)*f(x+eps)>0:
x=a-f(a)*float(x-a)/(f(x)-f(a))
N=N+1
return (x,N)
for eps in [1e-2,1e-3,1e-4,1e-5,1e-10]:
print cordes_eps(f,1,2,eps)[1]
print newton_eps(f,f1,2,eps)[1]
print dichotomie(f,1,2,eps)[1]
print "\n"
3 2 7
4 3 10
5 3 14
7 3 17
13 4 34
TP 18 : Approximations de racines et d’intégrales (3)
Exercice 1 Calcul de la période d’oscillation d’un pendule :
On considère un pendule simple pouvant osciller dans le plan verti-
cal constitué d’une masse m suspendue par un fil de longueur `. La
position du pendule par rapport à la verticale est repérée par un angle
θ. Lorsque les oscillations sont de faible amplitude, la période T des θ0
oscillations est donnée en première approximation par la relation :
θ
g
r
T = 2π
`

Dans le cas général, la période des oscillations est :


r Z π/2
g dϕ θ0
T =4 avec k = sin
` 0 2
q
1 − k 2 sin2 ϕ

où θ0 est l’amplitude des oscillations. En utilisant la commande quad du module S CIPY, calculer T
pour ` = 1 m et θ0 = 50◦ .

Exercice 2 Programmer et tester une méthode d’approximation d’intégrales :


On considère dans cet exercice la méthode des rectangles avec point
milieu. Cette approximation est construite à partir d’une subdivision
Rb
régulière a 0 , . . . , a n de l’intervalle [a, b]. L’intégrale a f (t ) dt est alors
approchée par la somme des aires des rectangles dont la largeur est
la longueur de l’intervalle [a i , a i +1 ] et la hauteur est la valeur de f au
milieu de cet intervalle. a b

(a) Écrire l’approximation obtenue comme une somme, à la manière de ce qui a été fait pour la
méthode des rectangles.
(b) Programmer une fonction rectangles_milieu(f,a,b,n) qui réalise cette approxima-
tion où n est le nombre d’intervalles de la subdivision.
(c) Proposer une méthode permettant de comparer le précision de cette approximation avec celle
obtenue pour la méthode des rectangles et des trapèzes.

Exercice 3 Valeur moyenne et valeur efficace d’une tension : On considère une tension sinusoïdale
u(t ) définie par la relation :

u(t ) = A sin(2π f t ) +U0

avec A = 6 V, U0 = 5 V et f = 50 Hz. On pose T = 1/ f et on note :

1 T
Z
u moy = u(t ) dt
T 0
s
1 T
Z
u eff = u(t )2 dt
T 0

(a) Représenter la fonction u sur [−2T, 2T ] (penser à donner des noms aux axes en précisant les
unités).
(b) Déterminer des valeurs approchées de u moy et u eff .

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp18.pdf
TP 18 : Approximations de racines et d’intégrales (3)

Éléments de correction

Ex. 1 :

from math import *


from scipy.integrate import quad
theta0=50*pi/180
k=sin(theta0/2)
g=9.81
l=1
print 4*sqrt(g/l)*quad(lambda u:1.0/sqrt(1-k**2*sin(u)**2),0,pi/2)[0]

20.6592186152

Ex.
def2 : rectangles_milieu(f,a,b,n):
s=0
for k in range(n):
s=s+f(a+(k+0.5)*float(b-a)/n)
return float(b-a)/n*s
for n in [10,100,1000,10000,100000,1000000]:
print rectangles_milieu(lambda x:x**2,0,1,n)
print "\n"
0.3325
0.333325
0.33333325
0.3333333325
0.333333333325
0.333333333333
On remarque que l’on gagne approximativement 2 chiffres significatifs en passant de n = 10k à
10k+1 .

Ex. 3 :

from scipy.integrate import quad


import numpy as np
import matplotlib.pyplot as plt
A=6
U0=5
f=50
T=1.0/f
def u(t):
return A*np.sin(2*np.pi*f*t)+U0
t=np.linspace(-2*T,2*T,100)
plt.plot(t,u(t))
plt.xlabel("t (s)")
plt.ylabel("u(t) (V)")
12

10

6
u(t) (V)

−2
−0.04 −0.03 −0.02 −0.01 0.00 0.01 0.02 0.03 0.04 0.05
t (s)

umoy=quad(u,0,T)[0]/T
ueff=(quad(lambda t:u(t)**2,0,T)[0]/T)**0.5
print umoy
print ueff

5.0 6.5574385243
TP 19 : Équations différentielles d’ordre 1

B Pour les représentations graphiques, penser à donner des noms aux axes en précisant les unités.

Exercice 1 Étude d’un circuit RC :


On considère le circuit RC ci contre (Fig. 1). La tension u aux
R
bornes du condensateur est solution de l’équation différen-
tielle :
du
RC + u = ue u e (t ) u(t )
dt C

On prendra R = 1000 Ω et C = 10−6 F ainsi que la condition ini-


tiale u(0) = 0.
Fig. 1
(a) Dans cette question, u e (t ) = U0 sin(2π f t ) avec U0 = 10 V ue
et f = 100 Hz. Représenter u e et u sur le même dessin sur
l’intervalle [0, 5/ f ]. 10 V
(b) Dans cette question, u e est la fonction dont la représenta-
tion graphique est donnée sur la figure 2. Programmer la
fonction ue(t). Représenter u e et u sur le même dessin
sur l’intervalle [0, 10−1 ].
0 10−2 s t

Fig. 2

Exercice 2 Chute d’un grêlon : On étudie la chute d’un grêlon de masse m = 3.6 · 10−3 kg. On note
v la composante de la vitesse en projection sur un axe vertical descendant. On étudie deux modèles
de forces de frottements :
• Le modèle des forces de frottements linéaires conduit à l’équation différentielle :

dv
m = mg − k 1 v
dt
• Le modèle des frottements quadratiques conduit à l’équation différentielle :

dv
m = mg − k 2 v 2
dt

Données numériques : k 1 = 1.8 · 10−3 Nsm−1 , k 2 = 9.2 · 10−5 et la condition initiale est v(0) = 0 pour
les deux modèles.
(a) Représenter sur le même dessin les solutions des deux équations sur l’intervalle [0, 15].
(b) Estimer numériquement la vitesse limite v lim atteinte par le grêlon dans chacun des deux mo-
dèles.
(c) Placer sur le dessin une droite horizontale située 95% de v lim . Estimer graphiquement le temps
nécessaire pour atteindre 95% de la vitesse limite dans chaque modèle.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp19.pdf
TP 19 : Équations différentielles d’ordre 1

Éléments de correction

Ex. 1 :

from math import *


from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt

R=1000
C=1e-6
f=100

def ue(t):
return 10*np.sin(2*pi*f*t)

def F(u,t):
return (ue(t)-u)/(R*C)

t=np.linspace(0,5.0/f,100)

plt.plot(t,ue(t),’b-’)
plt.plot(t,odeint(F,0,t),’r-’)
plt.legend(["ue","u"])
plt.xlabel("t (s)")
plt.ylabel("u (V)")

10
ue
u

5
u (V)

−5

−10
0.00 0.01 0.02 0.03 0.04 0.05 0.06
t (s)
def ue(t):
if (t<=0):
return 0
elif (t<=1e-2):
return 1000*t
else:
return 10

def F(u,t):
return (ue(t)-u)/(R*C)

t=np.linspace(0,0.02,100)

plt.plot(t,[ue(ti) for ti in t],’b-’)


plt.plot(t,odeint(F,0,t),’r-’)
plt.legend(["ue","u"],loc="lower right")
plt.xlabel("t (s)")
plt.ylabel("u (V)")

10

6
u (V)

ue
u
0
0.000 0.005 0.010 0.015 0.020 0.025
t (s)

Ex. 2 :
m=3.6e-3
g=9.81
k1=1.8e-3
k2=9.2e-5

tau=m/k1

def F(v,t):
return g-k1/m*v
def G(v,t):
return g-k2/m*v**2

t=np.linspace(0,15,100)

v1=odeint(F,0,t)
v2=odeint(G,0,t)

vlim=v1[-1]

plt.plot(t,v1,’b-’)
plt.plot(t,v2,’r-’)
plt.axhline(y=vlim*0.95,color=’k’)

plt.xlabel("t (s)")
plt.ylabel("v (m/s)")
plt.legend([u"Linéaire","Quadratique"],loc="lower right")
20

15
v (m/s)

10

Linéaire
Quadratique
0
0 2 4 6 8 10 12 14 16
t (s)
TP 20 : Méthode d’Euler

¦ On reprend la fonction P YTHON qui met en œuvre la méthode d’Euler présentée en classe :

def euler(F,y0,t):
N=len(t)
y=[0]*N
y[0]=y0
for i in range(N-1):
y[i+1]=y[i]+(t[i+1]-t[i])*F(y[i],t[i])
return y

Exercice 1 Estimer l’efficacité de la méthode d’Euler : On considère le problème de Cauchy :

y0 = y
½

y(0) = 1

dont on connait la solution exacte. On va l’utiliser pour estimer l’efficacité de la méthode d’Euler.
On va travailler sur l’intervalle [0, 1].
(a) Définir la fonction F(y,t) correspondant à cette équation différentielle.
(b) Définir la fonction ecart(n) qui renvoie la valeur e définie par :

e=np.mean(np.abs(y-np.exp(t)))

où t=np.linspace(0,1,n) et y est le résultat renvoyé par application de la méthode


d’Euler.
(c) Calculer ecart(10), ecart(100), ecart(1000). Commenter.
(d) Représenter graphiquement ecart(n) en fonction de n pour 2 É n É 20.
(e) Représenter graphiquement ecart(n)**(-1) en fonction de n pour 2 É n É 20.

Exercice 2 Adapter la méthode d’Euler à un problème spécifique : On considère la chute d’un grêlon
de masse m = 3.6 · 10−3 kg modélisée par l’équation différentielle avec condition initiale :

dv k
= g − v2
dt m
v(0) = 0

(modèle des forces de frottements quadratiques). On veut étudier l’influence du paramètre k sur le
mouvement. Pour cela, on va utiliser la méthode d’Euler en l’adaptant pour qu’elle puisse prendre
en compte des équations différentielles avec paramètres, de la forme :

y 0 = F (k, y, t )

où k est un paramètre.
(a) Définir la fonction F(k,v,t) correspondant au problème de la chute du grêlon.
(b) Écrire une fonction euler_param(F,k,y0,t) qui adapte la méthode d’Euler au cas d’une
fonction F avec paramètre.
(c) Représenter graphiquement sur l’intervalle [0, 15] la solution du problème de Cauchy lorsque
k = 5 · 10−5 , 6 · 10−5 , 7 · 10−5 , . . . , 15 · 10−5 . Quelle est l’influence de k sur la vitesse limite ?

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp20.pdf
TP 20 : Méthode d’Euler

Éléments de correction

Ex. 1 :

import numpy as np
def F(y,t):
return y
def ecart(n):
t=np.linspace(0,1,n)
y=euler(F,1,t)
e=np.mean(np.abs(y-np.exp(t)))
return e
print ecart(10), ecart(100), ecart(1000)

0.0527836197455 0.00502584677917 0.000500256651888

import matplotlib.pyplot as plt


plt.plot([ecart(n) for n in range(2,21)],’bo’)
plt.xlabel("n")
plt.ylabel("Ecart")

0.40

0.35

0.30

0.25
Ecart

0.20

0.15

0.10

0.05

0.00
0 2 4 6 8 10 12 14 16 18
n

Remarque : on peut tracer n*ecart(n) en fonction de n :

plt.clf()
plt.plot([ecart(n)**(-1) for n in range(2,21)],’bo’)
plt.xlabel("n")
plt.ylabel("Ecart**(-1)")
40

35

30

25

Ecart**(-1) 20

15

10

0
0 2 4 6 8 10 12 14 16 18
n

Sur cet exemple, on observe que ecart(n) est de l’ordre de 1/n.

Ex. 2 :

g=9.81
m=3.6e-3
def F(k,v,t):
return g-float(k)/m*v**2
def euler_param(F,k,y0,t):
N=len(t)
y=[0]*N
y[0]=y0
for i in range(N-1):
y[i+1]=y[i]+(t[i+1]-t[i])*F(k,y[i],t[i])
return y
t=np.linspace(0,15,100)
plt.clf()
for p in range(5,16):
if p==5:
style=’g-’
else:
style=’b-’
k=p*1e-5
y=euler_param(F,k,0,t)
plt.plot(t,y,style)
plt.xlabel("t")
plt.ylabel("v(t)")
30

25

20

v(t) 15

10

0
0 2 4 6 8 10 12 14 16
t
TP 21 : Calcul matriciel et systèmes linéaires

Matrices : point de vue mathématique


¦ Rappels :
• Une matrice A ∈ Mnp (R) est un tableau de nombres à n lignes et p colonnes ;
• Si A ∈ Mnp (R), B ∈ Mnp (R) et λ ∈ R, on peut définir la somme A + B et le produit λA ;
• Si A ∈ Mnp (R) et B ∈ Mpm (R), on peut définir le produit AB et AB ∈ Mnm (R) ;
• Si A ∈ Mnp (R), on peut définir la transposée A > ;
• Si A ∈ Mn (R) et k ∈ N, on peut définir la puissance A k ;
• Quelques matrices particulières :
 
1 (0)
..
In =  .  (identité de taille n)
 
(0) 1
 
0 ··· 0
 .. .. 
O np =  . .  (matrice nulle de taille n × p)
0 ··· 0
 
a1 (0)
..
.  (matrice diagonale de taille n)
 

(0) an

¦ Entrer dans une console les commandes ci-


import numpy as np
contre et observer le résultat.
A=np.array([[1,2,3],[4,5,6]])
print A
Remarques.
print A.shape
• On peut utiliser np.eye(10) à la place
3*A
de identity.
B=np.ones((2,3))
• np.dot effectue le produit matriciel.
print B
• Noter que le produit D A n’est pas défini
print np.indentity(10)
(incompatible).
A+B
• La construction A[1,:] correspond à la
print A.transpose()
ligne d’indice 1 de A (attention : il s’agit de
D=np.diag([1,2,3])
la deuxième ligne) et A[:,0] donne la co-
print D
lonne d’indice 0 de A (donc la première co-
np.dot(A,D)
lonne). 
np.dot(D,A)
np.linalg.matrix_power(D,5)
print A[1,:]
print A[:,0]

B Si on définit une matrice A puis une matrice B en écrivant


A=np.identity(2)
B=A, alors la matrice A n’est pas dupliquée en mémoire. Autre- B=A
ment dit, les variables A et B font référence à la même matrice
B[0,0]=2
et une modification de B portera également sur A (remarque : le
print A
même problème existe avec les listes).
print B

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp21.pdf
¦ Si on travaille sur une matrice extraite de A (ici la première ligne
A=np.identity(2)
de A), le même problème apparait.
x=A[:,0]
x[0]=2
print x
print A

¦ Pour définir une nouvelle x=A[:,0].copy()


A=np.identity(2)
matrice B égale à A mais in- x[0]=2
B=A.copy()
dépendantes, on peut utiliser print x
B[0,0]=2
la fonction copy. On pourrait print A
print A
aussi écrire B=np.array(A)
print B
et x=np.array(A[:,0]).

Exercice 1 : On considère la matrice

1 2 1
 

A= 1 2 1
−1 −2 −1

Calculer A 2 , A 3 , A 4 et A 5 . Conjecturer une expression générale pour A n (on ne demande pas de le


démontrer).

Vecteurs : point de vue mathématique


¦ Rappels :
 
x1
..
• Un vecteur v ∈ Rp se note v =  ;
 
.
xp
• Si v ∈ Rp , w ∈ Rp et λ ∈ R, on peut définir la somme v + w et le produit λv ;
• Si A ∈ Mnp (R) et v ∈ Rp , on peut définir le produit Av et Av ∈ Rn .

¦ Entrer dans la console les commandes ci- x=np.array([1,2,3])


contre et observer le résultat. y=np.ones(3)
x+y
x+2*y
A=np.array([[1,1,1],[1,1,-1]])
np.dot(A,x)

B Les vecteurs sont des tableaux à une dimension et les matrices sont des tableaux à deux dimen-
sions. Ainsi, les vecteur ne sont pas vraiment des cas particuliers de matrices. La commande shape
sert à obtenir la forme du vecteur ou de la matrice.

x.shape
A.shape

On peut changer la forme d’un vecteur pour le transformer en matrice :


x.shape=(3,1) x.shape=(1,3) x.shape=3
print x print x print x

Les colonnes et les lignes extraites d’une matrice sont des vecteurs (une dimension) :

u=A[:,1] v=A[1,:]
u.shape v.shape

Systèmes d’équations linéaires


¦ Rappel :
• Un système d’équations linéaire (n équations et n inconnues) :

 a 11 x 1 + · · · + a 1n x n = b 1


..
 .
a n1 x 1 + · · · + a nn x n = b n

   
a 11 ··· a 1n b1
.. ..  . 
peut s’écrire matriciellement Ax = b avec A =   et b =  .. .
 
. .
a n1 · · · a nn bn
• Si A est inversible, alors le système admet une unique solution qui est A −1 b ;
• Si x 0 est une solution particulière du système, alors l’ensemble des solutions est {x 0 + x |
x ∈ Rn et Ax = 0}.

¦ Entrer dans la console les commandes suivantes et observer le résultat :

A=np.array([[2,1,1],[0,2,1],[0,0,2]])
b=np.array([1,1,1])
print np.linalg.inv(A)
x=np.dot(np.linalg.inv(A),b)
print x
np.dot(A,x)

On peut comparer le vecteur x obtenu avec :

np.linalg.solve(A,b)

x
 

Exercice 2 : Écrire matriciellement le système suivant sous la forme A  y  = b puis le résoudre :


z

2x + y = 1


x + 2y + z = −1
2y + z = 0

Les conventions supplémentaires de Python/Numpy
¦ Avec N UMPY :
• Le produit * désigne le produit composantes par composantes, de même pour la puissance
** ;
• On peut ajouter un nombre à chaque composante ;
• Les fonctions mathématiques usuelles de N UMPY peuvent être appliquées à des vecteurs ou
des matrices (ce qui revient à appliquer la fonction à chaque composante).
L’intérêt est essentiellement de pouvoir appliquer des fonctions à des vecteurs. Par exemple :

t=nplinspace(-1,1,100)
y=np.exp(-t**2)
print t.shape
print y.shape

Ce sont ces conventions qui permettent d’effectuer facilement des représentations graphiques :

import matplotlib.pyplot as plt


plt.plot(t,np.sin(t)*np.exp(-t**2),’b-’)
plt.show()

2
(représentation graphique de t 7→ sin(t )e−t sur [−1, 1]).

Pour aller plus loin


¦ La fonction lstsq de N UMPY permet de résoudre de manière « approchée » un système qui ne
possède pas de solution au sens strict du terme. Considérons par exemple le système :

x+y =1
½

x+y =2

Clairement, ce système ne possède pas de solution. Avec la fonction lstsq :

A=np.array([[1,1],[1,1]])
b=np.array([1,2])
print np.linalg.lstsq(A,b)

On obtient un tuple consitué de 3 composantes. Seule la première nous intéresse ici : c’est (0.75, 0.75)
qui constitue la solution approchée du système. On donne ci-dessous une application pratique de
ce type de résolution et on donne ensuite quelques explications sur la notion de solution approchée.

Exercice 3 : On considère la réaction de décomposition des ions peroxodisulfate :


1
S 2O 82− + H2O = 2SO 42− + O 2 + 2H +
2
On note C la concentration en S 2O 82− . On a réalisé les mesures suivantes :

t0 t1 t2 t3 t4
t (min) 50 100 150 200 250
C (mol · L−1 ) 7.85 · 10−3 6.25 · 10−3 4.68 · 10−3 3.60 · 10−3 2.82 · 10−3
y = ln(C ) −4.85 −5.07 −5.36 −5.63 −5.87
y0 y1 y2 y3 y4
L’évolution de la concentration C est modélisée par une relation C (t ) = C 0 e−r t ou encore :

ln(C (t )) = ln(C 0 ) − r t

On cherche donc a et b de sorte que :




 y 0 = at 0 + b
 y 1 = at 1 + b


(S ) ..


 .
 y = at + b

4 4

(système de 5 équations dont les inconnues sont a et b).


(a) Représenter graphiquement les points de coordonnées (t i , y i ).
(b) Expliquer pourquoi le système (S ) ne possède pas de solution.
(c) Écrire matriciellement le système (S ) et déterminer la solution approchée (a, b) fournie par
np.linalg.lstsq.
(d) Représenter graphiquement les points de coordonnées (t i , y i ) ainsi que la droite d’équation
y = at + b pour les valeurs a et b obtenues ci-dessus. Commenter.

¦ Pour définir plus précisément ce que l’on entend par solution approchée, considérons un sys-
tème :
ax + b y = c
½

a0 x + b0 y = c 0
On lui associe une fonction f définie par :

f (x, y) = (ax + b y − c)2 + (a 0 x + b 0 y − c 0 )2

Cette fonction f est positive. De plus, si le système admet une solution (x 0 , y 0 ), alors f (x 0 , y 0 ) = 0.
Dans le cas général, on appelle solution approchée du système tout couple (x 0 , y 0 ) tel que f (x 0 , y 0 )
est minimal. On doit en fait parler de solution au sens des moindres carrés au lieu de « solution
approchée. »

Exercice 4 Une modélisation matricielle : On considère deux entreprises A et B . L’entreprise A


produit une quantité P A de produits chimiques (produit A pour simplifier) et l’entreprise B produit
une quantité P B de produits agro-alimentaires (produit B ). Une partie de ces produits est réutilisée
par les deux usines pour leur propre production :
— L’entreprise A utilise pour elle-même une quantité a ×P A de produit A et l’entreprise B utilise
pour elle-même une quantité b × P B de produit A ;
— De même, l’entreprise A utilise pour elle-même une quantité a 0 × P A de produit B et l’entre-
prise B utilise pour elle-même une quantité b 0 × P B de produit B
(noter qu’il est logique que les quantités de produits A ou B utilisées par chaque entreprise soient
proportionnelles aux productions de ces entreprises). On note U A (respectivement UB ) la quantité
totale de produit A (respectivement B ) utilisée par les deux entreprises et on note C A = P A −U A et
C B = P B −UB les quantités de produits A et B disponibles pour la consommation.
UA PA CA PA
· ¸ · ¸ · ¸ · ¸
(a) Exprimer matriciellement en fonction de puis exprimer en fonction de .
UB PB CB PB
(b) On suppose a = 0.2, b = 0.05, a 0 = 0.2 et b 0 = 0.1. Quelles doivent être les productions P A et P B
si l’on veut que C A = 10 et C B = 100 ?
TP 21 : Calcul matriciel et systèmes linéaires

Éléments de correction

Ex. 1 :

import numpy as np
A=np.array([[1,2,1],[1,2,1],[-1,-2,-1]])
for k in range(6):
print np.linalg.matrix_power(A,k)

[[1 0 0] [0 1 0] [0 0 1]]
[[ 1 2 1] [ 1 2 1] [-1 -2 -1]]
[[ 2 4 2] [ 2 4 2] [-2 -4 -2]]
[[ 4 8 4] [ 4 8 4] [-4 -8 -4]]
[[ 8 16 8] [ 8 16 8] [ -8 -16 -8]]
[[ 16 32 16] [ 16 32 16] [-16 -32 -16]]
Conjecture : pour n Ê 1, A n = 2n−1 A et A 0 = I3 .

Ex. 2 :

A=np.array([[2,1,0],[1,2,1],[0,2,1]])
b=np.array([1,-1,0])
print np.dot(np.linalg.inv(A),b)

[-1. 3. -6.]
ou alors :

print np.linalg.solve(A,b)

[-1. 3. -6.]

Ex. 3 :

import matplotlib.pyplot as plt


t=np.array([50,100,150,200,250])
y=np.array([-4.85,-5.07,-5.36,-5.63,-5.87])
plt.plot(t,y,’g--’)
plt.plot(t,y,’k+’)
plt.xlabel("t (min)")
plt.ylabel("y")
−4.8

−5.0

−5.2

y
−5.4

−5.6

−5.8

−6.0
50 100 150 200 250

t (min)

Les points ne sont pas alignés donc le système (S ) ne possède pas de solution. Ce système dont les
inconnues sont a et b s’écrit matriciellement :

t0 1 y0
   
t 1 a y1
· ¸  
1
=  .. 

 .. .. 
. . b  . 
t4 1 y4

On note A la matrice du système et b le second membre :

A=np.array([t,np.ones(5)]).transpose()
b=np.array(y)
print np.linalg.lstsq(A,b)[0]

[-0.0052 -4.576 ]

La solution approchée est donc a = −5.2 · 10−3 et b = −4.576. Vérifions en superposant le tracé de la
droite d’équation y = at + b :

plt.plot(t,y,’g--’)
plt.plot(t,(-5.2e-3)*t-4.576,’b-’)
plt.plot(t,y,’k+’)
plt.xlabel("t (min)")
plt.ylabel("y")
−4.8

−5.0

−5.2

y
−5.4

−5.6

−5.8

−6.0
50 100 150 200 250

t (min)

La droite obtenue est proche des points de coordonnées (t i , y i ) (ceci correspond en fait à une ré-
gression linéaire).

Ex. 4 : On a U A = aP A + bP B et UB = a 0 P A + b 0 P B donc matriciellement :

UA a b PA
· ¸ · ¸· ¸
= 0
UB a b0 PB
CA PA UA a b PA
· ¸ · ¸ · ¸ µ · ¸¶ · ¸
= − = I2 − 0
CB PB UB a b0 PB
=A

CA PA CA
· ¸ · ¸ · ¸
Connaissant , on obtient = A −1 :
CB PB CB

M=np.array([[0.2,0.05],[0.2,0.1]])
A=np.identity(2)-M
C=np.array([10,100])
print np.dot(np.linalg.inv(A),C)

[ 19.71830986 115.49295775]
La production de produit A doit donc être de 19.7 et celle de produit B de 115.5 (approximative-
ment).
TP 22 : Systèmes d’équations

Résolution d’un système 2 × 2


Exercice 1 Mise en œuvre de la méthode vue en classe : On définira au début du programme

import numpy as np
EPSILON=1e-10
def nul(x):
return abs(x)<=EPSILON
Pour tester si x est nul, on écrira alors nul(x) au lieu de x==0 (qui n’a pas vraiment de sens pour
un flottant). On considère un système linéaire à deux équations et deux inconnues :

ax + b y = c
½

a0 x + b0 y = c 0

a b c
· ¸
Ce système est décrit par la matrice M = 0 .
a b0 c 0
(a) Écrire la fonction resoudreM1(M), vue en classe, qui détermine les solutions du système
représenté par la matrice M dans le cas M 1 étudié en classe.
(b) Écrire de même les fonctions resoudreM2(M) et resoudreM0(M) qui déterminent les
solutions du système représenté par la matrice M dans les cas M 2 et M 0 étudiés en classe.
(c) Écrire les fonctions echange(M) et combinaison(M,c) qui réalisent respectivement les
opérations L 1 ↔ L 2 (échange des deux lignes de la matrice M ) et L 2 ← L 2 − c · L 1 .
(d) Écrire la fonction resoudre2x2(M) qui résout le système décrit par la matrice M en le
mettant d’abord sous l’une des formes M 1 , M 2 , M 0 apropriée puis en appelant la fonction qui
convient.
(e) Tester la fonction resoudre2x2(M) sur les systèmes suivants :

x+y =5 x+y =5 x+y =5


½ ½ ½
(S 1 ) ; (S 2 ) ; (S 3 )
x + 2y = 3 2x + 2y = 10 2x + 2y = 0

Une application des systèmes au calcul numérique


Exercice 2 Résolution approchée d’une équation différentielle d’ordre 2 : On considère l’équation
différentielle d’ordre 2 avec deux conditions
 00
 y − y = sin(t )
y(0) = 0
y(π) = 0

Ce problème est assez facile à résoudre explicitement. Cependant, la recherche d’une solution ap-
prochée va faire intervenir une technique intéressante qui peut être utilisée dans d’autres situations
semblables. On va considérer 6 valeurs de t régulièrement espacées t 0 , t 1 , . . . , t 5 et on va déterminer
y 0 , . . . , y 5 valeurs approchées de y(t 0 ), . . . , y(t 5 ).

t0 t1 t2 t3 t4 t5

y1 h
y2

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp22.pdf
Pour 1 É k É 4, on utilise l’approximation :

y k−1 − 2y k + y k+1
y 00 (t k ) '
h2

(a) En utilisant cette approximation, écrire les 4 équations obtenues à partir de l’équation diffé-
rentielle de départ.
(b) On ajoute les conditions y 0 = 0 et y 5 = 0. On obtient alors un système de 6 équations à 6
inconnues. Écrire ce système sous forme matricielle puis le résoudre.
(c) Représenter graphiquement les points (t i , y i ).
(d) Résoudre explicitement l’équation de départ et représenter graphiquement la solution obte-
nue sur le même dessin que l’approximation pour comparer.

Remarque. Pour justifier l’approximation de y 00 (t k ) utilisée dans cet exercice, on peut utiliser la
formule de Tayloy-Young :

y 00 (a)
y(a + h) = y(a) + h y 0 (a) + h 2 + o (h 2 )
2 h→0

Appliquée avec −h :

y 00 (a)
y(a − h) = y(a) − h y 0 (a) + h 2 + o (h 2 )
2 h→0

de sorte qu’en ajoutant les deux :

y(a + h) + y(a − h) = 2y(a) + h 2 y 00 (a) + o (h 2 )


h→0

On en déduit que :

y(a − h) − 2y(a) + y(a + h)


−−−→ y 00 (a)
h2 h→0

et comme h est « petit », on a l’approximation :

y(a − h) − 2y(a) + y(a + h)


y 00 (a) ' 
h2
TP 22 : Systèmes d’équations

Éléments de correction

Ex. 1 :

import numpy as np
import numpy as np
EPSILON=1e-10
def nul(x):
return abs(x)<=EPSILON

Deux versions possibles pour la fonctions d’échange des lignes :

def echange(M): def echange(M):


for i in range(3): v=M[0,:].copy()
tmp=M[0,i] M[1,:]=M[0,:]
M[0,i]=M[1,i] M[0,:]=v
M[1,i]=tmp

De même pour la fonction réalisant les combinaisons de lignes :

def combinaison(M,x): def combinaison(M,x):


for i in range(3): M[1,:]=M[1,:]-x*M[0,:]
M[1,i]=M[1,i]-x*M[0,i]

def resoudre_M0(M):
u=M[0,2]
v=M[1,2]
if nul(u) and nul(v):
# Le second membre est nul, tout (x,y) est solution
return [np.array([0,0]),np.array([1,0]),np.array([0,1])]
else:
# Le second membre n’est pas nul : pas de solution
return []

def resoudre_M2(M):
b=M[0,1]
u=M[0,2]
v=M[1,2]
if nul(v):
# v est nul, le système est compatible
return [np.array([0,float(u)/b]),np.array([1,0])]
else:
# v n’est pas nul : pas de solution
return []
def resoudre_M1(M):
a=M[0,0]
b=M[0,1]
u=M[0,2]
d=M[1,1]
v=M[1,2]
if nul(d):
# d est nul : il faut regarder v
if nul(v):
# v est nul également
return [np.array([float(u)/a,0]),np.array([-float(b)/a,1])]
else:
# v n’est pas nul : pas de solution
return []
else:
# d n’est pas nul : unique solution
return [np.array([(u-b*float(v)/d)/a,float(v)/d])]

def resoudre2x2(M):
if nul(M[0,0]) and nul(M[1,0]):
# Le première colonne est nulle
if nul(M[0,1]) and nul(M[1,1]):
# La deuxième colonne est nulle
return resoudre_M0(M)
else:
# La deuxième colonne n’est pas nulle
# On permute si besoin
if nul(M[0,1]):
echange(M)
combinaison(M,float(M[1,1])/M[0,1])
return resoudre_M2(M)
else:
# La première colonne n’est pas nulle
# On permute si besoin
if nul(M[0,0]):
echange(M)
combinaison(M,float(M[1,0])/M[0,0])
return resoudre_M1(M)
£1 1 5¤
Système (S 1 ) : M = 123

print resoudre2x2(np.array([[1,1,5],[1,2,3]]))

[array([ 7., -2.])]


. Système (S 2 ) : M = 12 12 10
5
£7¤
Le système (S 1 ) admet une unique solution −2
£ ¤

print resoudre2x2(np.array([[1,1,5],[2,2,10]]))

[array([ 5., 0.]), array([-1., 1.])]


Ensemble des solutions : 50 + t −1
£1 1 5¤
1 , t ∈ R. Système (S 3 ) : M = 2 2 0
£ ¤ £ ¤
print resoudre2x2(np.array([[1,1,5],[2,2,0]]))

[]
Ce système n’admet pas de solution.

Ex. 2 : On obtient pour k ∈ ‚1, 4ƒ l’équation :

y k−1 − 2y k + y k+1
− y k = sin(t k )
h2

ou encore :


µ ¶
2 2
y k−1 − (2 + h )y k + y k+1 = h sin
5

En ajoutant les deux équations y 0 = 0 et y 5 = 0 on obtient le système :

y0 = 0


2 2

y − (2 + h )y + y 2 = h sin (π/5)

0 1



 y − (2 + h 2 )y + y = h 2 sin
(2π/5)

1 2 3
2 2

 y 2 − (2 + h )y 3 + y 4 = h sin (3π/5)
2 2
y 3 − (2 + h )y 4 + y 5 = h sin (4π/5)





y5 = 0

· y0 ¸
..
Ce système s’écrit sous la forme A . = b avec :
y5

1 0 0 0 0 0 0
   
1 −(2 + h 2 ) 1 0 0 0  h 2 sin(π/5) 
   
0 1 −(2 + h 2 ) 1 0 0 h 2 sin(2π/5)
A= ; b= 2
   
0 0 1 −(2 + h 2 ) 1 0 h sin(3π/5)

−(2 + h 2 )
 2
0 0 0 1 1 h sin(4π/5)
  

0 0 0 0 0 1 0

import numpy as np
import matplotlib.pyplot as plt
h=np.pi/5
A=np.array([[1,0,0,0,0,0],[1,-(2+h**2),1,0,0,0],[0,1,-(2+h**2),1,0,0],[0,0,1,-(
b=np.array([0,h**2*np.sin(h),h**2*np.sin(2*h),h**2*np.sin(3*h),h**2*np.sin(4*h)
y=np.linalg.solve(A,b)
plt.plot([k*h for k in range(6)],y,’k+’)
0.0

−0.1

−0.2

−0.3

−0.4

−0.5
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5

On vérifie facilement que la fonction

1
y : t 7→ − sin t
2
est la solution du problème considéré. On représente graphiquement cette fonction et les valeurs
approchées obtenues :

t=np.linspace(0,np.pi,100)
plt.plot(t,-0.5*np.sin(t),’b--’);
plt.plot([k*h for k in range(6)],y,’k+’)

0.0

−0.1

−0.2

−0.3

−0.4

−0.5
0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5
TP 23 : Systèmes d’équations différentielles
Exercice 1 Mise sous tension d’un moteur à courant continu :
On alimente un moteur initialement à l’arrêt par une tension u(t )
dont la représentation graphique est donnée ci-contre. On note w(t ) u(t )
la vitesse de rotation du moteur et i (t ) l’intensité du courant. On a les
40 V
équations différentielles :

di
u(t ) = Ri (t ) + L + K w(t )
dt
dw
J = K i (t ) − f w(t ) 0.1 s t
dt
où :
• J est le moment d’inertie J = 3.2 · 10−4 kg · m2 ;
• f est un coefficient de frottement f = 2.4 · 10−3 N · m · s · rad−1 ;
• R est la résistance du bobinage R = 0.67 Ω ;
• L est l’inductance du bobinage L = 3.8 · 10−3 H ;
• K est la constante de force électromotrice du couple K = 0.12 N/A.
(a) Définir la fonction u(t).
(b) Vérifier que i (t ) et w(t ) sont solutions d’un système d’équations différentielles :

 di
= ···


dt
 dw
= ···


dt

(c) On note X = wi . Définir la fonction F(X,t) associée au système.


£ ¤

(d) Résoudre le sytème avec la condition initiale w(0) = 0 et i (0) = 0 sur l’intervalle [0, 0.4] et re-
présenter les fonctions obtenues.
(e) Écrire la fonction associée au système sous la forme F(X,t,K) afin que l’inertie K soit prise
comme un paramètre. On place une charge sur le moteur ce qui a pour effet d’augmenter son
inertie à K 1 = 0.2 N/A. Résoudre alors le système pour cette valeur et représenter sur le même
graphique les deux vitesses de rotation. Quelle est l’influence de K sur la vitesse de rotation ?

Exercice 2 Cinétique chimique / Réactions successives : On considère les réactions successives d’hy-
drolyse d’un diester A :

k1
A + H2O −→ B
k2
B + H2O −→ C +???

(A est le diester et B le monoester). On note a(t ) (respectivement b(t ), c(t )) la concentration [A]
(respectivement [B ], [C ]) à l’instant t . La cinétique est décrite par les équations différentielles :

da
= −k 1 a(t )
dt
db
= −k 2 b(t ) + k 1 a(t )
dt
dc
= k 2 b(t )
dt

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp23.pdf
On donne les valeurs numériques :

[A]0 = 10−3 mol · L−1


[B ]0 = [C ]0 = 0
k 1 = 8,02 · 10−6 s−1
k 2 = 1,51 · 10−4 s−1

L’intuition du chimiste : comme k 1 << k 2 , la concentration de B va rester très faible et on peut donc
considérer que db/dt = 0.
(a) Résoudre numériquement le système d’équations différentielles, représenter conjointement
les fonctions a, b et c et vérifier l’intuition du chimiste (déterminer en particulier le maximum
de b). On travaillera sur un intervalle de temps de... 10 jours !
(b) Pour contrôler, vérifier numériquement les points suivants :
• à l’état final, c = a(0) et a = 0 ;
• a(t ) + b(t ) + c(t ) est constante égale à a(0).
TP 23 : Systèmes d’équations différentielles

Éléments de correction

Ex. 1 : (a)

from math import *


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

J=3.2e-4
f=2.4e-3
R=0.67
L=3.8e-3
K=0.12

def u(t):
if t<0:
return 0
elif t>0.1:
return 40
else:
return 400*t
(b) On obtient le système d’équations différentielles :


di K R 1
= − w(t ) − i (t ) + u(t )



dt L L L
dw f K
= − w(t ) + i (t )



dt J J

(c)

def F(X,t):
i=X[0]
w=X[1]
iprim=-K/L*w-R/L*i+1/L*u(t)
wprim=-f/J*w+K/J*i
return [iprim,wprim]
(d)

t=np.linspace(0,0.4,100)
X=odeint(F,[0,0],t)
plt.plot(t,X[:,0])
plt.xlabel("t")
plt.ylabel("i(t)")
plt.title(u"Intensité")
Intensité
14

12

10

i(t)
6

0
0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45

plt.plot(t,X[:,1])
plt.xlabel("t")
plt.ylabel("w(t)")
plt.title("Vitesse de rotation")

Vitesse de rotation
350

300

250

200
w(t)

150

100

50

0
0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45
t

(e)
def F(X,t,K):
i=X[0]
w=X[1]
iprim=-K/L*w-R/L*i+1/L*u(t)
wprim=-f/J*w+K/J*i
return [iprim,wprim]
t=np.linspace(0,1,200)
X=odeint(F,[0,0],t,args=(K,))
X1=odeint(F,[0,0],t,args=(0.2,))
plt.plot(t,X[:,1],’b’)
plt.plot(t,X1[:,1],’r’)
plt.xlabel("t")
plt.ylabel("w(t)")
plt.legend([u"À vide",u"Chargé"],loc="lower right")
plt.title("Vitesse de rotation")

350
Vitesse de rotation

300

250

200
w(t)

150

100

50
À vide
Chargé
0
0.0 0.2 0.4 0.6 0.8 1.0
t

plt.plot(t,X[:,0],’b’)
plt.plot(t,X1[:,0],’r’)
plt.xlabel("t")
plt.ylabel("i(t)")
plt.legend([u"À vide",u"Chargé"])
plt.title(u"Intensité")
14
Intensité
À vide
Chargé
12

10

i(t)
6

0
0.0 0.2 0.4 0.6 0.8 1.0
t

Ex. 2 :

from math import *


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

a0=1e-3
b0=0
c0=0
k1=8.02e-6
k2=1.51e-4

def F(X,t):
a=X[0]
b=X[1]
c=X[2]
return [-k1*a,-k2*b+k1*a,k2*b]

t=np.linspace(0,10*24*3600,100)
X=odeint(F,[a0,b0,c0],t)

plt.plot(t,X[:,0])
plt.plot(t,X[:,1])
plt.plot(t,X[:,2])
plt.legend(["a(t)","b(t)","c(t)"])
plt.xlabel("t (s)")
plt.ylabel("Concentrations (mol/L)")
0.0010
a(t)
b(t)
c(t)
0.0008

Concentrations (mol/L)
0.0006

0.0004

0.0002

0.0000
0 100000 200000 300000 400000 500000 600000 700000 800000 900000
t (s)

# Le maximum de b :
print X[:,1].max()

4.47434545101e-05
Numériquement, on a bien c = a(0) dans l’état final et a = 0. Représentons graphiquement la somme
des concentrations :

plt.plot(t,X[:,0])
plt.plot(t,X[:,1])
plt.plot(t,X[:,2])
plt.plot(t,X[:,0]+X[:,1]+X[:,2])
plt.legend(["a(t)","b(t)","c(t)","a+b+c"])
plt.box(False)
plt.axhline(y=0,color=’k’)
plt.axvline(x=0,color=’k’)
plt.xlabel("t (s)")
plt.ylabel("Concentrations (mol/L)")

0.0010
a(t)
b(t)
c(t)
0.0008 a+b+c
Concentrations (mol/L)

0.0006

0.0004

0.0002

0.0000
0 100000 200000 300000 400000 500000 600000 700000 800000 900000
t (s)
TP 24 : Équations différentielles d’ordre 2
Exercice 1 Projectile dans le champ de pesanteur terrestre avec frottements quadratiques : Un mobile
de masse m = est lancé de la position x = 0, y = h = 1 m avec une vitesse initiale de norme v 0 =
27.7 m/s dont la direction fait un angle α = π/4 avec l’horizontale. La trajectoire du mouvement est
décrite par les équations différentielles :

s
¶2 ¶2
d2 x k 2 dx
#–
dx dy v0
µ µ
+ + =0
dt 2 m dt dt dt
s
¶2 ¶2 α
d2 y k 2 dy dx dy
µ µ
+ + = −g
dt 2 m dt dt dt h
O
x ¸
dx dy
·
y
On rappelle que g = 9.81 m/s2 . On pose v x = et v y = et on note X = vx .
dt dt vy
(a) Vérifier que x, y, v x , v y sont solution d’un système d’équations différentielles de la forme :

 dx
= ···


dt



 dy = · · ·




dt
 dv x
= ···


dt



dv y




 = ···
dt
Déterminer également la condition initiale associée.
(b) Définir la fonction F(X,t,m,k2) qui décrit ce système d’équations différentielles.
(c) Résoudre numériquement ce système et représenter graphiquement sur le même dessin les
trajectoires obtenues pour m = 0.45 kg, k 2 = 8.9 · 10−3 kg/m (ballon de football) puis pour
m = 5 · 10−3 kg, k 2 = 1.6 · 10−3 kg/m (volant de badminton).
(d) Dans les deux situations précédentes, représenter graphiquement la norme de la vitesse en
fonction du temps.
(e) On prend m = 0.45 kg, k 2 = 8.9 · 10−3 kg/m. Représenter simultanément les trajectoires pour
plusieurs valeurs de l’angle α.

Exercice 2 Modélisation d’une suspension de véhicule : On modélise une suspension d’un véhicule
par un ressort de raideur k et un amortisseur de coefficient d’amortissement c, montés en parallèles.
On ramène le poids du véhicule à une masse globale m.
On prendra :

m Habitacle m = 100 kg
s(t )
c = 1.13 · 103 N · s · m−1

Ressort : k Amortisseur : c k = 80 · 103 N · m−1


s
k
ω0 =
e(t ) m
Châssis

T=
ω0

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp24.pdf
On note respectivement e(t ) et s(t ) les déplacements verticaux du châssis et de l’habitacle par rap-
port à la position d’équilibre du système. On supposera que le véhicule se déplace horizontalement
à vitesse constante. On étudie la situation où l’axe de la roue est légèrement excentré par rapport à
son centre ; ceci provoque un déplacement e(t ) du châssis en fonction de la vitesse de rotation de
la roue ω : e(t ) = e 0 sin(ωt ) avec e 0 = 0.05 m. On veut modéliser la réponse en déplacement verti-
cal de l’habitacle en fonction de la pulsation ω. Le principe fondamental de la dynamique permet
d’obtenir l’équation différentielle :

d2 s d(s − e)
m +c + k(s − e) = 0
dt 2 dt
c’est à dire :

d2 s ds de
m +c + ks = ke + c
dt 2 dt dt

On prendra comme condition initiale s(0) = 0 et s 0 (0) = 0.


ds
(a) On pose v = , écrire le système différentiel d’ordre 1 satisfait par les fonction s et v.
dt
(b) Représenter graphiquement s en fonction de t sur l’intervalle [0, 5T ] pour ω = ω0 /2, ω = 2ω0
et ω = 27.7 rad/s.
TP 24 : Équations différentielles d’ordre 2

Éléments de correction

Ex. 1 : (a) On obtient le système d’équations différentielles :


dx
= vx



dt



dy


= vy


dy

dv x k2 q
= − v x v x2 + v 2y



dt m



dv y

k2 q 2

= − v y v x + v 2y − g



dt m

Avec la condition initiale x(0) = 0, y(0) = h, v x (0) = v 0 cos α et v y (0) = v 0 sin α.


(b)

from math import *


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

h=1
v0=27.7
alpha=pi/4
g=9.81

def F(X,t,m,k2):
x=X[0]
y=X[1]
vx=X[2]
vy=X[3]
xprim=vx
yprim=vy
vxprim=-k2/m*vx*sqrt(vx**2+vy**2)
vyprim=-k2/m*vy*sqrt(vx**2+vy**2)-g
return [xprim,yprim,vxprim,vyprim]
(c)

t=np.linspace(0,10,100)
X1=odeint(F,[0,h,v0*cos(alpha),v0*sin(alpha)],t,args=(0.45,8.9e-3))
X2=odeint(F,[0,h,v0*cos(alpha),v0*sin(alpha)],t,args=(5e-3,1.6e-3))
plt.plot(X1[:,0],X1[:,1])
plt.plot(X2[:,0],X2[:,1])
plt.axhline(y=0,color=’k’)
20

−20

−40

−60

−80

−100

−120

−140
0 10 20 30 40 50 60

(d) Les composantes v x et v y correspondent aux deux dernières colonnes des matrices X 1 et X 2
donc :

plt.plot(t,np.sqrt(X1[:,2]**2+X1[:,3]**2))
plt.plot(t,np.sqrt(X2[:,2]**2+X2[:,3]**2))

30

25

20

15

10

0
0 2 4 6 8 10

(e) On a pris α ' 0.78. Prenons par exemple α = 0.2, 0.3, . . . , 1.5 (la courbe pour α = 0.1 est tracée
en rouge). Notons que le changement sur α ne change que la condition initiale :

for k in range(2,16):
alpha=float(k)/10
couleur="r" if k==2 else "b"
X=odeint(F,[0,h,v0*cos(alpha),v0*sin(alpha)],t,args=(0.45,8.9e-3))
plt.plot(X[:,0],X[:,1],couleur)
plt.axhline(y=0,color=’k’)
50

−50

−100

−150

−200
0 10 20 30 40 50 60 70

Ex. 2 : (a) On obtient le système :


ds
=v



dt
dv 1 de
µ ¶
ke + c − c v − ks


 =
dt m dt

(b)

from math import *


import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

m=100.0
c=1.13e3
k=80e3
w0=sqrt(k/m)
e0=0.05
T=2*pi/w0

def F(X,t,w):
s=X[0]
v=X[1]
sprim=v
vprim=1/m*(k*e0*sin(w*t)+c*w*e0*cos(w*t)-c*v-k*s)
return [sprim,vprim]
t=np.linspace(0,5*T,100)
plt.clf()
for w in [w0/2,27.7,2*w0]:
X=odeint(F,[0,0],t,args=(w,))
plt.plot(t,X[:,0])
plt.legend(["w0/2","27.7","2w0"])
0.15
w0/2
27.7
2w0
0.10

0.05

0.00

−0.05

−0.10

−0.15
0.0 0.2 0.4 0.6 0.8 1.0 1.2
TP 25 : Régressions linéaires
Exercice 1 Mesure du pas d’un réseau : On réalise une diffraction par un réseau de pas a. On
rappelle la formule du réseau :

λ
sin i = k
a
où i est l’angle sous lequel est vue la raie de longueur d’onde λ et k est l’ordre du spectre. On réalise
les mesures suivantes pour le spectre d’ordre 1 (k = 1) avec une lampe au cadmium :

Couleur Rouge Vert Bleu Indigo


Longueur d’onde (nm) 643.8 508.6 480.0 467.8
i (degrés) 22.9 17.9 16.9 16.4

On définira :

lambda_mes=np.array([643.8,508.6,480.0,467.8])
i_mes=np.array([22.9,17.9,16.9,16.4])

(a) Déterminer le pas du réseau par une régression appropriée.


(b) En déduire le nombre de traits du réseau par millimètre.
(c) Sur le même dessin, représenter graphiquement λ en fonction de i pour k = 1 et la valeur de
a obtenue à la question précédente ainsi que les mesures effectuées.
(d) Pour une lampe au sodium, on mesure i = 20.8◦ pour la raie double du sodium avec le même
réseau. Déterminer la longueur d’onde correspondant à cette raie double.

Exercice 2 Réaction chimique : On considère la réaction

t (s) C (mol · L−1 )


Fe2+ + Co3+ = Fe3+ + Co2+ 20 2.78 · 10−4
40 1.92 · 10−4
C’est une réaction d’ordre 2 et l’évolution de la concentration en ions Fe2+ , 60 1.47 · 10−4
notée C , est modélisée par une relation du type : 80 1.19 · 10−4
100 1.0 · 10−4
1
C (t ) = 120 0.86 · 10−4
at + b

On donne ci-dessus des mesures expérimentales de C en fonction du temps et on veut déterminer


les constantes a et b associées.
(a) Définir les tableaux t_mes et C_mes correspondant aux mesures effectuées.
(b) Effectuer une regression linéaire appropriée et determiner des valeurs approchées de a et b.
Donner le coefficient de corrélation.
(c) Représenter sur le même dessin la fonction C du modèle (pour les valeurs a et b obtenues)
ainsi que les mesures effectuées.
(d) Déterminer la concentration à t = 0.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp25.pdf
TP 25 : Régressions linéaires

Éléments de correction
Ex. 1 :

from math import *


import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import linregress

lambda_mes=np.array([643.8,508.6,480.0,467.8])
i_mes=np.array([22.9,17.9,16.9,16.4])

i_radians=i_mes*pi/180

Comme λ = a sin i dans le cadre de l’expérience, on obtient a en effectuant une regression linéaire
en prenant les valeurs de sin i en abscisse et les valeurs de λ en ordonnée :

(a,b,rho,_,_)=linregress(np.sin(i_radians),lambda_mes)
print "a=%f nm, rho=%f" % (a,rho)

a=1654.676349 nm, rho=0.999965

n=1/(a*10**(-6))
print "Nombre de traits / mm : %f" % n

Nombre de traits / mm : 604.347793

t=np.linspace(0,pi/4,100)
plt.plot(t,a*np.sin(t),’r-’)
plt.plot(i_radians,lambda_mes,’bo’)
plt.xlabel("i (rad)")
plt.ylabel("lambda (nm)")
plt.legend([u"Modèle (rho=%f)" % rho,"Mesures"],loc="lower right")

1200

1000

800
lambda (nm)

600

400

200
Modèle (rho=0.999965)
Mesures
0
0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
i (rad)

Pour la lampe au sodium, on utilise la relation λ = a sin i avec i = 20.8◦ :


lambda_sodium=a*sin(20.8*pi/180)
print "Longueur d’onde de la raie double : %f" % lambda_sodium

Longueur d’onde de la raie double : 587.587092

Ex. 2 :

from math import *


import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import linregress

t_mes=np.array([20,40,60,80,100,120])
C_mes=np.array([2.78e-4,1.92e-4,1.47e-4,1.19e-4,1.0e-4,0.86e-4])
On définit le tableau y=1/C_mes, on effectue alors la régression linéaire en prenant t_mes comme
abscisses et y pour ordonnées :

y=1/C_mes
(a,b,rho,_,_)=linregress(t_mes,y)
print "a=%f, b=%f, rho=%f" % (a,b,rho)
print "C(0)=%e mol/L" % b**(-1)

a=80.185091, b=1993.617811, rho=0.999996 C(0)=5.016007e-04 mol/L

t=np.linspace(0,140,100)
plt.plot(t,1/(a*t+b),’r-’)
plt.plot(t_mes,C_mes,’bo’)
plt.xlabel("t (s)")
plt.ylabel("C (mol/L)")
plt.legend([u"Modèle (rho=%f)" % rho,"Mesures"])

0.0006
Modèle (rho=0.999996)
Mesures
0.0005

0.0004
C (mol/L)

0.0003

0.0002

0.0001

0.0000
0 20 40 60 80 100 120 140
t (s)
TP 26 : Calcul numérique – TP noté

Avant tout :
• Lancer S PYDER.
• Aller dans le menu Fichier, choisir Nouveau fichier.
• Aller dans le menu Fichier, choisir Enregistrer sous.
• Sélectionner le répertoire Documents, créer un nouveau dossier intitulé Devoirs et
sélectionner ce dossier.
• Créer un nouveau dossier intitulé BOISSEAUA et sélectionner ce dossier.
• Enregistrer votre fichier en lui donnant le nom tp_votrenom.py (où votrenom est à
remplacer par votre nom de famille).
Vous ferez TOUS LES EXERCICES de la feuille de TP DANS CE FICHIER. en signalant claire-
ment où se trouve chaque exercice par des commentaires dans le fichier.

Exercice 1 Résolution d’une équation numérique : Utiliser P YTHON pour déterminer une solution
approchée de l’équation

1
ln(x) =
x

Le programme devra afficher la valeur obtenue dans la console.

Exercice 2 Une équation différentielle d’ordre 1 : On considère le problème de Cauchy :



 dy = −t y + cos(t )


dt
 y(0) = 1

Représenter graphiquement la solution de ce problème sur l’intervalle [0, 5].

Exercice 3 Une équation différentielle d’ordre 2 : On considère l’équation différentielle :

y 00 + m y 0 + y = c

où m et c sont des paramètres réels.


(a) Traduire cette équation différentielle en un système en appliquant la méthode vue en classe.
(b) On travaille sur l’intervalle [0, 1]. Représenter sur le même dessin :
• La solution correspondant aux conditions initiales y(0) = 0, y 0 (0) = 0 pour les paramètres
(m, c) = (1, 2).
• La solution correspondant aux conditions initiales y(0) = 0, y 0 (0) = 1 pour les paramètres
(m, c) = (1, −2).

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp26.pdf
Exercice 4 Propagation d’une épidémie / Système d’équations différentielles : On propose le modèle
simple suivant représentant la propagation d’une épidémie (appelé modèle SIR) :
— La population est divisé en trois groupes : sains (S), infectés (I) et résistants (R), dont les effec-
tifs au temps t sont notés respectivement s(t ), i (t ) et r (t ) ;
— Les fonctions s, i et r sont solution d’un système d’équations différentielles du type :
 0
 s (t ) = −bs(t )i (t )
i 0 (t ) = bs(t )i (t ) − ci (t )
r 0 (t ) = ci (t )

Le coefficient b est un taux de contagion entre un individu sain et un individu infecté et le


coefficient c est un taux de guérison d’un individu infecté ;
— On prendra comme conditions initiales s(0) = 0.99, i (0) = 0.01 et r (0) = 0.
Représenter graphiquement les fonctions s et i pour t ∈ [0, 50] et (b, c) = (0.9, 0.1). Faire de même
lorsque (b, c) = (0.6, 0.4).
TP 27 : Introduction à la structure de graphe
¦ Un graphe orienté G est défini à l’aide d’un ensemble de sommets (chaque sommet est représenté
par un nombre) et un ensemble d’arêtes reliant deux sommets et représentées par des flèches. Voici
un premier exemple de graphe, noté G 1 :

2
0 1 3

On décrira un tel graphe en P YTHON en donnant la liste de ses arêtes. Par exemple le graphe G 1 est
représenté par la liste :

G1=[[0,1],[1,0],[1,2],[2,3],[3,1]]

Une arête reliant le sommet s 1 au sommet s 2 (dans cet ordre) est représentée par la liste [s 1 , s 2 ]. On
appelle taille du graphe le nombre de sommets de ce graphe et on conviendra que si G est un graphe
de taille n, alors :
• Ses sommets sont 0, 1, . . . , n − 1 ;
• Tout sommet du graphe apparait au moins dans une arête (comme point de départ ou d’arri-
vée).

Question 1 : Quelle est la taille du graphe G 1 ?


Question 2 : On considère le graphe suivant, noté G 2 :

2
4 3

0 5 1

Donner la taille de ce graphe et sa représentation en P YTHON sous forme d’une liste G2.

Question 3 : Écrire une fonction taille(G) qui détermine la taille du graphe G (G est la liste des
arêtes).

Question 4 : Si G est un graphe de taille n, on appelle matrice d’adjacence de G la matrice M de


taille n×n telle que M [i , j ] = 1 si il y a dans G une arête allant du sommet i au sommet j et M [i , j ] = 0
sinon.
(a) Écrire une fonction matrice(G) qui retourne la matrice d’adjacence de G. Vérifier le résultat
obtenu pour les graphes G 1 et G 2 .
(b) On admet le résultat suivant : si M est la matrice d’adjacence de G, alors le nombre de chemins
partant d’un sommet i et allant à un sommet j et constitués de k arêtes est le coefficient (i , j )
de la matrice M k . Application : combien y a-t-il de chemins de longueur 8 partant du sommet
0 et arrivant au sommet 1 dans le graphe G 1 ? Expliciter ces chemins.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp27.pdf
¦ On considère le problème suivant : dans un tableur, certaines cellules se calculent en fonction
des autres et, lorsqu’une valeur change, il faut recalculer les valeurs des cellules. Cependant, l’ordre
dans lequel on effectue ce calcul doit être tel que, si une cellule c 1 dépend de la valeur d’une cellule
c 2 , alors c 2 doit être recalculée avant c 1 .

Question 5 : On considère le frament de feuille de calcul suivant :


A B C
1 3.2 =B3+C3 =A3+1
2 =B1+C3 0.2 =A3+2
3 =0.9*A2 0.3 0.6

et on s’intéresse essentiellement aux cellules A2, A3, B1, C1, C2.


(a) Donner un ordre de calcul légitime pour ces cellules.
(b) Expliquer comment représenter les dépendances entres ces cellules à l’aide d’un graphe que
l’on notera G 3 .

Question 6 : Soit un graphe G. On considère l’algorithme suivant :


• On note S la liste contenant tous les sommets de G et T la liste vide ;
• On retire le premier élément de S. On le note a et la liste S contient maintenant un élément
de moins. Si il existe un élément b dans S tel que [a,b] soit une arête de G, alors on remet a
à la lin de S, à la fin. Sinon on met a à la fin de T ;
• On répète l’étape précédente tant que la liste S n’est pas vide.
(a) Que peut-on dire de la liste T obtenue une fois que l’algorithme est terminé ?
(b) Mettre en œuvre cet algorithme sous la forme d’une fonction tri(G) qui retourne la liste T
obtenue à la fin.
(c) Que se passe-t-il si on applique cette fonction au graphe G 1 (ne pas le faire !) ?

Question 7 : Expliquer comment la fonction précédente permet de résoudre le problème de l’ordre


de recalcul des cellules d’une feuille de calcul.

Notes
¦ Les graphes servent à modéliser de nombreux problèmes : réseaux de communication, relation
de dépendance, systèmes de transitions etc. C’est pourquoi de nombreux problèmes sur les graphes
ont été étudiés. Le problème que l’on vit de considérer est celui du tri topologique. Bien que l’algo-
rithme proposé dans ce TP soit correct, il est cependant peu permormant. Quelques liens :

www-sop.inria.fr/members/Frederic.Havet/FeteScience/Graphes-reseaux.pdf
https://fr.wikipedia.org/wiki/Théorie_des_graphes
https://fr.wikipedia.org/wiki/Tri_topologique
TP 27 : Introduction à la structure de graphe

Éléments de correction
Q. 1 : Le graphe G 1 est de taille 4.

Q. 2 : Le graphe G 2 est de taille 6 et on le définit en P YTHON avec la liste :

G2=[[1,0],[0,4],[4,3],[3,0],[3,5],[3,2],[2,3],[2,5],[5,2],[2,1],[1,5],[5,1]]

Q. 3 : Avec les hypothèses faites sur les graphes considérées, la taille de G et m + 1 où m est le plus
grand nombre apparaissant des la liste G. Ainsi :

def taille(G):
m=0
for a in G:
# a est une arête de G,
# donc une liste à 2 éléments a[0] et a[1]
if a[0]>m:
m=a[0]
if a[1]>m:
m=a[1]
return m+1
print taille(G1)

print taille(G2)

Q. 4 :

import numpy as np
def matrice(G):
n=taille(G)
M=np.zeros((n,n))
for a in G:
M[a[0],a[1]]=1
return M
M1=matrice(G1)
print M1

[[ 0. 1. 0. 0.] [ 1. 0. 1. 0.] [ 0. 0. 0. 1.] [ 0. 1. 0. 0.]]

M2=matrice(G2)
print M2

[[ 0. 0. 0. 0. 1. 0.] [ 1. 0. 0. 0. 0. 1.] [ 0. 1. 0. 1. 0. 1.] [ 1. 0. 1.


0. 0. 1.] [ 0. 0. 0. 1. 0. 0.] [ 0. 1. 1. 0. 0. 0.]]

print np.linalg.matrix_power(M1,8)[0,1]

3.0
Il y a donc 3 chemins de taille 8 allant de 0 à 1 dans G 1 :

0, 1, 2, 3, 1, 0, 1, 0, 1
0, 1, 0, 1, 2, 3, 1, 0, 1
0, 1, 0, 1, 0, 1, 2, 3, 1

Q. 5 : Un ordre possible : B1, A2, A3, C1, C2. On peut modéliser les dépendances entre cellules par
un graphe orienté dans lequel les sommets sont les cellules considérées et une arête de c 1 à c 2 signi-
fie que la valeur de c 1 dépend de celle de c 2 . Sur l’exemple considéré, on obtient le graphe :

C1

A3 A2 B1

C2

ou alors, en utilisant la convention de numérotation des sommets à partir de 0 :

3
1 0 2
4

Q. 6 : La liste T obtenue à la fin contient tous les sommets du graphe G rangés dans un ordre tel que
si il y a une arête allant du sommet c 1 au sommet c 2 dans G, alors c 2 apparait avant c 1 dans la liste
T.

def tri(G):
n=taille(G)
S=range(n)
T=[]
while S!=[]:
c=S[0] # On prend le 1er élément de S
S=S[1:] # et on le retire
remettre=False
for x in S:
if [c,x] in G:
remettre=True
if remettre:
S.append(c) # On remet c à la fin de S
else:
T.append(c)
return T
G3=[[3,1],[4,1],[1,0],[0,2]]
print tri(G3)

[2, 0, 1, 3, 4]
TP 28 : Introduction aux BDD

Explorer une base de données


¦ On va utiliser pour cela le logiciel SQL ITEMAN. Tout d’abord :
• Lancer SQL ITEMAN ;
• Aller dans Fichier/Ouvrir et ouvrir le fichier videoclub.db3.
On observe la disposition suivante :

¦ Il y a essentiellement 3 zones :
• À gauche, la zone Schema, elle va permettre de parcourir la base de données et ses différentes
tables ;
• En bas à droite, la zone Vue, elle va afficher le contenu des différentes tables. On restera tou-
jours sur l’onglet Vue complète ;
• En haut à droite, le cadre SQL (voir utilisation plus loin).

¦ Double cliquer sur Tables dans la zone Schema. Noter les noms des différentes tables qui appa-
raissent. Double cliquer sur chaque table et observer son contenu qui apparait dans la zone Vue.

Question 1 : Donner la liste des tables qui composent cette base de données et pour chacune des
ces tables, donner son schéma. Mettre en évidence (par exemple avec différentes couleurs) les clés
primaires et les clés étrangères qui apparaissent.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp28.pdf
Question 2 : On considère la table emprunte. Chercher les emprunts pour lesquels le numéro de
client est égal à 66. Pour ces emprunts, donner le nom du client et le titre du film emprunté.

Question 3 : En cherchant dans les différentes tables, déterminer les noms des clients qui ont
emprunté le film HOT SHOTS 2.

Introduction au langage SQL


¦ Dans la zone SQL, taper

SELECT numClient, dateEmprunt FROM historique

cliquer ensuite sur Ï, observer le résultat dans la zone Vue. Faire de même avec la commande :

SELECT * FROM client WHERE 5<=numClient AND numClient<=10

On peut également croiser des tables (ceci s’appelle une jointure) :

SELECT numInventaire, titre_VO FROM film


JOIN exemplaire ON film.idFilm=exemplaire.idFilm

Question 4 :
(a) Taper une commande SQL permettant de lister les emprunts pour lesquels le numéro de client
est égal à 66.
(b) Pour ces emprunts, faire afficher également le nom du client.
(c) Faire également afficher le titre du film emprunté.
Question 5 :
(a) Taper une commande SQL permettant de lister le film pour lequel idFilm vaut 41.
(b) Pour ce film, afficher également la valeur de numInventaire.
(c) Faire également afficher les noms des clients qui ont emprunté ce film.

Construction d’une base de données


¦ Aller dans Fichier, choisir Nouveau et choisir comme nom commandes.sqlite. En utilisant l’in-
terface graphique :
• Créer une table Articles(Reference INTEGER, Designation TEXT) ;
• Créer une table Stocks(Reference INTEGER, Qte INTEGER) ;
• Créer une table Fournisseur(Reference INTEGER, Nom TEXT, Adresse TEXT) ;
• Toujours en utilisant l’interface graphique, remplir les trois tables de la manière suivante :

Articles Stocks Fournisseur


Reference Designation Reference Qte Reference Nom Adresse
12 Stylo 12 56 12 BIC Clichy
138 Encre 138 250 138 Waterman Paris
acteur client
idPersonne idFilm numClient prenom nom ville credit bonus
emprunte exemplaire
numClient numInventaire dateEmprunt numInventaire idFilm format
film
idFilm titre_VO titre_VF annee pays
historique personne
numClient numInventaire dateEmprunt dateRetour idPersonne nom
Emprunts du client 66
realisateur tarif numClient numInventaire dateEmprunt
idPersonne idFilm format prix 66 45 2010-6-1
66 357 2010-6-1

numClient prenom nom ville credit bonus


66 Julie LUCAS Épinay-sur-Orge 10 2

numInventaire idFilm format


45 38 DVD
357 397 DVD

idFilm titre_VO titre_VF annee pays


38 The Grissom gang Pas d’orchidées pour Miss Blandish 1971 USA
397 The Wild one L’Equipée sauvage 1952 USA
Le film HOT SHOTS 2
idFilm titre_VO titre_VF annee pays numInventaire idFilm format
3 HOT SHOTS 2 1993 USA 1 3 DVD

numClient numInventaire dateEmprunt


4 1 2010-6-1

numClient numInventaire dateEmprunt dateRetour


4 1 2010-6-1

numClient prenom nom ville credit bonus


4 Evan PETIT Arpajon 3 0
TP 29 : Interroger une BDD

Interroger avec SQLiteman


Exercice 1 Base de données Videoclub.db3 : Lancer le logiciel SQL ITEMAN et ouvrir cette base
de données. On rappelle la forme des différentes tables qui la constituent :

acteur client
idPersonne idFilm numClient prenom nom ville credit bonus
emprunte exemplaire
numClient numInventaire dateEmprunt numInventaire idFilm format
film
idFilm titre_VO titre_VF annee pays
historique personne
numClient numInventaire dateEmprunt dateRetour idPersonne nom
realisateur tarif
idPersonne idFilm format prix

Pour chacune des questions suivantes, on déterminera la réponse à l’aide d’une requête SQL appro-
priée (noter la requête sur la feuille) :
(a) Déterminer les enregistrements de la table exemplaire dont le format est Blu-ray.

(b) Déterminer les titres (en VO) des films qui sont au format Blu-ray.

(c) Déterminer les emprunts qui correspondent à des films au format Blu-ray.

(d) Déterminer les noms des clients qui ont emprunté des films au format Blu-ray.

Exercice 2 Base de données poteries.sqlite : Ouvrir cette base de données dans le logiciel
SQL ITEMAN. Elle n’est constituée que d’une seule table qui répertorie les proportions de différents
métaux (Al, Fe, Mg, Ca et Na) présents dans des échantillons de poteries trouvés sur différents sites
archéologiques désignés par une lettre (L, C , I ou A).
(a) Donner le schéma de cette table.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp29.pdf
(b) Écrire une requête SQL permettant de sélectionner les enregistrements qui correspondent au
site L uniquement.

(c) Écrire une requête SQL permettant d’afficher uniquement les champs Al, Fe et Site unique-
ment.

(d) Déterminer la moyenne des valeurs du champ Al pour le site L, puis faire de même pour les
autres sites.

Interroger une base de données dans un programme Python


Exercice 3 :

B Si ce n’est pas déjà fait, pensez à déplacer le fichier poteries.sqlite dans votre répertoire
TPinfo.

À l’intérieur d’un programme P YTHON, on peut accéder à la base de données poteries.sqlite


avec :

import sqlite3
bdd=sqlite3.connect(’poteries.sqlite’)

Écrire un programme P YTHON qui réalise les tâches suivantes :


(a) Obtenir la liste des moyennes des proportions des différents métaux pour le site L.
(b) Obtenir les enregistrements pour lesquels la valeur de Al est à 10% de la moyenne obtenue à
la question précédente.
On désire savoir si les proportions de Al et Fe dans un échantillon de poterie peuvent permettre de
retrouver de quel site il est issu.
(c) Construire la matrice ML constituée de deux colonnes qui représentent les proportions de Al
et Fe pour le site L. Faire de même pour les autres sites (on notera les matrices MA, MI et MC).
(d) Tracer en bleu les points dont les coordonnées correspondent aux proportions de Al (en abs-
cisses) et Fe (en ordonnées) pour le site L. Faire de même pour les autres sites en choisissant
des couleurs différentes.
(e) Conclusion ?
TP 29 : Interroger une BDD

Éléments de correction

Ex. 1 : Enregistrements dont le format est Blu-ray (on n’affiche que les 10 premiers) :

import sqlite3
bdd=sqlite3.connect(’/home/ba/Enseignement/PC/Python/Data/Videoclub.db3’)
requete="""
SELECT * FROM exemplaire WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall()[0:10]:
print e

(3, 5, u'Blu-ray')
(12, 12, u'Blu-ray')
(32, 30, u'Blu-ray')
(36, 31, u'Blu-ray')
(43, 37, u'Blu-ray')
(51, 41, u'Blu-ray')
(72, 69, u'Blu-ray')
(75, 77, u'Blu-ray')
(78, 79, u'Blu-ray')
(82, 83, u'Blu-ray')

Les titres des films qui sont au format Blu-ray (on n’affiche que les 10 premiers) :

requete="""
SELECT titre_VO FROM film
JOIN exemplaire
ON film.idFilm=exemplaire.idFilm
WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall()[0:10]:
print e

(u'Ruthless people',)
(u'Rue du Bac',)
(u'What ever happened to Baby Jane?',)
(u'Four for Texas',)
(u'Too late for heroes',)
(u'The Mean Machine or the longest yard',)
(u'The Uninvited',)
(u'Take the money and run',)
(u'Sleeper',)
(u'Manhattan',)

Les emprunts correspondant à des films qui sont au format Blu-ray :


requete="""
SELECT numClient, emprunte.numInventaire, dateEmprunt
FROM emprunte
JOIN exemplaire
ON emprunte.numInventaire=exemplaire.numInventaire
WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall():
print e

(19, 411, u'2010-6-1')


(63, 75, u'2010-6-1')
(15, 102, u'2010-6-1')
(30, 166, u'2010-6-1')
(15, 143, u'2010-6-1')

Les noms des clients ayant emprunté des films qui sont au format Blu-ray :

requete="""
SELECT nom, prenom FROM client
JOIN emprunte
ON client.numClient=emprunte.numClient
JOIN exemplaire
ON emprunte.numInventaire=exemplaire.numInventaire
WHERE format=’Blu-ray’
"""
for e in bdd.execute(requete).fetchall():
print e
bdd.close()

(u'FOURNIER', u'Romain')
(u'GIRAUD', u'Louise')
(u'ROUX', u'Jules')
(u'ANDRE', u'Baptiste')
(u'ROUX', u'Jules')

Ex. 2 : Les enregistrements correspondant au site L :

bdd=sqlite3.connect(’/home/ba/Enseignement/PC/Python/Data/poteries.sqlite’)
requete="""
SELECT * FROM poteries WHERE Site=’L’
"""
for e in bdd.execute(requete).fetchall():
print e
(14.4, 7.0, 4.3, 0.15, 0.51, u'L')
(13.8, 7.08, 3.43, 0.12, 0.17, u'L')
(14.6, 7.09, 3.88, 0.13, 0.2, u'L')
(11.5, 6.37, 5.64, 0.16, 0.14, u'L')
(13.8, 7.06, 5.34, 0.2, 0.2, u'L')
(10.9, 6.26, 3.47, 0.17, 0.22, u'L')
(10.1, 4.26, 4.26, 0.2, 0.18, u'L')
(11.6, 5.78, 5.91, 0.18, 0.16, u'L')
(11.1, 5.49, 4.52, 0.29, 0.3, u'L')
(13.4, 6.92, 7.23, 0.28, 0.2, u'L')
(12.4, 6.13, 5.69, 0.22, 0.54, u'L')
(13.1, 6.64, 5.51, 0.31, 0.24, u'L')
(12.7, 6.69, 4.45, 0.2, 0.22, u'L')
(12.5, 6.44, 3.94, 0.22, 0.23, u'L')
On sélectionne les champs Al, Fe et Site (on affiche uniquement les 10 premiers enregistrements) :

requete="""
SELECT Al, Fe, Site FROM poteries
"""
for e in bdd.execute(requete).fetchall()[0:10]:
print e

(14.4, 7.0, u'L')


(13.8, 7.08, u'L')
(14.6, 7.09, u'L')
(11.5, 6.37, u'L')
(13.8, 7.06, u'L')
(10.9, 6.26, u'L')
(10.1, 4.26, u'L')
(11.6, 5.78, u'L')
(11.1, 5.49, u'L')
(13.4, 6.92, u'L')
Moyenne du champ Al pour le site L puis pour les autres sites :

requete="""
SELECT AVG(Al) FROM poteries WHERE Site=’L’
"""
print bdd.execute(requete).fetchall()

[(12.564285714285713,)]
Pour les quatre sites :

for site in [’L’,’I’,’A’,’C’]:


requete="""
SELECT AVG(Al) FROM poteries WHERE Site=’%s’
""" % site
print "Moyenne Al pour le site %s" % site
print bdd.execute(requete).fetchone()[0]
bdd.close()
Moyenne Al pour le site L 12.5642857143 Moyenne Al pour le site I 18.18 Moyenne
Al pour le site A 17.32 Moyenne Al pour le site C 11.7

Ex. 3 : Les moyennes des proportions des différents métaux pour le site L :

bdd=sqlite3.connect(’/home/ba/Enseignement/PC/Python/Data/poteries.sqlite’)
requete="""
SELECT AVG(Al), AVG(Fe), AVG(Mg), AVG(Ca), AVG(Na)
FROM poteries
WHERE Site=’L’
"""
print bdd.execute(requete).fetchall()

[(12.564285714285713, 6.372142857142856, 4.826428571428572, 0.20214285714285718,


0.2507142857142857)]
On récupère la valeur moyenne de Al pour le site L :

Moy_L=bdd.execute(requete).fetchall()[0]
Moy_L_Al=Moy_L[0]
print Moy_L_Al

12.5642857143
On sélectionne les enregistrements pour lesquels Al est situé à ±10% de cette valeur moyenne :

requete="""
SELECT * FROM poteries
WHERE %f<=Al and Al<=%f
""" % (Moy_L_Al*0.9,Moy_L_Al*1.1)
for e in bdd.execute(requete).fetchall():
print e

(13.8, 7.08, 3.43, 0.12, 0.17, u'L')


(11.5, 6.37, 5.64, 0.16, 0.14, u'L')
(13.8, 7.06, 5.34, 0.2, 0.2, u'L')
(11.6, 5.78, 5.91, 0.18, 0.16, u'L')
(13.4, 6.92, 7.23, 0.28, 0.2, u'L')
(12.4, 6.13, 5.69, 0.22, 0.54, u'L')
(13.1, 6.64, 5.51, 0.31, 0.24, u'L')
(12.7, 6.69, 4.45, 0.2, 0.22, u'L')
(12.5, 6.44, 3.94, 0.22, 0.23, u'L')
(11.8, 5.44, 3.94, 0.3, 0.04, u'C')
(11.6, 5.39, 3.77, 0.29, 0.06, u'C')
On construit les matrices ML, MA, MC et MI :
import numpy as np
ML=np.array(bdd.execute("""
SELECT Al,Fe FROM poteries WHERE Site=’L’
""").fetchall())
MA=np.array(bdd.execute("""
SELECT Al,Fe FROM poteries WHERE Site=’A’
""").fetchall())
MI=np.array(bdd.execute("""
SELECT Al,Fe FROM poteries WHERE Site=’I’
""").fetchall())
MC=np.array(bdd.execute("""
SELECT Al,Fe FROM poteries WHERE Site=’C’
""").fetchall())
Représentation graphique :

import matplotlib.pyplot as plt


plt.plot(ML[:,0],ML[:,1],’bo’)
plt.plot(MA[:,0],MA[:,1],’ro’)
plt.plot(MC[:,0],MC[:,1],’go’)
plt.plot(MI[:,0],MI[:,1],’co’)
plt.xlabel(’Al’)
plt.ylabel(’Fe’)
plt.legend([’L’,’A’,’C’,’I’])

8
L
A
7 C
I
6

4
Fe

0
10 12 14 16 18 20 22
Al

Il semble que le couple (Al, Fe) permette de distinguer entre les échantillons issus des sites L et C
d’une part et A et I d’autre part.
TP 30 : Exemple d’utilisation d’une BDD

¦ On s’intéresse au fonctionnement d’une éolienne et on veut en particulier étudier comment esti-


mer l’énergie produite en un an. L’éolienne est caractérisée par un certain nombre de grandeurs et
on utilisera les valeurs numériques suivantes :

S = 9.08 m2 Surface utile de l’éolienne


C p = 0.3 Coefficient de performance
Vmin = 4.0 ms−1 Vitesse minimale de fonctionnement de l’éolienne
Vmax = 25.0 ms−1 Vitesse maximale de fonctionnement
Vnom = 12.0 ms−1 Vitesse nominale de fonctionnement
Vmoy = 7.41 ms−1 Vitesse moyenne du vent (à l’endroit où est située l’éolienne)
ρ = 1.25 kg · m−3 Masse volumique de l’air

Calcul de la puissance fournie par l’éolienne


¦ On rencontre plusieurs difficultés pour mener ce calcul. Tout d’abord, l’énergie produite par l’éo-
lienne n’est pas simplement proportionnelle à la vitesse du vent. En effet, l’éolienne a besoin que le
vent ait une vitesse minimale pour démarrer et à partir d’une vitesse du vent trop élevée, elle s’ar-
rête car son fonctionnement deviendrait risqué. Ensuite, à partir du moment où le vent dépasse la
vitesse nominale, la puissance fournie par l’éolienne ne varie plus.

Question 1 : Si la vitesse du vent est v, on note P (v) la puissance obtenue à la sortie de la turbine
de l’éolienne. On suppose que :
• P (v) = 0 si v < Vmin ou v > Vmax ;
1
• P (v) = ρC p Sv 3 si Vmin É v É Vnom ;
2
1 3
• P (v) est constant égal à ρC p SVnom si Vnom < v É Vmax ].
2
(a) Définir la fonction P(v) qui réalise ce calcul.
(b) Représenter graphiquement cette fonction sur l’intervalle [0, 26].

Distribution de probabilités associée à une vitesse moyenne


¦ On ne peut pas simplement considérer que l’éolienne fonctionne constamment avec la vitesse
moyenne du vent. En effet, la vitesse du vent varie au cours de l’année et on va donc considérer
cette vitesse comme une variable aléatoire.

Question 2 : On considère que la vitesse du vent suit une loi de probabilité appelée loi de Rayleigh.
La densité de probabilité de cette loi est la fonction notée R et définie par :

2v v2 2Vmoy
µ ¶
R(v) = 2 exp − 2 avec A = p
A A π

Rappelons que ceci signifie en particulier que pour v 2 Ê v 1 Ê 0, la probabilité que la vitesse du vent
v soit comprise entre v 1 et v 2 est :
Z v2
P(v 1 É v É v 2 ) = R(v) dv
v1

(a) Définir la fonction R(v).

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp30.pdf
(b) Estimer numériquement la probabilité que la vitesse du vent v soit comprise entre Vmin et
Vmax .
(c) Estimer numériquement la probabilité que la vitesse du vent v soit comprise entre Vnom et
Vmax .
(d) Représenter graphiquement la fonction R sur l’intervalle [0, 26].

Énergie produite en un an
Question 3 : On estime la quantité d’énergie E produite en un an (en kWh) par la relation :

8760
Z Vmax
E= R(v)P (v) dv
1000 Vmin

Calculer numériquement E .

Utilisation d’une base de données


Question 4 : Ouvrir la base de données eoliennes.sqlite avec SQL ITEMAN.
(a) Regarder la table eoliennes, elle donne les caractéristiques de différentes éoliennes repérées
par leur numéro (Num). Utiliser une commande SQL pour lister les enregistrements de cette
table pour lesquels Vnom, Vmin, Vmax et Surf correspondent aux valeurs utilisées dans ce TP.
Vérifier qu’il n’y a qu’un seul enregistrement correspondant et noter le numéro de l’éolienne
et sa hauteur (notés n et h).
(b) Regarder la table vents, elle donne la vitesse moyenne du vent suivant la hauteur considérée
ainsi que le type de terrain. Utiliser une commande SQL pour déterminer les enregistrements
de cette table qui correspondent à la vitesse moyenne utilisée dans ce TP et à la hauteur de
l’éolienne obtenue à la question précédente. Vérifier que l’on obtient qu’un seul enregistre-
ment et noter le type de terrain correspondant.
(c) Regarder la table terrains et rechercher la description du type de terrain obtenu à la question
précédente.
TP 30 : Exemple d’utilisation d’une BDD

Éléments de correction

Q. 1 :

import numpy as np
import matplotlib.pyplot as plt

S=9.08
Cp=0.3
Vmin=4.0
Vmax=25.0
Vnom=12.0
Vmoy=7.41
rho=1.25

def P(v):
if v<Vmin or v>Vmax:
return 0
elif Vmin<=v<=Vnom:
return 0.5*rho*Cp*S*v**3
else:
return 0.5*rho*Cp*S*Vnom**3
vv=np.linspace(0,26,100)
plt.plot(vv,[P(vi) for vi in vv],’b-’)
plt.xlabel("v (m/s)")
plt.ylabel("P (W)")
plt.title("Puissance P fournie en fonction de la vitesse du vent v")

Puissance P fournie en fonction de la vitesse du vent v


3000

2500

2000
P (W)

1500

1000

500

0
0 5 10 15 20 25 30
v (m/s)

Q. 2 :
def R(v):
A=2*Vmoy/np.sqrt(np.pi)
return 2*v*A**(-2)*np.exp(-v**2*A**(-2))
plt.plot(vv,R(vv))
plt.title(u"Densité de probabilité de la v.a.r. v")
plt.xlabel("v")
plt.ylabel("R(v)")

0.12
Densité de probabilité de la v.a.r. v

0.10

0.08

0.06
R(v)

0.04

0.02

0.00
0 5 10 15 20 25 30
v

Estimation numérique de la probabilité que v soit compris entre Vmin et Vmax :

from scipy.integrate import quad


print quad(R,Vmin,Vmax)

(0.7953073454295636, 1.971260414970532e-12)
Estimation numérique de la probabilité que v soit compris entre Vnom et Vmax :

from scipy.integrate import quad


print quad(R,Vnom,Vmax)

(0.12735391116070854, 1.4139124444668532e-15)

Q. 3 : Calcul numérique de E :

print "E=%f (kWh)" % (8760e-3*quad(lambda v:P(v)*R(v),Vmin,Vmax)[0])

E=8627.497276 (kWh)

Q. 4 :

import sqlite3
FICHIER_BDD=’/home/ba/Enseignement/PC/Python/Data/eoliennes.sqlite’
bdd=sqlite3.connect(FICHIER_BDD)
print bdd.execute("""
SELECT * FROM eoliennes
WHERE Vnom=%f AND Vmin=%f AND Vmax=%f and Surf=%f
""" % (Vnom,Vmin,Vmax,S)).fetchall()
[(3, 24.0, 3.4, 9.08, 0.3, 4.0, 12.0, 25.0)]
Pour récupérer le numéro n et la hauteur h :

(n,h)=bdd.execute("""
SELECT Num,Haut FROM eoliennes
WHERE Vnom=%f AND Vmin=%f AND Vmax=%f and Surf=%f
""" % (Vnom,Vmin,Vmax,S)).fetchone()
print n,h

3 24.0

print bdd.execute("""
SELECT * FROM vents
WHERE Vmoy=%f AND Haut=%f
""" % (Vmoy,h)).fetchall()

[(7, 24.0, 7.41)]


Le terrain correspondant aux valeurs numériques de ce TP est de type 7. Ensuite :

print bdd.execute("""
SELECT * FROM terrains
WHERE Type=7
""").fetchall()

[(7, u’Haies’, 0.21)]


TP 31 : Ave Cesar (zud bdrzq)
On cherche à crypter un texte t de longueur n composé de caractères en minuscules (soit 26
lettres différentes) représentés par des entiers compris entre 0 et 25 (0 ↔ a, 1 ↔ b, . . . 25 ↔ z).
Ainsi, le texte ecolepolytechnique est représenté par le tableau suivant où la première ligne
représente le texte et la seconde les entiers correspondants :

e c o l e p o l y t e c h n i q u e
4 2 14 11 4 15 14 11 24 19 4 2 7 13 8 16 20 4

Ce même texte est représenté en P YTHON par la liste :

t=[4,2,14,11,4,15,14,11,24,19,4,2,7,13,8,16,20,4]

On utilisera cette liste t pour tester les fonctions écrites dans les question 2, 3, 4, 5 et 7.

Partie 1 Codage de César


Ce codage est le plus rudimentaire que l’on puisse imaginer. Il a été utilisé par Jules César (et
même auparavant) pour certaines de ces correspondances. Le principe est de décaler les lettres de
l’alphabet vers la gauche de 1 ou plusieurs positions. Par exemple, en décalant les lettres de 1 po-
sition, le caractère a se transforme en z, le b en a,... le z en y. Le texte avecesar devient donc
zudbdrzq.

Question 1 : Que donne le codage du texte maitrecorbeau en utilisant un décalage de 5 ?

Question 2 : Écrire la fonction codageCesar(t,d) qui prend en arguments la liste t et un entier


d et qui retourne la liste tc de même taille que t contenant le texte décalé de d positions.

Question 3 : Écrire de même la fonction decodageCesar(tc,d) prenant en argument la liste


tc correspondant au texte crypté et le décalage d qui a été utilisé et qui réalise le décalage dans
l’autre sens.

Partie 2 Décodage automatique


Pour réaliser ce décodage, il faut connaitre la valeur du décalage. Une manière de la déterminer
automatiquement est d’essayer de deviner cette valeur. L’approche la plus couramment employée
est de regarder la fréquence d’apparition de chaque lettre dans le texte crypté. En effet, la lettre la
plus fréquente dans un texte en français suffisamment long est e.

Question 4 : Écrire la fonction frequences(tc) qui prend en argument une liste tc qui re-
présente le texte crypté et qui retourne une liste de taille 26 dont l’élément d’indice i est le nombre
d’apparitions de i dans tc.

Question 5 : Écrire la fonction decodageAuto(tc) qui prend en argument la liste tc qui repré-
sente le texte crypté et qui retourne la liste t correspondant au texte d’origine (en calculant la clé
pour que la lettre e soit la plus fréquente dans le texte de départ).

1. D’après Polytechnique PC-MP 2008.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp31.pdf
Partie 3 Codage de Vigenère
Au XVIe siècle, Blaise de Vigenère a modernisé le codage de César très peu résistant de la manière
suivante. Au lieu de décaler toutes les lettres du texte de la même manière, on utilise un texte clé qui
donne une suite de décalages.
Prenons par exemple la clé concours. Pour crypter un texte, on code la première lettre en uti-
lisant le décalage qui envoie le a sur le c (la première lettre de la clé). Pour la deuxième lettre, on
prend le décalage qui envoie le a sur le o (la seconde lettre de la clé) et ainsi de suite. Pour la hui-
tième lettre, on utilise le décalage a vers s puis, pour la neuvième, on reprend la clé à partir de sa
première lettre. Sur l’exemple ecolepolytechnique avec la clé concours, on obtient :

e c o l e p o l y t e c h n i q u e
g q b n s j f d a h r e v h z i w s
c o n c o u r s c o n c o u r s c o

(la première ligne donne le texte, la deuxième le texte crypté et la troisième la lettre de la clé utilisée
pour le décalage).
Question 6 : Donner le codage de becunfromage en utilisant la clé jean.

Question 7 : Écrire la fonction codageVigenere(t,c) qui prend comme arguments une liste
t représentant le texte à crypter et une liste d’entiers c donnant la clé servant au codage et qui
retourne la liste tc contenant le texte crypté. Écrire la fonction decodageVigenere(tc,c) qui
réalise le décodage.
TP 31 : Ave Cesar (zud bdrzq)

Éléments de correction
Partie 1 Codage de César
Q. 2 :

def codageCesar(t,d):
n=len(t)
tc=[0]*n
for i in range(n):
tc[i]=t[i]-d
if tc[i]<0:
tc[i]=tc[i]+26
return tc
print codageCesar(t,5)

[25, 23, 9, 6, 25, 10, 9, 6, 19, 14, 25, 23, 2, 8, 3, 11, 15, 25]
On peut aussi utiliser un calcul de reste de division euclidienne.

Q. 3 :

def decodageCesar(tc,d):
n=len(tc)
t=[0]*n
for i in range(n):
t[i]=tc[i]+d
if t[i]>25:
t[i]=t[i]-26
return t
print decodageCesar(codageCesar(t,5),5)==t

True

print decodageCesar(codageCesar(t,22),22)==t

True

Partie 2 Décodage automatique


Q. 4 :

def frequences(tc):
f=[0]*26
for c in tc:
f[c]=f[c]+1
return f
print frequences(codageCesar(t,2))

[2, 0, 4, 0, 0, 1, 1, 0, 0, 2, 0, 1, 2, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
0]

Q. 5 :
def decodageAuto(tc):
f=frequences(tc)
# On recherche c tq f[c] est maximal
c=0
for i in range(2,26):
if f[i]>f[c]:
c=i
# Le nombre 4 (caractère e) a été codé en c
# donc 4-d=c
d=4-c
if d>25:
d=d-26
if d<0:
d=d+26
return decodageCesar(tc,d)
print decodageAuto(codageCesar(t,5))==t

True

Partie 3 Codage de Vigenère


Q. 7 :

def codageVigenere(t,c):
n=len(t)
tc=[0]*n
j=0 # Position dans la clé c
for i in range(n):
tc[i]=t[i]-c[j]
if tc[i]<0:
tc[i]=tc[i]+26
j=j+1
if j>=len(c):
j=0
return tc
def decodageVigenere(tc,c):
n=len(tc)
t=[0]*n
j=0 # Position dans la clé c
for i in range(n):
t[i]=tc[i]+c[j]
if t[i]>25:
t[i]=t[i]-26
j=j+1
if j>=len(c):
j=0
return t
print decodageVigenere(codageVigenere(t,[5,25]),[5,25])==t

True
TP 32 : Dépouillement d’élections
Le problème consiste à faire le décompte du résultat des élections dans le pays X . La règle élec-
torale y est très laxiste, puisqu’on peut être élu sans s’être présenté. En effet, chaque citoyen est
identifié par un numéro i (avec 0 É i < n) et l’ensemble des votes est représenté par une liste V où
V[i] représente le vote du citoyen i . La liste V est de taille n (on utilisera l’instruction n=len(V)).
Un citoyen ayant obtenu strictement plus de 50% des voix est élu au premier tour.
Question 1 : Écrire une fonction nb_voix(V,x) qui compte le nombre de fois où x apparait
dans la liste V (c’est à dire le nombre de voix obtenues par le candidat x).

Question 2 : Écrire la fonction gagnant_tour1(V) qui retourne le gagnant du premier tour s’il
existe. S’il n’existe pas, on retournera −1. Donner l’ordre de grandeur du temps d’exécution de cette
fonction en fonction de n. Tester cette fonction sur les exemples suivants :

V1=[1,2,3,4,5,6,7,8,9,0] V4=[1,1,0,1,0,1,0,0,2,2]
V2=[1,0,2,2,1,0,1,0,1,1] V5=[1,1,1,2,2,2,2,2,2,5]
V3=[1,0,1,2,1,0,1,0,1,1] V6=[1,1,1,2,3,3,3,4,4,4]

Question 3 : On considère la fonction suivante :


def mystere(V):
n=len(V)
W=sorted(V)
x=W[n/2]
if nb_voix(V,x)>float(n/2):
return x
else:
return -1
L’instruction W=sorted(V) construit une liste dont les éléments ceux exactement les mêmes que
ceux de V mais triés dans l’ordre croissant.
(a) Décrire ce que fait cette fonction.
(b) On admet que le temps d’exécution de W=sorted(V) est O(n ln(n)). Donner un ordre de
grandeur du temps d’exécution de mystere(V) en fonction de n.
Au deuxième tour des élections, le candidat ayant obtenu le plus de voix est élu. Si il y a égalité,
tous les candidat ayant obtenu le plus de voix sont élus.
Question 4 : On considère la la fonction suivante :
def mystere2(V):
n = len(V)
m = nb_voix(V,V[0])
i=1
while i<n:
k = nb_voix(V,V[i])
if k>m:
m = k
i = i+1
return m

1. D’après Polytechnique PSI/PT 2005.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp32.pdf
Décrire ce que fait cette fonction. Donner un invariant de boucle permettant de justifier cette affir-
mation. Donner un ordre de grandeur du temps d’exécution de cette fonction, en fonction de n.

Question 5 : Écrire une fonction gagnants_tour2(V) qui construit est renvoie la liste des
gagnants du deuxième tour (attention : chaque gagnant ne devra apparaitre qu’une seule fois dans
la liste renvoyée). Donner un ordre de grandeur du temps d’exécution de cette fonction en fonction
de n.

Question 6 : Écrire une fonction gagnants_tour2_trie(V) qui construit et renvoie la liste


des gagants du deuxième tour en supposant que la liste V est triée. Le temps d’exécution de cette
fonction devra être O(n).
TP 32 : Dépouillement d’élections

Éléments de correction
Q. 1 :

def nb_voix(V,x):
k = 0
for y in V:
if y==x:
k = k+1
return k

Q. 2 : On parcourt tous les éléments x ∈ V et on compte le nombre d’occurrences de x dans V . Si ce


nombre est strictement supérieur à n/2, alors x est gagnant au premier tour.

def gagnant_tour1(V):
n = len(V)
for x in V:
if nb_voix(V,x)>float(n)/2:
return x # Et la boucle s’arrête
# La boucle est allée jusqu’au bout
# il n’y a pas de gagnant au premier tour donc :
return -1

print gagnant_tour1(V1)

-1

print gagnant_tour1(V2)

-1

print gagnant_tour1(V3)

print gagnant_tour1(V4)

-1

print gagnant_tour1(V5)

print gagnant_tour1(V6)

-1
Voici un moyen d’écrire ceci plus simplement :

for i in range(1,7):
print eval("gagnant_tour1(V%s)" % i)

-1 -1 1 -1 2 -1
Comme le temps d’exécution de nb_voix(V,x) est en O(n), celui de gagnant_tour1(V) est
en O(n 2 ).

Q. 3 : La liste W est triée. S’il y a un gagnant x au premier tour, alors il occupe plus de 50% des
éléments de W donc l’élément « au milieu » de W est nécessairement egal à x. Pour savoir s’il y a
un gagnant au premier tour, il suffit donc de regarder si l’élément au mileu de V a obtenu stricte-
ment plus de 50% des voix. La fonction mystere donne donc également le gagnant éventuel du
premier tour. Comme sorted(V) est en O(n ln(n)) et nb_voix en O(n), le temps d’exécution de
mystere(V) est en O(n) + O(n ln n) = O(n ln n).

for i in range(1,7):
print eval("mystere(V%s)" % i)

-1 -1 1 -1 2 -1

Q. 4 : Cette fonction calcule le plus grand nombre de voix obtenu par un candidat (les gagnants
du deuxième tour seront donc les candidats qui totalisent ce nombre de voix). On peut considérer
l’invariant de boucle :

m = max {nb_voix(V[0]), . . . , nb_voix(V[i-1])}

Comme nb_voix s’exécute en O(n) et la boucle while est faite exactement n fois, donc le temps
d’exécution de mystere2(V) est en O(n 2 ). Pour plus de clarté dans la suite, on pose :

nb_voix_max=mystere2

Q. 5 : On utilise la fonction définie dans la question précédente. On va construire progressivement


une liste G contenant tous les gagnants du second tour (chacun apparaissant une seule fois dans la
liste) :

def gagnants_tour2(V):
m = nb_voix_max(V)
G = []
for x in V:
if (x not in G) and (nb_voix(V,x)==m):
G.append(x)
return G

for i in range(1,7):
print eval("gagnants_tour2(V%s)" % i)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] [1] [1] [1, 0] [2] [1, 3, 4]


Là encore, le temps d’exécution est en O(n 2 ).

Q. 6 : La première chose à faire est de calculer le nombre maximum de voix obtenues par un candi-
dat. Pour cela, on parcourt la liste V et à chaque fois que l’on observe un changement on calcule le
nombre d’éléments correspondant et on retient le maximum. On parcourt ensuite la liste. Si on est
à l’indice i et si V [i + m − 1] et V [i ] sont égaux, alors V [i ] est un gagnant du second tour. Pour éviter
de sortir de la liste, il faut considérer les indices de i = 0 jusqu’à i = n − m.
def gagnants_tour2_trie(V):
n = len(V)
i0 = 0
m = 0
for i in range(n):
if V[i]!=V[i0]:
i0 = i
t = i-i0+1
if t>m:
m = t
G = [] # ou :
for i in range(n-m+1): # for i in range(n):
if V[i+m-1]==V[i]: # if i+m-1<n and V[i+m-1]==V[i]
G.append(V[i]) # ...
return G

for i in range(1,7):
print eval("gagnants_tour2(V%s)" % i)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] [1] [1] [1, 0] [2] [1, 3, 4]


TP 33 : Quelques exercices du site http://www.france-ioi.org/

Le site d’entraînement à la programmation et l’algorithmique.

¦ On peut avoir besoin dans un programme de demander des informations à l’utilisateur. Pour de-
mander un nombre entier (par exemple le nombre d’élèves dans une classe), on écrira :

n = int(raw_input("Nombre d’élèves de la classe : "))

et le nombre entré au clavier sera alors enregistré dans la variable n. Pour demander un nombre réel
(par exemple le rayon d’un cercle) :

r = float(raw_input("Rayon du cercle : "))

B Dans ce TP, il n’y aura pas besoin d’écrire de fonction. On utilisera un fichier différent pour
chaque exercice (par exemple epidemie.py, melange.py et marchands.py).

Exercice 1 Contrôle d’une épidémie : Afin de pouvoir mieux combattre les différentes épidémies,
parfois très graves, qui se développent régulièrement dans la région, le département de médecine
de l’université a lancé une grande étude. En particulier, les chercheurs s’intéressent à la vitesse de
propagation d’une épidémie et donc à la vitesse à laquelle des mesures sanitaires doivent êtres mises
en place.

Ce que doit faire votre programme : Votre programme doit d’abord lire un entier, la population
totale de la ville. Sachant qu’une personne était malade au jour 1 et que chaque malade contamine
deux nouvelles personnes le jour suivant (et chacun des jours qui suivent), vous devez calculer à
partir de quel jour toute la population de la ville sera malade.

Exemple 1 : Exemple 2 :
entrée : entrée :
3 10
sortie : sortie :
2 4

Commentaires. On a 1 malade le premier jour, donc 2 nouveaux malades le second jour, soit un
total de 3 malades. On a donc 6 nouveaux malades au troisième jour, soit un total de 9 malades. On
a donc 18 nouveaux malades au quatrième jour, soit...

Exercice 2 Mélange explosif : Les chimistes de l’université ont mis au point un nouveau procédé
de fabrication d’un onguent qui permet une cicatrisation très rapide des blessures. Ce procédé est
cependant très long et nécessite une surveillance de tous les instants de la préparation en train de
chauffer, et ce parfois pendant des heures. Confier cette tâche à un étudiant n’est pas possible, ils
s’endorment toujours ou ne font pas attention... et cela risque alors d’exploser ! Un dispositif auto-
matique de surveillance de la préparation serait donc intéressant. Celui-ci surveillerait la tempéra-
ture toutes les 15 secondes et si celle-ci devient anormale alors une alarme devrait sonner, afin de
prévenir tout le monde.

http://alexandre.boisseau.free.fr/Prive/WWW/InfoPCSI/tp33.pdf
Ce que doit faire votre programme : Votre programme devra lire trois entiers : le nombre total de
mesures envisagées ainsi que la température minimum et maximum autorisées. Les entiers suivants
seront les différentes températures relevées au cours du temps. Tant que les températures relevées
restent dans le bon intervalle, votre programme devra écrire le texte "Rien à signaler" mais dès que
la température n’est pas bonne il doit écrire le texte "Alerte ! !" et s’arrêter.

Exemple 1 Exemple 2
entrée : entrée :
5 3
10 0
20 100
15 15
10 50
20 75
0 sortie :
15 Rien à signaler
sortie : Rien à signaler
Rien à signaler Rien à signaler
Rien à signaler
Rien à signaler
Alerte !!

Attention. Dans l’exemple 1, le programme doit s’arrêter de demander les mesures dès qu’il dé-
clenche l’alerte, bien que nombre total de mesures n’ait pas été entré.

Exercice 3 Répartition du poids : Après seulement quelques heures de route, au sein d’une longue
caravane de marchands, certains chevaux montrent déjà des signes de fatigue alors que d’autres sont
en pleine forme. En cherchant la raison de ce phénomène, vous vous rendez compte que certaines
charrettes sont bien plus lourdes que les autres ! Vous décidez donc de mieux répartir le poids, afin
que toutes les charrettes aient exactement le même poids 1 .

Ce que doit faire votre programme : On vous décrit les charrettes qui com- Exemple
posent une caravane, en vous donnant pour chacune, le poids des marchan- entrée :
dises qu’elle transporte. Votre programme doit déterminer quel poids ajouter 5
ou retirer à chaque charrette, pour qu’elles transportent toutes ensuite le même 40.0
poids, et ce sans modifier le poids total transporté par l’ensemble des charrettes 12.0
de la caravane. 20.0
Entrée : L’entrée commence par un entier nbCharrettes : le nombre de 5.0
charrettes de la caravanne. Les nbCharrettes lignes suivantes décrivent 33.0
chacune une charrette par un nombre décimal : le poids qu’elle transporte ini- sortie :
tialement. -18.0
Sortie : Vous devez afficher nbCharrettes nombres décimaux sur la sor- 10.0
tie : le poids à ajouter à chaque charrette (ce qui revient à en retirer si ce nombre 2.0
est négatif), dans le même ordre que celui de l’entrée. Il n’y a pas d’arrondis à 17.0
faire. -11.0

Commentaires : Dans cet exemple, on modifie toutes les charettes pour qu’elles transportent cha-
cune un poids de 22.0, soit un total de 110 pour la caravane, comme au départ.

1. Pour les puristes, il s’agit en fait de masses.


TP 33 : Quelques exercices du site http://www.france-ioi.org/

Éléments de correction
Ex. 1 : On définit les variables population (population totale), malades (nombre de personnes
malades) et jour (numéro du jour concerné). Initialement, malades=1 et jour=1. À chaque
fois que jour augmente de 1, malades est multiplié par 3. On continue jusqu’à ce que l’on ait
malades>=population (i.e. on continue tant que malades<population). Dans la suite, les
valeurs soulignées sont celles entrées par l’utilisateur.

population = int(raw_input("Population totale : "))


malades = 1
jour = 1
while malades<population:
jour = jour+1
malades = malades*3
print "Nombre de jours :", jour

Population totale : 3 Nombre de jours : 2


Autre exemple : Population totale : 10 Nombre de jours : 4

Ex. 2 : La difficulté est que le programme peut s’arrêter de deux manières : soit parce que toutes les
mesures ont été traitées, soit parce que la mesure est hors de l’intervalle. Première possibilité :

nb_mes = int(raw_input("Nombre de mesures : "))


mes_min = int(raw_input("Valeur minimale : "))
mes_max = int(raw_input("Valeur maximale : "))
n = 1 # Nombre de mesures traitées
continuer = 1
while n<=nb_mes and continuer==1:
mesure = int(raw_input("Mesure %s : " % n))
if mesure>=mes_min and mesure<=mes_max:
print "Rien a signaler"
else:
print "Alerte !!"
continuer = 0
n = n+1

Nombre de mesures : 5 Valeur minimale : 10 Valeur maximale : 20 Mesure 1 :


15 Rien a signaler Mesure 2 : 10 Rien a signaler Mesure 3 : 20 Rien a signaler
Mesure 4 : 0 Alerte !!
Une autre possibilité, plus concise.

nb_mes = int(raw_input("Nombre de mesures : "))


mes_min = int(raw_input("Valeur minimale : "))
mes_max = int(raw_input("Valeur maximale : "))
for n in range(1,nb_mes+1):
mesure = int(raw_input("Mesure %s : " % n))
if mesure>=mes_min and mesure<=mes_max:
print "Rien a signaler"
else:
print "Alerte !!"
break
Nombre de mesures : 5 Valeur minimale : 10 Valeur maximale : 20 Mesure 1 :
15 Rien a signaler Mesure 2 : 10 Rien a signaler Mesure 3 : 20 Rien a signaler
Mesure 4 : 0 Alerte !!

Ex. 3 : Dans ce type de problème, on remarque que l’on ne pourra donner la réponse qu’une fois
toutes les valeurs entrées et on ne connait pas leur nombre à l’avance. On va donc utiliser une liste
Poids dans laquelle on enregistre le poids de chacune des charettes.

nbCharettes = int(raw_input("Nombre de charettes : "))


Poids = [0]*nbCharettes
for i in range(nbCharettes):
Poids[i] = float(raw_input("Poids de la charette %s : " % i))

Nombre de charettes : 5 Poids de la charette 0 : 40.0 Poids de la charette


1 : 12.0 Poids de la charette 2 : 20.0 Poids de la charette 3 : 5.0 Poids
de la charette 4 : 33.0
On calcule ensuite la moyenne. Le poids à ajouter à chaque charette correspond alors à la différence
du poids actuel avec la moyenne :

m = 0
for i in range(nbCharettes):
m = m+Poids[i]
m = m/nbCharettes
for i in range(nbCharettes):
print m-Poids[i]

-18.0 10.0 2.0 17.0 -11.0

Vous aimerez peut-être aussi