TP3 : des listes python aux tableaux numpy.. 1 Mini cours ...

ï»żTP3 : des listes python aux tableaux numpy..

1

1.1

Mini cours avec expe?rimentation sur machine :

Identifiant et affectation

LorsquĄŻon fait lĄŻaffectation a=3.2, le nom de variable a pointe (on peut imaginer un fil) vers

une adresse me?moire avec un nume?ro, et a? cette adresse est stocke?e une valeur. Si on tape :

>>>a=3.2

>>>id(a)

La commande id() donne le nume?ro de la case me?moire ou? est stocke?e la valeur de a.

Si lĄŻon fait lĄŻaffectation ensuite :

b=a

le nom de variable b pointe non pas vers le nom a mais vers lĄŻadresse me?moire vers laquelle pointait

de?ja? a. De?duire de ce qui pre?ce?de les re?ponses donne?es par le shell python aux commandes suivantes

et ve?rifier !

id(b)

a=2

print(b)

id(a)

id(b)

1.2

Comment est repre?sente?e une liste en me?moire

Une liste L = [1, Ą±marcelĄ±, 5.2] a elle aussi un identifiant me?moire. Donc le nom L pointe comme

au paragraphe pre?ce?dent vers une case me?moire.





Ce qui change est le contenu de cette case me?moire !





En effet chaque entre?e de la liste a elle-me?me un identifiant me?moire propre comme on peut le

tester. Essayez :

L=[1,"marcel",5.2]

id(L)

id(L[0])

id(L[1])

id(L[2])

Les numeros dĄŻadresse nĄŻont rien de remarquables a? part quĄŻils sont diffe?rents.

Ce quĄŻil faut savoir : le nom de liste L pointe en fait vers une case contenant la liste

des adresses (des id.) des entre?es de la liste, et pas vers leurs valeurs !

1.3

Ce qui se passe lors de lĄŻaffectation entre listes : la me?me chose...

Pour la liste L du paragraphe pre?ce?dent, si on cre?e une nouvelle liste M par lĄŻaffectation M=L

alors le nom de variable M va pointer vers lĄŻadresse me?moire vers laquelle pointait L exactement

comme au Ąì 1.1. La diffe?rence est que cette adresse me?moire contient elle-me?me une liste dĄŻadresse.

1

1.4

Ce qui est diffe?rent est lĄŻeffet dĄŻune modification de la liste initiale

Exercice important a? faire : Reprendre la liste du Ąì 1.2. Essayez :

Ąń La modification dĄŻune entre?e.

L[0]=12

id(L)

id(L[0])

L[1]=24

id(L)

Morale : Que dire de lĄŻidentifiant me?moire de L quand on modifie une entre?e de L ?

Ąń La modification dĄŻune tranche (slice) :

L=[4,3,5,1]

id(L)

L[0:2]=[5,6,7]

L

id(L)

Morale : Que dire de lĄŻidentifiant me?moire de L quand on modifie toute une tranche de L ?

N.B. Cette fac?on de modifier toute une tranche de la liste est efficace pour programmer le

del() des listes demande? au T.P. 2.

A retenir : toutes ces modifications de L ne sont pas des reaffectations de L car id(L). . .

1.5

Conse?quence pour la copie des listes : les alias

Essayez le code suivant :

L=[4,3,5,1]

M=L

print(M)

L[0:2]=[5,6,7]

print(L)

print(M)

Justifier le re?sultat avec ce qui pre?ce?de.

On dit que la liste M cre?e?e par M=L se comporte comme un alias de L

Moralite? : Ce qui distingue un objet mutable (liste) dĄŻun objet non mutable (int, bool, float,

str, tuple) : a? comple?ter a? lĄŻoral

1.6

Un exemple avec des matrices

On peut coder une matrice comme liste de listes. Par exemple A = [[1, 2], [3, 4]] pour A =

2

).

4

Ainsi A[1] donnera la deuxie?me ligne de A par exemple.

Exercice : On veut cre?er une matrice n ĄÁ n remplies de ze?ros, dont on pourra ensuite modifier

les entre?es, disons pour simplifier n = 10.

1

