Formation Python du 14 Octobre 2010

publicité
Formation Python du 14 Octobre 2010
Version 1.0.1
Dimitri Bonnet, François Cuenot, Alexandre Vaudrey
12 October 2010
Table des matières
1
Organisation
1.1 Déroulement de la formation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
2
Préalables à la formation
2.1 Outils à installer avant la formation (linux) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Outils à installer avant la formation (windows) . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
5
5
3
Introduction à Python
3.1 Opérations de base . . . . . . . . . . . . . . . .
3.2 Les variables . . . . . . . . . . . . . . . . . . .
3.3 Les blocs & sections de code . . . . . . . . . . .
3.4 Les types . . . . . . . . . . . . . . . . . . . . .
3.5 Définition de fonctions et passage de paramètres
3.6 Exemple de structure de contrôle . . . . . . . .
.
.
.
.
.
.
7
7
7
8
9
10
10
4
Numpy
4.1 Introduction à numpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 L’indexing, le slicing et le broadcasting avec numpy . . . . . . . . . . . . . . . . . . . . . . . .
13
13
15
5
Matplotlib
5.1 Tracé de courbes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Tracé d’une fonction bidimensionnelle en courbes de niveaux . . . . . . . . . . . . . . . . . . .
19
19
21
6
Exemples
6.1 Exemples de traitement d’image . . . . . . . .
6.2 Résolution approchée d’équations non linéaires
6.3 Optimisation . . . . . . . . . . . . . . . . . .
6.4 Equations différentielles . . . . . . . . . . . .
25
25
31
33
38
7
Quelques liens...
Index
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
43
45
i
ii
Formation Python du 14 Octobre 2010, Version 1.0.1
Auteurs : Dimitri Bonnet, François Cuenot, Alexandre Vaudrey.
Table des matières
1
Formation Python du 14 Octobre 2010, Version 1.0.1
2
Table des matières
CHAPITRE 1
Organisation
La séance de formation à Python aura lieu le jeudi 14 Octobre 2010 à partir de 14h, à la faculté des sciences de
Belfort. Elle se tiendra dans une salle informatique (salles 204 et 205). Ainsi, ceux qui n’ont pas d’ordinateur
portable pourront utiliser les ordinateurs de la fac. Pour ceux qui désirent venir avec leur propre ordinateur, nous
vous demandons de préinstaller différents outils qui sont accessibles ici.
1.1 Déroulement de la formation
heure
14h - 14h45
14h45 - 15h45
15h45 - 16h15
16h15 - 16h45
16h45 - 18h
formation
Introduction à Python
Manipulation de tableaux avec Numpy
Pause
Tracés de graphiques avec Matplotlib
Exemples
lieu
salles 204 - 205
salles 204 - 205
salles 204 - 205
salles 204 - 205
D’autres informations à venir seront communiquées aux participants par mail. Mais vous pouvez aussi consulter
ces pages.
3
Formation Python du 14 Octobre 2010, Version 1.0.1
4
Chapitre 1. Organisation
CHAPITRE 2
Préalables à la formation
2.1 Outils à installer avant la formation (linux)
–
–
–
–
–
–
python 2.6 ou supérieur (Attention : ne pas installer une version 3)
scipy
numpy
matplotlib
PIL
Ipython
Warning : Ne pas installer la version 3 de Python ! !
2.2 Outils à installer avant la formation (windows)
– Python(x, y)
Note : Si vous avez un problème d’installation, vous pouvez nous contacter ici
5
Formation Python du 14 Octobre 2010, Version 1.0.1
6
Chapitre 2. Préalables à la formation
CHAPITRE 3
Introduction à Python
Python est un langage de programmation qui présente l’avantage d’être livré de base avec un interpréteur interactif.
On peut ainsi facilement tester chaque commande avant de l’inclure dans un programme.
Ipython est l’interpréteur que nous allons utiliser au cours de cette formation.
Une fois l’interpréteur lancé on peut saisir des commandes :
In [0]: print("Bonjour !")
Bonjour !
3.1 Opérations de base
In [1]: 1+1
Out[1]: 2
In [2]: 1-1
Out[2]: 0
In [3]: 2*3
Out[3]: 6
In [4]: 12%5
Out[4]: 2
In [5]: 2**8
Out[5]: 256
3.2 Les variables
In [6]: a = 1+1
le résultat de 1+1 est affecté à la variable a
In [7]: a
Out[7]: 2
7
Formation Python du 14 Octobre 2010, Version 1.0.1
3.2.1 Convention de nommage :
– les variables sont écrites en minuscule, les mots sont attachés et différentiés par des majuscules
In [8]: uneVariable = a #Copie de la valeur de "a" dans "uneVariable"
– les constantes sont écrites en majuscule, les mots sont séparé par des _
In [9]: FARADAY_CONSTANT = 9.64e4
3.3 Les blocs & sections de code
Lorsque l’on programme on organise le code en blocs ou sections (class, fonctions, structures de contrôle. . . ).
Python utilise l’indentation pour repérer ces blocs, et les retours à la ligne pour détecter la fin d’instruction.
Ce code C de déclaration de fonction
void disBonjour(){
print("bonjour"); //fin d’instruction
} //fin de bloc
devient en python :
def disBonjour() :
print(’Bonjour’)
Attention : Attention à conserver le même nombre d’espace pour l’indentation (4)
En enregistrant ce code dans un fichier texte “salut.py”, on peut l’exécuter depuis IPython
In [10]: %run salut.py
In [11]: disBonjour()
Out[11]: Bonjour
Attention : Attention à l’encodage, évitez les messages d’erreur avec la ligne suivante à ajouter en début du
fichier.py :
# -*- coding: utf-8 -*Pour empêcher un retour à la ligne d’être considéré comme une fin d’instruction on utilise \\
In [12]: resultat = 210392109 + 210393901293 + 2302319012 \
...:
+ 2130130921 - 2132898123 / 2202932 \
...:
** 2
Enfin la commande print associée au """ ou ”’ d’afficher du texte sur plusieurs lignes sans recourir a \\
In [13]: print("""blabla blabla blabla blabla
....: blabla blabla
....: blabla blabla blabla bla""")
blabla blabla blabla blabla
blabla blabla
blabla blabla blabla bla
8
Chapitre 3. Introduction à Python
Formation Python du 14 Octobre 2010, Version 1.0.1
3.4 Les types
In [14]: entier = 1
In [15]: type(entier)
Out[15]: <type ’int’>
In [16]: flotant = 1.
In [17]: type(flotant)
Out[17]: <type ’float’>
In [18]: complexe = 0+1j
In [19]: complexe.real
Out[19]: 0.0
In [20]: complexe.imag
Out[20]: 1.0
In [21]: complexe**2
Out[21]: (-1+0j)
In [22]: booleen = False
In [23]: booleen == booleen
Out[23]: True
Attention : 3/2 = 1 alors que 3/2.=1.5
3.4.1 Les tuples & les listes
In [24]: unTuple = (1,2,3,4)
In [25]: uneListe = [5,6,7,8]
Pour accéder à un élément on précise entre [] le numéro de l’élément voulu à partir de 0
In [26]: unTuple[0]
Out[26]: 1
In [27]: uneListe[2]
Out[27]: 7
La différence entre les deux : une liste est modifiable un tuple ne l’est pas
In [28]: unTuple[0] = 1
TypeError: ’tuple’ object does not support item assignment
In [29]: uneListe[2] = 1
In [30]: uneListe
Out[30]: [5, 6, 1, 8]
À noter que les chaines sont accessibles comme les tuples
In [31]: uneChaine = "coucou"
In [32]: uneChaine[1]
Out[32]: ’o’
3.4. Les types
9
Formation Python du 14 Octobre 2010, Version 1.0.1
On peut accéder à des sections (on reverra le slicing en détail avec numpy)
In [33]: uneChaine[0:3] # Les 3 première lettres
Out[33]: ’cou’
In [34]: uneChaine[1:-1] # Du second à l’avant dernier caractère
Out[34]: ’ouco’
In [35]: uneChaine[::2] # 1 caractère sur 2
Out[35]: ’cuo’
In [36]: uneChaine[::-1] # La chaine à l’envers
Out[36]: ’uocuoc’
In [37]: uneChaine[::-2] # 1 caractère sur 2 de la chaine à l’envers
Out[37]: ’uco’
On peut les concaténer :
In [38]: uneChaine+uneChaine
Out[38]: ’coucoucoucou’
In [39]: uneChaine*2
Out[39]: ’coucoucoucou’
3.4.2 Les dictionnaires
In [40]: dic = { ’list’ : [1,2,3],
....:
’str’ : ’coucou’ }
In [41]: dic[’str’]
Out[41]: ’coucou’
In [42]: dic[’list’][0]
Out[42]: 1
3.5 Définition de fonctions et passage de paramètres
In [43]: def somme(a,b,c) :
....:
return a + b + c
....:
In [44]: somme(2,3,3)
Out[44]: 8
In [45]: somme(*[2,3,3])
Out[45]: 8
3.6 Exemple de structure de contrôle
3.6.1 if/elif/else
In [46]: prenom = raw_input(’Prénom : ’)
Prénom : François
10
Chapitre 3. Introduction à Python
Formation Python du 14 Octobre 2010, Version 1.0.1
In [47]: if prenom == ’Chef’ :
....:
print("Bonjour Chef")
....: elif prenom in (’Alex’, ’Dimitri’, ’François’) :
....:
print("Bravo !")
....: else :
....:
print("Salut %s" %prenom)
....:
Bravo !
3.6.2 for/range
In [48]: for i in range(3) :
....:
print(i)
....:
0
1
2
In [49]: for organisateur in (’Alex’, ’Dimitri’, ’François’):
....:
print(organisateur)
....:
Alex
Dimitri
François
In [50]: for index, organisateur in enumerate(’Alex’, ’Dimitri’, ’François’):
....:
print index, organisateur
0 Alex
1 Dimitri
2 François
3.6.3 while/break/continue
In [51]: a = [1, 0, 2, 4]
In [52]: for element in a :
.....:
if element == 0 :
.....:
continue
.....:
print 1. / element
.....:
1.0
0.5
0.25
In [53]: end = False
In [54]: while not end :
.....:
end = raw_input(’Stop ou Encore ? ’)
.....:
if end == ’Stop’ :
.....:
print("Voilà c’est fini !")
.....:
end = True
.....:
elif end == ’Encore’ :
.....:
print("On continue !")
.....:
end = False
.....:
else :
.....:
print("On sent la fatigue ; FIN !")
.....:
break
.....:
3.6. Exemple de structure de contrôle
11
Formation Python du 14 Octobre 2010, Version 1.0.1
12
Chapitre 3. Introduction à Python
CHAPITRE 4
Numpy
4.1 Introduction à numpy
Numpy est un module python qui permet de manipuler des tableaux (array) de différentes dimensions. Pour
pouvoir utiliser numpy, on doit commencer par importer ce module :
In [1]: import numpy
La création d’un tableau peut se faire de la manière suivante :
In [2]: a = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
In [3]: a
Out[3]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Ensuite, on peut effectuer tous les calculs usuels. Attention, par défaut ce n’est pas du calcul matriciel :
In [4]: b = numpy.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
In [5]: b
Out[5]:
array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
In [6]: a*b
Out[6]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Le produit matriciel existe tout de même dans numpy, mais ne ce note pas ‘*’ :
In [7]: numpy.dot(a, b)
Out[7]:
array([[ 6, 6, 6],
[15, 15, 15],
[24, 24, 24]])
numpy permet de faire des opérations sur les tableaux sans avoir à recourir à des boucles.
En plus des opérations sur les tableaux, numpy a des méthodes de créations de tableau. Quelques exemples :
13
Formation Python du 14 Octobre 2010, Version 1.0.1
In [8]: numpy.zeros((3,
Out[8]:
array([[ 0., 0., 0.,
[ 0., 0., 0.,
[ 0., 0., 0.,
4))
0.],
0.],
0.]])
In [9]: numpy.ones((3, 4))
Out[9]:
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
In [10]: numpy.diag((1, 2, 3, 4))
Out[10]:
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]])
In [11]:
Out[11]:
array([[
[
[
numpy.random.random((3, 4))
0.81876645,
0.01391773,
0.23346125,
0.64060841,
0.50076912,
0.69950522,
0.0032919 ,
0.81533495,
0.77122613,
0.74856126],
0.83478922],
0.98571267]])
In [12]: numpy.arange(0, 10)
Out[12]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Il est aussi possible de créer des grilles :
In [13]: x = numpy.arange(0, 10)
In [14]: y = numpy.arange(0, 4)
In [15]: x
Out[15]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [16]: y
Out[16]: array([0, 1, 2, 3])
In [17]: X, Y = numpy.meshgrid(x, y)
In [18]: X
Out[18]:
array([[0,
[0,
[0,
[0,
1,
1,
1,
1,
2,
2,
2,
2,
3,
3,
3,
3,
4,
4,
4,
4,
5,
5,
5,
5,
6,
6,
6,
6,
7,
7,
7,
7,
8,
8,
8,
8,
9],
9],
9],
9]])
In [19]: Y
Out[19]:
array([[0,
[1,
[2,
[3,
0,
1,
2,
3,
0,
1,
2,
3,
0,
1,
2,
3,
0,
1,
2,
3,
0,
1,
2,
3,
0,
1,
2,
3,
0,
1,
2,
3,
0,
1,
2,
3,
0],
1],
2],
3]])
Avec numpy, on peut aussi obtenir des informations sur les tableaux :
In [20]: X.dtype
Out[20]: dtype(’int64’)
In [21]: X.shape
Out[21]: (4, 10)
14
Chapitre 4. Numpy
Formation Python du 14 Octobre 2010, Version 1.0.1
On peut aussi redimensionner des tableaux :
In [21]: a = numpy.ones((3, 4))
In [22]:
Out[22]:
array([[
[
[
a
In [23]:
Out[23]:
array([[
[
[
[
a.reshape((4, 3))
In [24]:
Out[24]:
array([[
[
[
a
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.,
1.],
1.],
1.]])
1.,
1.,
1.,
1.,
1.],
1.],
1.],
1.]])
1.,
1.,
1.,
1.,
1.,
1.,
1.],
1.],
1.]])
On remarque que la méthode reshape n’assigne pas de valeur à a, mais elle crée un résultat indépendant de a.
On peut utiliser autant de dimensions que désirées :
In [25]: a = numpy.random.random((3, 4, 2))
In [26]: a
Out[26]:
array([[[ 0.1827689 ,
[ 0.68885651,
[ 0.75809976,
[ 0.79636776,
0.46305519],
0.73044252],
0.25411572],
0.09944155]],
[[
[
[
[
0.13858014,
0.32894374,
0.62099969,
0.21603854,
0.44896837],
0.11556955],
0.6674025 ],
0.2682789 ]],
[[
[
[
[
0.68087085,
0.52750067,
0.09230344,
0.73838503,
0.2107056 ],
0.47428393],
0.0692179 ],
0.89622892]]])
In [27]: a.shape
Out[27]: (3, 4, 2)
4.2 L’indexing, le slicing et le broadcasting avec numpy
4.2.1 L’indexing
L’indexing permet d’obtenir la valeur du tableau à un indice donné :
In [1]: import numpy
In [2]: a = numpy.random.random_integers(0, 10, (3, 4))
4.2. L’indexing, le slicing et le broadcasting avec numpy
15
Formation Python du 14 Octobre 2010, Version 1.0.1
In [3]: a
Out[3]:
array([[ 2, 10,
[ 5, 5,
[ 7, 0,
8,
1,
4,
2],
2],
3]])
In [4]: a[2, 1]
Out[4]: 0
Le premier indice représente le premier axe, le deuxième indice représente le second axe...
Warning : En python, le premier indice est 0.
Avec l’indexing, on obtient un vue de l’élément du tableau, c’est à dire qu’on ne crée pas une nouvelle variable,
mais qu’on ne fait que visualiser l’élément. Ainsi, si on modifie la valeur de cet élément, la nouvelle valeur sera
affectée au tableau. Exemple :
In [5]: a[0,1] = 999
In [6]: a
Out[6]:
array([[ 2, 999,
[ 5,
5,
[ 7,
0,
8,
1,
4,
2],
2],
3]])
On peut aussi utiliser plusieurs indices :
In [7]: a[(0, 2), (0, 1)]
Out[7]: array([2, 0])
Dans cet exemple, on obtient un tableau composé de la valeur de a[0,0] = 2 et de a[2,1] = 0.
Il est également possible d’obtenir les valeurs d’un tableau en utilisant des booléens :
In [8]: booleen = (a <= 2)
In [9]: booleen
Out[9]:
array([[ True, False, False, True],
[False, False, True, True],
[False, True, False, False]], dtype=bool)
In [10]: a[booleen]
Out[10]: array([2, 2, 1, 2, 0])
In [11]: a[booleen]
Out[11]: array([2, 2, 1, 2, 0])
In [12]: a[(a <= 2)]
Out[12]: array([2, 2, 1, 2, 0])
On appelle ce booléen un masque. On peut aussi donner une valeur à ce masque :
In [20]: a[booleen] = 3333
In [23]: a
Out[23]:
array([[3333, 999,
8, 3333],
[
5,
5, 3333, 3333],
[
7, 3333,
4,
3]])
16
Chapitre 4. Numpy
Formation Python du 14 Octobre 2010, Version 1.0.1
4.2.2 Le slicing
Le slicing est une méthode qui permet de découper un tableau. Pour chaque axe, on peut découper le tableau en
indiquant le premier indice à partir du quel on va couper le tableau, puis le dernier indice et enfin le pas utilisé :
In [1]: import numpy
In [2]: a = numpy.arange(12)
In [3]: a
Out[3]: array([ 0,
1,
2,
3,
4,
5,
6,
7,
8,
9, 10, 11])
In [4]: a[3:9:2]
Out[4]: array([3, 5, 7])
a est coupé à partir de l’indice 3 (on compte en slice, le slice 3 se situe avant l’indice 3, entre l’indice 2 et l’indice
3) jusqu’à l’indice 8 (en compte en slice, le slice 9 se situe entre l’indice 8 et l’indice 9) en prenant un pas de 2
unités.
Le pas est optionnel :
In [5]: a[3:9]
Out[5]: array([3, 4, 5, 6, 7, 8])
Si on n’indique pas le premier slice, on commence du début :
In [6]: a[:9]
Out[6]: array([0, 1, 2, 3, 4, 5, 6, 7, 8])
Si on n’indique pas le dernier slice, on termine au dernier :
In [7]: a[3:]
Out[7]: array([ 3,
4,
5,
6,
7,
8,
9, 10, 11])
Il est aussi possible de compter en indices négatifs, on commence alors depuis la fin :
In [8]: a[-5:-2]
Out[8]: array([7, 8, 9])
In [9]: a[3:-2]
Out[9]: array([3, 4, 5, 6, 7, 8, 9])
Ces opérations peuvent se faire sur toutes les dimensions :
In [19]: a = numpy.random.random_integers(0, 10, (4, 5))
In [20]:
Out[20]:
array([[
[
[
[
a
7,
8,
9,
9,
6, 2,
9, 1,
4, 10,
0, 6,
8,
4,
7,
4,
9],
4],
0],
6]])
In [21]: a[0:2, 2:5]
Out[21]:
array([[2, 8, 9],
[1, 4, 4]])
Le slice sur la première dimension est indiqué en premier, puis on indique le slice sur la seconde dimension...,
chaque dimension est séparée par une ‘,’.
4.2. L’indexing, le slicing et le broadcasting avec numpy
17
Formation Python du 14 Octobre 2010, Version 1.0.1
4.2.3 Le broadcasting
Le broadcasting est une fonctionnalité de numpy qui permet de réaliser des opérations entre des tableaux de
dimensions différentes tant qu’une consistence existe entre ces tableaux.
Quelques exemples :
In [1]: import numpy
In [2]: a = numpy.arange(9).reshape((3,3))
In [3]: a = numpy.arange(9).reshape((3,3))
In [4]: a + 1
Out[4]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [5]: a = numpy.arange(0, 40, 10).reshape((4, 1))
In [6]: a
Out[6]:
array([[ 0],
[10],
[20],
[30]])
In [7]: b = numpy.arange(4)
In [8]: b
Out[8]: array([0, 1, 2, 3])
In [9]: a +
Out[9]:
array([[ 0,
[10,
[20,
[30,
b
1, 2, 3],
11, 12, 13],
21, 22, 23],
31, 32, 33]])
In [10]: a = numpy.zeros((4, 4))
In [11]:
Out[11]:
array([[
[
[
[
a
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.,
0.],
0.],
0.],
0.]])
In [12]: b = numpy.arange(4)
In [13]: b
Out[13]: array([0, 1, 2, 3])
In [14]:
Out[14]:
array([[
[
[
[
18
a + b
0.,
0.,
0.,
0.,
1.,
1.,
1.,
1.,
2.,
2.,
2.,
2.,
3.],
3.],
3.],
3.]])
Chapitre 4. Numpy
CHAPITRE 5
Matplotlib
Matplotlib est un module qui permet de réaliser des graphes 2D (et quelques graphes 3D de base, pour la 3D il est
préférable de se tourner vers Mayavi)
5.1 Tracé de courbes
Pour tracer des courbes, il faut utiliser l’outils plot.
Détaillons un exemple :
In [1]: import numpy
In [2]: import matplotlib as mpl
In [3]: import matplotlib.pyplot as plt
In [4]: from matplotlib import rc
Note : matplotlib et pyplot sont les outils pour les tracés, rc est utilisé ici pour avoir un rendu Latex des formules.
In [6]: X = numpy.linspace(-2, 2, 20)
In [7]: X
Out[7]:
array([-2.
, -1.78947368, -1.57894737, -1.36842105, -1.15789474,
-0.94736842, -0.73684211, -0.52631579, -0.31578947, -0.10526316,
0.10526316, 0.31578947, 0.52631579, 0.73684211, 0.94736842,
1.15789474, 1.36842105, 1.57894737, 1.78947368, 2.
])
Note : Ici, nous avons créé un tableau qui nous servira d’absices
In [8]: Y1 = numpy.exp(X)
In [9]: Y2 = X ** 2
In [10]: Y3 = 2 * numpy.sin(X) + 4.
Note : Ici, nous avons créé 3 tableaux représentant les ordonnées relatives à X pour 3 fonctions.
In [11]: plt.plot(X, Y1, ’b-’, label = r’$e^{x}$’)
Out[11]: [<matplotlib.lines.Line2D object at 0x35b4f10>]
19
Formation Python du 14 Octobre 2010, Version 1.0.1
In [12]: plt.plot(X, Y2, ’r+’, label = r’$x^{2}$’)
Out[12]: [<matplotlib.lines.Line2D object at 0x3976350>]
In [13]: plt.plot(X, Y3, ’ks--’, linewidth = 2, label = r’$2 \times sin(x) + 4$’)Out[13]: [<matplo
In [14]: plt.xlabel(’x’)
Out[14]: <matplotlib.text.Text object at 0x3db2f90>
In [15]: plt.ylabel(’y’)
Out[15]: <matplotlib.text.Text object at 0x3db5cd0>
In [16]: plt.legend()
Out[16]: <matplotlib.legend.Legend object at 0x39769d0>
In [17]: plt.grid(’True’)
In [17]: plt.show()
Note : Enfin, les tracés sont réalisés en indiquant un tableau pour les abscisses et un pour les ordonnées. En
option, on peut ajouter la couleur de la courbe ‘b’ pour bleu, ‘r’ pour rouge... La forme des points ‘+’, ‘s’... la
forme de la ligne ‘-‘, ‘–‘... peuvent compléter cette option. On peut choisir l’épaisseur de la ligne linewidth et on
peut ajouter un titre label.
Pour avoir la légende affichée, il faut utiliser plt.legend(). Et pour avoir une grille on emploie plt.grid(‘True’).
Le nom des axes sont donnés avec plt.xlabel et plt.ylabel
Le résultat obtenu :
20
Chapitre 5. Matplotlib
Formation Python du 14 Octobre 2010, Version 1.0.1
5.2 Tracé d’une fonction bidimensionnelle en courbes de niveaux
La représentation graphique de l’évolution d’une fonction f de deux variables x et y n’est pas une tâche facile,
surtout si le graphique en question est destiné à être imprimé. Dans ce type de cas, un graphe faisant apparaître les
lignes de niveaux de la fonction en question peut être une solution intéressante et lisible. Commençons donc par
considérer l’exemple simple d’une fonction de Rosenbrock de la forme :
f (x, y) = (1 − x)2 + y − x2
2
(5.1)
Que l’on déclare en python de la façon suivante :
In [1]: def f(x,y):
...:
"""Fonction de Rosenbrock."""
...:
return (1-x)**2+(y-x**2)**2
Le tracé de cette fonction en courbes de niveaux va nécessiter la création d’un maillage bidimensionnel permettant
de stocker l’intervalle de chacune des variables x et y. La fonction destinée à cela s’appelle meshgrid (incluse dans
‘NumPy‘‘). On construit donc le maillage en question sur l’intervalle (x, y) ∈ [−1; 1] × [−1; 2] :
In [2]: import numpy as np
In [3]: x , y = np.meshgrid(np.linspace(-1,1,201),np.linspace(-1,2,201))
In [4]: z = f(x,y)
La fonction meshgrid fait appel dans ce cas à deux fonctions linspace pour chacune des variables. z est ici
un objet array qui contient les valeurs de la fonction f sur chaque noeud du maillage. Pour tracer l’évolution
de f en lignes de niveaux, de fonctions sont adaptées, appelées respectivement contour et contourf. La
première ne trace que les lignes de niveaux alors que la seconde colore le graphe entre ces lignes de niveaux :
In [5]: graphe = contour(x,y,z,20)
Avec comme arguments, les variables x et y, les valeurs de z correspondantes ainsi que le nombre (ici 20) de
lignes de niveaux choisit.
Par défaut, ces courbes de niveaux sont colorées en fonction de leur “altitude” z correspondante. On peut par
ailleurs imposer une couleur uniforme pour le graphe précédent :
In [6]: graphe = contour(x,y,z,20,colors=’grey’)
Ce qui donne :
Comme dit précédemment, la fonction contourf colore toute la surface représentant la fonction :
In [7]: graphe = contourf(x,y,z,20)
In [8]: colorbar()
Out[8]: <matplotlib.colorbar.Colorbar instance at 0x3cc5758>
Ce qui donne :
S’il n’est pas possible d’utiliser de la couleur, comme dans un article ou un rapport imprimé en noir et blanc, on
peut utiliser des labels sur les lignes de niveaux afin de repérer leurs altitudes. La fonction en question s’appelle
clabel et prend comme principal argument la variable graphe précédente.
In [9]: graphe = contour(x,y,z,20,colors=’grey’)
In [10]: clabel(graphe,inline=1,fontsize=10,fmt=’%3.2f’)
Out[10]: <a list of 21 text.Text objects>
Qui donne : La première option inline=1 impose d’écrire les valeurs sur les lignes de niveaux, les deux options
suivantes gérant la taille de la police utilisée et le format d’écriture des valeurs.
5.2. Tracé d’une fonction bidimensionnelle en courbes de niveaux
21
Formation Python du 14 Octobre 2010, Version 1.0.1
22
Chapitre 5. Matplotlib
Formation Python du 14 Octobre 2010, Version 1.0.1
5.2. Tracé d’une fonction bidimensionnelle en courbes de niveaux
23
Formation Python du 14 Octobre 2010, Version 1.0.1
24
Chapitre 5. Matplotlib
CHAPITRE 6
Exemples
6.1 Exemples de traitement d’image
Voici quelques exemples de traitement d’image, basés sur une image de référence en traitement d’image : Lena.
6.1.1 Seuillage
Le seuillage est une opération qui affecte la valeur 0 à tous les pixels dont le niveau est inférieur à celui du seuil.
Ici, sur une image 8 bits (les niveaux varient de 0 à 255), on réalise un seuillage avec un niveau de seuil à 100. La
méthode numpy.where crée un masque et ici remplace par 0 toutes les valeurs du tableau lena inférieures à 100.
import
import
import
import
matplotlib as mpl
matplotlib.pyplot as plt
numpy
scipy
lena = scipy.lena()
# opération de seuillage
lena_seuil = numpy.where(lena > 100, lena, 0)
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
plt.title(’lena’)
ax1.imshow(lena, cmap = mpl.cm.gray)
ax2 = fig.add_subplot(1, 2, 2)
plt.title(’seuillage (100)’)
ax2.imshow(lena_seuil, cmap = mpl.cm.gray)
plt.show()
6.1.2 Sélection d’une partie de l’image
Pour sélectionner une partie de l’image, on peut utiliser le slicing de Numpy.
import
import
import
import
matplotlib as mpl
matplotlib.pyplot as plt
numpy
scipy
25
Formation Python du 14 Octobre 2010, Version 1.0.1
lena = scipy.lena()
# slicing
lena_select = lena[200:400, 100:300]
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
plt.title(’lena’)
ax1.imshow(lena, cmap = mpl.cm.gray)
ax2 = fig.add_subplot(1, 2, 2)
plt.title(’Selection [200:400, 100:300]’)
ax2.imshow(lena_select, cmap = mpl.cm.gray)
plt.show()
6.1.3 Transformée de Fourier
On peut réaliser une transformée de Fourier sur une image en utilisant la méthode de transformée de Fourier rapide
de Numpy en dimension 2 : numpy.fft.fft2.
Un exemple de transformée de Fourier et de transformée inverse sur le module et sur la phase :
import
import
import
import
26
matplotlib as mpl
matplotlib.pyplot as plt
numpy
scipy
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
# fonction de normalisation
def norma(mat):
mat1 = mat.real
mat1 -= mat1.min()
mat1 *= 255. / mat1.max()
return mat1
#fonction de normailsation sur une échelle logarithmique
def normalog(mat):
mat1 = norma(mat)
mat1 = numpy.log(1 + mat1)
mat1 *= 255. / mat1.max()
return mat1
lena = scipy.lena()
# transformée de Fourier de l’image
lena_fft = numpy.fft.fft2(lena)
# module de la transformée de Fourier de l’image
lena_fft_abs = abs(lena_fft)
# centré
lena_fft_abs_centre = numpy.fft.fftshift(lena_fft_abs)
# phase de la transformée de Fourier de l’image
lena_fft_phase = lena_fft / lena_fft_abs
# centré
lena_fft_phase_centre = numpy.fft.fftshift(lena_fft_phase)
6.1. Exemples de traitement d’image
27
Formation Python du 14 Octobre 2010, Version 1.0.1
# transformée de Fourier inverse du module
lena_abs = numpy.fft.ifft2(lena_fft_abs)
# transformée de Fourier inverse de la phase
lena_phase = numpy.fft.ifft2(lena_fft_phase)
fig = plt.figure()
ax1 = fig.add_subplot(2, 3, 1)
plt.title(’lena’)
ax1.imshow(lena, cmap = mpl.cm.gray)
ax2 = fig.add_subplot(2, 3, 2)
plt.title(’fft module’)
ax2.imshow(normalog(lena_fft_abs_centre), cmap = mpl.cm.gray)
ax3 = fig.add_subplot(2, 3, 3)
plt.title(’fft phase’)
ax3.imshow(norma(lena_fft_phase_centre), cmap = mpl.cm.gray)
ax5 = fig.add_subplot(2, 3, 5)
plt.title(’module’)
ax5.imshow(normalog(lena_abs), cmap = mpl.cm.gray)
ax6 = fig.add_subplot(2, 3, 6)
plt.title(’phase’)
ax6.imshow(norma(lena_phase), cmap = mpl.cm.gray)
plt.show()
28
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
6.1.4 Filtrage
Gradient
Pour l’opération gradient, on utilise ici une convolution selon chaque axe de l’image entre l’image et un filtre
représentatif du gradient selon ces axes.
import
import
import
import
import
matplotlib as mpl
matplotlib.pyplot as plt
numpy
scipy
scipy.signal
lena = scipy.lena()
# définition des filtres
fx = numpy.array([[-1, 0, 1]])
fy = numpy.transpose(fx)
# convolutions
lena_convol_x = scipy.signal.convolve2d(lena, fx, mode = ’same’)
lena_convol_y = scipy.signal.convolve2d(lena, fy, mode = ’same’)
lena_gradient = numpy.sqrt(lena_convol_x**2 + lena_convol_y**2)
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
plt.title(’lena’)
ax1.imshow(lena, cmap = mpl.cm.gray)
ax2 = fig.add_subplot(1, 2, 2)
plt.title(’Gradient’)
ax2.imshow(lena_gradient, cmap = mpl.cm.gray)
plt.show()
6.1.5 Transformations
Rotation
Dans scipy, il existe un module pour les images : scipy.ndimage. Dans ce module, on peut trouver différentes
fonctions comme la rotation. La rotation est effectuée en utilisant une matrice de rotation et une interpolation en
spline cubique est ensuite réaliser pour obtenir les valeurs des pixels de la nouvelle grille.
import
import
import
import
import
matplotlib as mpl
matplotlib.pyplot as plt
numpy
scipy
,
lena = scipy.lena()
# angle de rotation désiré
angle = 30.
# roations
lena_30_degresF = scipy.ndimage.rotate(lena, angle, reshape = False)
lena_30_degresT = scipy.ndimage.rotate(lena, angle, reshape = True)
fig = plt.figure()
6.1. Exemples de traitement d’image
29
Formation Python du 14 Octobre 2010, Version 1.0.1
ax1 = fig.add_subplot(1, 3, 1)
plt.title(’lena’)
ax1.imshow(lena, cmap = mpl.cm.gray)
ax2 = fig.add_subplot(1, 3, 2)
plt.title(’30 degres\nnon redimensionne’)
ax2.imshow(lena_30_degresF, cmap = mpl.cm.gray)
ax3 = fig.add_subplot(1, 3, 3)
plt.title(’30 degres\n redimensionne’)
ax3.imshow(lena_30_degresT, cmap = mpl.cm.gray)
plt.show()
Transformation géométrique
On peut créer ses propres déformation avec la fonction scipy.ndimage.geometric_transform, qui renvoie une image
avec un système de coordonnées souhaité. Une interpolation en spline cubique est là aussi réaliser pour obtenir la
valeur des pixels sur la nouvelle grille.
import
import
import
import
import
matplotlib as mpl
matplotlib.pyplot as plt
numpy
scipy
scipy.ndimage
lena = scipy.lena()
30
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
# définition du système de coordonnées
def deformation(coordonnees):
return (coordonnees[0], \
coordonnees[1] + (coordonnees[1] - lena.shape[1])/2.)
# transformation géométrique
lena_deform = scipy.ndimage.geometric_transform(lena, deformation)
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
plt.title(’lena’)
ax1.imshow(lena, cmap = mpl.cm.gray)
ax2 = fig.add_subplot(1, 2, 2)
plt.title(’Deformation’)
ax2.imshow(lena_deform, cmap = mpl.cm.gray)
plt.show()
6.2 Résolution approchée d’équations non linéaires
6.2.1 Fonction scalaire
Voyons comment approcher la solution d’une équation du type f (x) = 0 avec f une fonction réelle quelconque.
Considérons pour commencer la fonction scalaire f (x) = x − exp(−x) qui dispose d’une racine comprise entre
0 et 1. La première étape consiste à déclarer cette fonction :
6.2. Résolution approchée d’équations non linéaires
31
Formation Python du 14 Octobre 2010, Version 1.0.1
In [1]: import numpy as np
In [2]: def f(x):
...:
"""Fonction dont on cherche une racine."""
...:
return x-np.exp(-x)
Pour se convaincre de l’existence de cette racine, on peut par exemple tracer l’allure de cette fonction entre 0 et 1
à l’aide de matplotlib :
In [3]: import pylab as plt
In [4]: x = np.linspace(0,1,101)
In [4]: plt.plot(x,f(x),’b-’)
In [5]: plt.grid(True)
La fonction fsolve que nous allons utiliser pour résoudre notre problème est comprise dans le package
SciPy/Optimisation :
In [6]: import scipy.optimize as op
L’appel de cette fonction nécessite au minimum deux arguments, la fonction f précédemment déclarée et un point
de départ x0 de l’algorithme, estimation initiale de la solution. En utilisant x0 = 0.0 comme point de départ, la
solution est ainsi :
In [7]: op.fsolve(f,0.0)
Out[7]: 0.56714329040978384
32
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
6.2.2 Fonction vectorielle
Une démarche strictement identique doit être suivie pour obtenir la solution à un système d’équation non linéaires,
à condition de n’utiliser qu’un seul argument (list ou tuple) pour stocker les différentes composantes du vecteur
x = (x1 , x2 , . . . , xN ) considéré. En guise d’exemple, considérons le système non-linéaire [1] formé par les
fonctions f1 (x1 , x2 ) = x1 + 3 · log10 (x1 ) − x22 et f2 (x1 , x2 ) = 2 · x21 − x1 · x2 − 5 · x1 + 1. La déclaration de la
fonction f est désormais classique :
In [8]: def f(x):
...:
return [x[0]+3*log10(x[0])-x[1]**2,2*x[0]**2-x[0]*x[1]-5*x[0]+1]
En considérant comme point de départ le vecteur x0 = (5.0, 5.0), on obtient :
In [9]: op.fsolve(f,(5.0,5.0))
Out[9]: array([ 3.48744279, 2.26162863])
6.2.3 Références
[1] B. Démidovitch et I. Maron, Eléments de calcul numérique, Editions MIR, 1979.
6.3 Optimisation
6.3.1 Un premier problème d’optimisation
Afin de tester les fonctionnalités des algorithmes d’optimisation compris dans la bibliothèque SciPy, nous allons
utiliser comme support une “classique” fonction de Rosenbrock bidimensionnelle :
f (x1 , x2 ) = (1 − x1 )2 + (x2 − x21 )2
(6.1)
Fonction de deux variables que nous étudierons sur l’intervalle (x1 , x2 ) ∈ [0; 2] × [0; 2]. On commence donc par
déclarer cette fonction comme n’appelant qu’un seul argument qui peut être une liste ou un tuple :
In [1]: def f(x):
...:
"""Fonction de Rosenbrock a deux variables"""
...:
return (1-x[0])**2+(x[1]-x[0]**2)**2
On définit ensuite l’intervalle de variation de x1 et x2 à l’aide de la fonction meshgrid de NumPy :
In [2]: x1 , x2 = np.meshgrid(np.linspace(0,2,201),np.linspace(0,2,201))
Le tracé en lignes de niveaux de cette fonction fait clairement apparaître l’existence de cet optimum :
In [3]: contourf(x1,x2,f([x1,x2]),linspace(0,1,21))
In [4]: colorbar()
Ce qui donne :
On peut alors chercher la coordonnée de cet optimum en utilisant la fonction fmin comprise dans la partie optimisation de la bibliothèque SciPy :
In [5]: import scipy.optimize as op
In [6]: %time op.fmin(f,(0.0,0.0))
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 67
Function evaluations: 129
CPU times: user 0.02 s, sys: 0.00 s, total: 0.02 s
Wall time: 0.05 s
Out[7]: array([ 1.00001608, 1.0000338 ])
6.3. Optimisation
33
Formation Python du 14 Octobre 2010, Version 1.0.1
La fonction fmin est basée sur l’utilisation de l’algorithme du simplexe, qui après 67 itérations et 129 évaluations
de la fonction f a localisé un minimum au point (x1 , x2 ) = (1.0, 1.0).
Différents types de fonctions fmin existent dans SciPy, dont une qui utilise l’algorithme du gradient conjugué,
appelée fmin_cg :
In [8]: op.fmin_cg(f,(0.0,0.0))
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 18
Function evaluations: 132
Gradient evaluations: 33
Out[8]: array([ 1.00000614, 1.00001565])
Le résultat affiché précise par ailleurs le nombre d’évaluations du gradient de la fonction f , calculé ici de manière
approchée. Notons qu’il est possible de fournir à la fonction fmin_cg l’expression analytique du gradient de la
fonction objectif, sous forme de fonction Python.
Chacune des fonction fmin précédentes accepte certains arguments optionnels, comme par exemple le chemin
parcouru par l’algorithme. Dans le cas du simplexe, on peut ainsi afficher :
In [9]: solsimplexe = op.fmin(f,(0.0,0.0),retall=1)
Et le chemin suivit par l’algorithme est stocké dans la variable solsimplexe[1]. Une fois ce chemin tracé, on
obtient :
Le même procédé peut être utilisé pour étudié le chemin suivi par le gradient conjugué, que l’on peut superposer
à celui suivi par le simplexe :
34
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
6.3. Optimisation
35
Formation Python du 14 Octobre 2010, Version 1.0.1
6.3.2 Problème d’optimisation de type “moindres carrés”
Un problème très courant d’optimisation est celui qui cherche à minimiser le résidu formé par la différence entre
une fonction de structure donnée et un ensemble de points issus d’expérimentations. Le critère le plus courant
pour minimiser un tel résidu est celui dit, des moindres carrés, qui exprime cet écart sous la forme de la somme
des carrés des écart en chaque point, soit par exemple :
S(p) =
N
X
2
(y(xi , p) − ỹi )
(6.2)
i=1
avec S le critère servant de fonction objectif, y la fonction de structure connue (polynôme, spline, etc.) dépendante
d’un ensemble de paramètres p et ỹ les données expérimentales définies sur N points.
Ce type très particulier de problème d’optimisation bénéficie de méthodes numériques spécialement dédiées, dont
celle de Levenberg-Marquardt [1,2] justement implémentée dans SciPy. Comprise dans la partie optimisation de
SciPy, elle se nomme leastsq et prend comme argument la différence y(xi , p) − ỹi .
Comme exemple pratique d’application, on peut traiter les données expérimentales contenues dans le fichier
donnees-moindrescarres.dat. On importe donc ces données à l’aide de la fonction loadtxt de NumPy :
In [1]: import numpy as np
In [2]: donnees = np.loadtxt(’donnees-moindrescarres.dat’,skiprows=1)
L’option skiprows=1 sert ici à négliger la première ligne du fichier qui contient les entêtes. On extrait ensuite les
informations, le temps t et la grandeur mesurée notée ỹ :
In [3]: t , yb = donnees[:,0] , donnees[:,1]
L’étape suivante consiste à tracé l’évolution de y en fonction de t :
In
In
In
In
In
[4]:
[5]:
[6]:
[7]:
[8]:
plot(t,yb,’bo’)
grid(True)
xlabel(r’$t$’,size=20)
ylabel(r’$\tilde{y}$’,size=20)
title(r’Donn\’{e}es exp\’{e}rimentales’,size=18)
Ce qui donne :
L’évolution des données ressemblant globalement à une exponentielle décroissante, la fonction utilisée pour les
représenter sera de la forme :
y(t, p) = p1 · exp(−p2 · t)
(6.3)
Qui est fonction du temps et du vecteur des paramètres p = (p1 , p2 ). On créé donc la fonction en question :
In [9]: def y(t,p):
...:
"""Exponentielle decroissante."""
...:
return p[0]*np.exp(-p[1]*t)
Il faut ensuite créer la fonction résidu qui sera utilisée comme argument par leastsq et qui ne comprend comme
argument que le vecteur des paramètres :
In [10]: def residu(p):
...:
"""Residu."""
...:
return y(t,p)-yb
Et la fonction leastsq fonctionne directement sur la fonction residu, de la manière suivante :
In [11]: LM = op.leastsq(residu,[1.0,1.0],full_output=1)
L’option full_output étant ici activée afin de tirer le maximum d’informations du résultat, en premier lieux la
valeur du vecteur des paramètres recherché :
36
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
In [12]: LM[0]
Out[12]: array([ 1.03181619,
2.05876184])
Ce qui permet au passage de comparer la courbe d’ajustement obtenue avec les données de départ :
La seconde information contenue dans la variable LM est très importante puisqu’il s’agit de la matrice de covariance du résultat obtenu :
In [13]: LM[1]
Out[13]: array([[ 0.11623005,
0.23191121],[ 0.23191121,
0.95467769]])
D’autres informations sont contenues dans la variable LM dont par exemple le nombre d’appels de la fonction
objectif :
In [14]: LM[2][’nfev’]
Out[14]: 16
6.3.3 Références
[1] Kenneth Levenberg (1944). A Method for the Solution of Certain Non-Linear Problems in Least Squares. The
Quarterly of Applied Mathematics 2 : 164–168.
[2] Donald Marquardt (1963). An Algorithm for Least-Squares Estimation of Nonlinear Parameters. SIAM Journal
on Applied Mathematics 11 : 431–441.
6.3. Optimisation
37
Formation Python du 14 Octobre 2010, Version 1.0.1
6.4 Equations différentielles
6.4.1 Résolution approchée d’une équation différentielle logistique
La résolution approchée d’équations ou de systèmes d’équations différentielles peut être faite dans SciPy à l’aide
de la fonction odeint :
In [1]: from scipy. import odeint
Comme dans n’importe quel autre logiciel de ce type (matlab,etc.), l’équation différentielle ou le système différentiel doivent être écrits sous la forme d’un système du premier du type :
dy
(x) = F (x, y)
dx
(6.4)
avec y(x) = (y1 (x), . . . , yN (x)) le vecteur des fonctions recherchées, dépendant de la variable x et F une
fonction de forme quelconque. En guise d’exemple, considérons une équation logistique simple de la forme :
dy
y(t)
(t) = r · y(t) · 1 −
(6.5)
dx
K
Pour les besoins de la résolution numérique, on considère que r = 1, 5 et K = 6. On créé alors la fonction F :
In [2]: def F(y,t):
...:
"""Equation logistique"""
...:
return 1.5*y*(1-y/6)
Et la fonction odeint peut être appelée avec au minimum trois arguments, la fonction F , la condition initiale
y0 = y(t = 0) et le temps t comme variable principale :
38
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
In [3]: y0 = 1.0
In [4]: t = linspace(0,5,201)
In [5]: sol = odeint(F,y0,t)
Et la fonction y recherchée peut alors être tirée du résultat :
In [6]: y = sol[:,0]
et tracée sur un graphique :
6.4.2 Le système de Lotka-Volterra
Proposées indépendamment par Alfred James Lotka en 1925 et Vito Volterra en 1926, les équations dites de LotkaVolterra ou modèle proie-prédateur peuvent servir à reproduire les évolutions temporelles de deux populations
animales, l’une étant le prédateur de l’autre. Si ces deux populations sont représentées par des variables contiunes
x1 et x2 , le système différentiel en question est alors :
dx1
(t) = x1 (t) · (a − b · x2 (t))
dt
(6.6)
Puis :
dx2
(t) = −x2 (t) · (c − d · x1 (t))
(6.7)
dt
Pour les besoins de la résolution numérique, nous considérerons dans la suite que a = 2, b = 1, c = 1 et d = 0, 3.
On déclare ainsi la fonction F sous forme vectorielle, en la faisant toujours dépendre de la variable temporelle
même si ce n’est pas le cas dans la formulation mathématique de départ :
6.4. Equations différentielles
39
Formation Python du 14 Octobre 2010, Version 1.0.1
In [1]: def F(x,t):
...:
"""Systeme de Lotka-Volterra"""
...:
return [x[0]*(2-x[1]),-x[1]*(1-0.3*x[0])]
En faisant varier le temps sur l’intervalle t ∈ [0; 10] et en prenant comme condition initiale le vecteur x0 =
(2.0, 1.0) :
In [2]: t = linspace(0,10,201)
In [3]: x0 = [2.0,1.0]
La résolution se fait alors de la même manière que précédemment :
In [4]: lokVol = odeint(F,y0,t)
In [5]: x1 , x2 = lokVol[:,0] , lokVol[:,1]
Le tracé des évolutions de x1 et x2 en fonction du temps t donne :
Ou encore sous forme paramétrique :
40
Chapitre 6. Exemples
Formation Python du 14 Octobre 2010, Version 1.0.1
6.4. Equations différentielles
41
Formation Python du 14 Octobre 2010, Version 1.0.1
42
Chapitre 6. Exemples
CHAPITRE 7
Quelques liens...
Voici une liste de références pour les outils présentés lors de la formation. De cette manière, vous pourrez appronfondir les concepts vus pendant la formation. Vous pourrez y rencontrer un grand nombre d’exemples libres
d’utilisation.
– Une excellente documentation python très détaillée et très didactique de Gérard Swinnen.
– La galerie matplotlib où de nombreux exemples sont détaillés.
43
Formation Python du 14 Octobre 2010, Version 1.0.1
44
Chapitre 7. Quelques liens...
Index
broadcasting, 18
cmap, 25
contour, 21
contourf, 21
couleur, 20
courbes, 19
courbes de niveaux, 21
création de tableau, 13
date, 3
documentation, 43
dtype, 14
equation différentielle logistique, 38
equations différentielles, 38
equations non linéaires, 31
exemples, 25
filtrage, 29
fonction scalaire, 31
fonction vectorielle, 33
gradient, 29
gradient conjugué, 33
grille, 14
image, 25
indexing, 15
indice, 15
inline, 21
installation, 5
label, 20
latex, 19
Lena, 25
Levenberg, 36
Levenberg-Marquardt, 36
liens, 43
lieu, 3
ligne, 20
linewidth, 20
LM, 36
log, 26
Lotka, 39
Lotka-Volterra, 39
Marquardt, 36
masque, 15
Matplotlib, 19, 43
moindres carrés, 36
multiplication, 13
normalisation, 26
numpy, 13
numpy.arange, 13
numpy.array, 13
numpy.diag, 13
numpy.dot, 13
numpy.fft, 26
numpy.fft.fft2, 26
numpy.fft.fftshift, 26
numpy.fft.ifft2, 26
numpy.linspace, 19, 33
numpy.log, 26
numpy.meshgrid, 14, 21, 33
numpy.ones, 13
numpy.random.random, 13
numpy.random.random_integers, 15
numpy.transpose, 29
numpy.where, 25
numpy.zeros, 13
odeint, 38
op, 31, 33
op.fmin, 33
op.fsolve, 31
op.leastsq, 36
optimisation, 33
optimum, 33
organisation, 3
plot, 19
plt.grid, 20
plt.legend, 20
plt.xlabel, 20
45
Formation Python du 14 Octobre 2010, Version 1.0.1
plt.ylabel, 20
préalables, 5
préparation, 5
pyplot, 19
Python, 25
résidu, 36
résolution, 31, 38
redimensionner, 14
reshape, 14
Rosenbrock, 21, 33
rotation, 29
sélection, 25
scipy.integrat, 38
scipy.lena, 25
scipy.ndimage, 29
scipy.ndimage.geometric_transform, 30
scipy.ndimage.rotate, 29
scipy.optimize, 31, 33
scipy.signal, 29
scipy.signal.convolve2d, 29
seuillage, 25
shape, 14
simplexe, 33
slice, 17
slicing, 17, 25
tableau, 13
taille, 14
traitement d’image, 25
transforamtions, 29
transformée de Fourier, 26
transformée de Fourier inverse, 26
transformation géométrique, 30
type, 14
Volterra, 39
46
Index
Téléchargement