(

3

2

Une solution pour cre?er une liste forme?e de 0 est X = [0] ? n. On peut ensuite en modifier les

entre?es.

On pourrait se dire que pour un tableau, on peut faire pareil, mais il y a un pie?ge.

Q1 La me?thode suivante semble donner satisfaction pour n = 2 A = [[0, 0]] ? 2. Cependant que

se passe-t-il si on la modifie ensuite via A[0][0] = 1 ? Justifier ce comportement e?trange.

Q2 Trouver une bonne me?thode pour re?pondre a? lĄŻobjectif de lĄŻexercice. (La tester avec n

petit !). Indication : utiliser des boucles.

2

2.1

Comment fabriquer une copie plus autonome dĄŻune liste

La premie?re me?thode : la copie par extraction

On a vu (chap. 1, extraction, slicing) que si L est une liste comme celle de notre exemple, la

commande L[0:2] va fabriquer une nouvelle liste contenant L[0] et L[1].

Ce qui est inte?ressant avec cette commande, cĄŻest que la nouvelle liste ainsi cre?e?e a un identifiant

me?moire diffe?rent de celui de L donc si on extrait toutes les valeur de L, on a une copie du contenu

de L qui est cette fois a? un endroit diffe?rent dans la me?moire.

L=[13,4,5,6]

M=L[0:4]

print(id(L))

print(id(M))

Du coup cette fois, M appara??t bien comme autonome de L puisque

L[0]=45

print(L)

print(M)





Pratique : pour extraire tout le contenu dĄŻune liste L, commande L[:]





2.2

Pourquoi Python appelle-t-il le type de copie pre?ce?dente une shallow copy ?





Shallow copy : copie peu profonde.





La raison est quĄŻon peut faire des listes de listes ! On lĄŻa vu dans lĄŻexemple des matrices ci-dessus

au Ąì 1.6.

Conside?rons le code :

L=[1,2,3]

G=[L,"bidule"]

Gbis=G[:]

N.B. Gbis a un id diffe?rent de G mais il contient la me?me liste dĄŻadresses me?moires.

Exercice : On fait la modification

L[0]=4

Que dire de Gbis[0][0] ? Ve?rifier !

2.3

Comment faire une copie vraiment autonome ? A deep copy

Il y a plusieurs me?thodes. Il serait amusant de programmer cela en descendant les ramifications

de la me?moire. En Python le module copy est disponible pour le faire avec la commande deepcopy.

Exercice Reprendre les donne?es pre?ce?dentes. Importer la fonction deepcopy du module copy.

Cre?er Gter=copy(G). Tester le me?me code quĄŻau Ąì 2.2 :

3

L=[1,2,3]

G=[L,"bidule"]

Gter=copy(G)

L[0]=4

Tester alors Gter[0][0].

3

Introduction a? numpy

3.1

Les tableaux

Le module numpy contient un grand nombre de fonctions permettant du faire du calcul nume?rique

en python.

a) Importer ce module et lister les fonctions correspondantes. Dans la suite on conside?re quĄŻon

a importe? numpy avec le nom np.

N.B. Eviter de faire help(numpy) : elle est tellement longue quĄŻon nĄŻen sort plus ! Par contre,

help(np.nom_dĄŻune_fonction)est utile.

b) Pre?sentation des tableaux de numpy : on dispose dans numpy dĄŻun type array (comme tableau

en anglais), dont les entre?es par de?faut sont des flottants.

Un array peut e?tre re?duit a? une ligne comme A=np.array([1,2]) Il peut e?tre forme? de plusieurs lignes comme M=np.array([[1,2],[3,4]]) On obtient un joli affichage avec print(A) et

print(M).

c) Avec numpy, il est tre?s facile de fabriquer ce quĄŻon a eu du mal a? faire au 1.6 : des tableaux

tout faits remplis de 0 et de 1, quĄŻon peut modifier a? loisir.

Voir lĄŻaide des commandes zeros ou ones.

3.2

Application de fonctions a? un tableau

Pour tracer un graphe de fonctions, on va dĄŻabord cre?er un array contenant toutes les valeurs

en abscisses ou? lĄŻon va faire calculer la fonction.

Une fonction de numpy permet de cre?er une subdivision re?gulie?re dĄŻun intervalle [a, b] en N

points : np.linspace(a,b,N)

Une autre possibilite? est dĄŻutiliser lĄŻe?quivalent numpy du range de Python a? savoir np.arange

qui permet dĄŻavoir des pas non entiers.

Ensuite il faut conna??tre :



Un paradigme de numpy (he?rite? de SciLab, Matlab) : les fonctions numpy peuvent agir

directement sur les tableaux.

Autrement dit on peut utiliser le code suivant :

import numpy as np

X=np.linspace(0,2*np.pi,256)

S=np.sin(X)

On aura alors deux tableaux a? une ligne chacun : X pour les valeurs en abscisses et S pour les

valeurs en ordonne?es correspondantes.

3.3

Le plot de matplotlib

On va utiliser le sous-module pyplot du module matplotlib.

On lĄŻimporte donc via

import matplotlib.pyplot as plt # abrev. standard

On va utiliser la fonction plot de ce (sous)-module. Par de?faut, pour deux arrays X et Y a? une

ligne plot(X,Y) va tracer des segments entre les points (X[i],Y[i]) successifs.

Pour mieux comprendre :

4

import matplotlib.pyplot as plt # abrev. standard

X=np.array([1,2,3])

Y=np.array([3,2,4])

plt.plot(X,Y) # cre?e la courbe mais ne lĄŻaffiche bizarrement pas

plt.show() # affiche la courbe

plt.savefig("essai-courbe.pdf",format=ĄŻpdfĄŻ)# fabrique un pdf dans le re?pert. courant





Pour le graphe de sin sur [0, 2ŠĐ] : Essayez en faisant varier le nombre de points de la subdivision !





X=np.linspace(0,2*np.pi,256)

S=np.sin(X)

plt.plot(X,C) # si on veut voir les points de (X,C) :

plt.show()

4

plt.plot(X,C,ĄŻoĄŻ)

Application a? la me?thode dĄŻEuler

Cadre ge?ne?ral : On fixe un proble?me de Cauchy :

y Ąä (x) = F (x, y(x)), avec la C.I. y(x0 ) = y0

Autrement dit, on se donne la fonction F , et le couple (x0 , y0 ).

Notre exemple : on prendra lĄŻE.D. tre?s simple y Ąä (x) = x.y(x), pour la C.I. y(0) = 1. Autrement dit, (x0 , y0 ) = (0, 1) et F ĄĂ (x, u) ? x.u.

Retour a? la the?orie ge?ne?rale : On suppose que la fonction F est telle quĄŻil y ait une et une

seule fonction solution a? lĄŻE.D. pour la condition initiale y(x0 ) = y0 (Cauchy-Lipschitz).

Le principe de la me?thode dĄŻEuler est le suivant : sur un petit intervalle [x0 , x0 + p] ou? p

sĄŻappelle le pas, et p est pris petit, on va approcher la fonction solution y quĄŻon ne conna??t pas par

la fonction affine de?finissant la tangente au graphe de y, au point dĄŻabscisse x0 , autrement dit par

z0 ĄĂ x ? y0 + y Ąä (x0 )(x ? x0 ).

LĄŻessentiel : on conna??t y Ąä (x0 ) = F (x0 , y0 ).

En notant M0 = (x0 , y0 ), on conside?re alors le segment [M0 , M1 ] sur le graphe de la fonction

affine z0 ou? M1 = (x1 , y1 ) est le point dĄŻabscisse x1 = x0 + p.

Ensuite, au point M1 = (x1 , y1 ) on conside?re le segment partant de M1 et de pente cette fois

F (x1 , y1 ). 1 .

On poursuit ce segment jusquĄŻau point M2 dĄŻabscisse x0 + 2p.

En ite?rant ce proce?de?, on obtient une courbe continue qui est une succession de segments

[Mk , Mk+1 ] avec Mk = (xk , yk ), et dont on espe?re quĄŻelle nĄŻest pas trop loin de la solution y de

lĄŻE.D.

Question 1 šC Donner la formule de re?currence donnant yk+1 en fonction de yk et xk pour

chaque k.

Question 2 šC Ecrire une fonction Python qui prend comme argument F,p,x0,y0,n ou? n est le

nombre de points quĄŻon veut tracer et tracer la solution approche?e au pb. de Cauchy correspondant

avec la me?thode dĄŻEuler. On la testera sur lĄŻexemple donne? ci-dessus, en trac?ant sur le me?me graphe

la solution ? exacte ?.

1. Cette pente est celle de la tangente au graphe de la solution de lĄŻE.D. qui passerait par M1

5

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download