IPT MPSI DS3 Corrige
IPT MPSI DS3 Corrige
IPT MPSI DS3 Corrige
‚ Les programmes demandés seront écrits en langage Python. Prière de faire figurer clairement les
niveaux d’indentation à l’aide de barres verticales comme expliqué en cours.
‚ Plus généralement, la clarté du raisonnement, la rédaction, la précision du discours, la mise en
page, la présentation, le soin et l’orthographe seront pris en compte. Laissez une marge à gauche !
‚ Questions dans l’ordre et bien numérotées.
‚ Les calculatrices et téléphones portables sont interdits durant l’épreuve.
‚ Je voudrais vous corriger en rouge, donc n’utilisez pas cette couleur sur votre copie.
Les parties du devoir sont complètement indépendantes.
1 (4 points) Compléter les réponses de la console marquées de xxxxxxxxx (ces réponses peuvent
s’étaler sur plusieurs lignes. . . )
1 >>> A = np.random.randint(-10,11,(8,8))
2 >>> print(A)
3 [[ -8 -10 -10 2 4 -8 -9 -9]
4 [ 10 -7 1 -8 10 10 -9 -4]
5 [-10 8 -9 -8 9 9 1 8]
6 [ -9 9 0 7 -5 2 -9 -2]
7 [ 0 -1 -3 6 10 1 -8 10]
8 [ 7 -8 3 3 -9 3 7 3]
9 [ -9 4 -1 -5 -9 -7 -7 -3]
10 [ -8 -3 -1 7 3 6 -7 6]]
11 >>> print(A[1:3,2:4])
12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
13 >>> print(A[-4:,:7])
14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
15 >>> print(A[6:7,6:7])
16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
17 >>> print(A[6,6:7])
18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
19 >>> print(A[6:7,6])
20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1
21 >>> print(A[6,6])
22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
23 >>> print(A[:,-1:])
24 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
25 >>> print([ [A[i][j] for j in range(8) if i+j>7 ] for i in range(8) if i
%3==0 ])
26 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1 >>> A = np.random.randint(-10,11,(8,8))
2 >>> print(A)
3 [[ -8 -10 -10 2 4 -8 -9 -9]
4 [ 10 -7 1 -8 10 10 -9 -4]
5 [-10 8 -9 -8 9 9 1 8]
6 [ -9 9 0 7 -5 2 -9 -2]
7 [ 0 -1 -3 6 10 1 -8 10]
8 [ 7 -8 3 3 -9 3 7 3]
9 [ -9 4 -1 -5 -9 -7 -7 -3]
10 [ -8 -3 -1 7 3 6 -7 6]]
11 >>> print(A[1:3,2:4])
12 [[ 1 -8]
13 [-9 -8]]
14 >>> print(A[-4:,:7])
15 [[ 0 -1 -3 6 10 1 -8]
16 [ 7 -8 3 3 -9 3 7]
17 [-9 4 -1 -5 -9 -7 -7]
18 [-8 -3 -1 7 3 6 -7]]
19 >>> print(A[6:7,6:7])
20 [[-7]]
21 >>> print(A[6,6:7])
22 [-7]
23 >>> print(A[6:7,6])
24 [-7]
25 >>> print(A[6,6])
26 -7
27 >>> print(A[:,-1:])
28 [[-9]
29 [-4]
30 [ 8]
31 [-2]
32 [10]
33 [ 3]
34 [-3]
35 [ 6]]
36 >>> print([ [A[i][j] for j in range(8) if i+j>7 ] for i in range(8) if i
%3==0 ])
37 [[], [2, -9, -2], [-1, -5, -9, -7, -7, -3]]
2 (2 points) Ecrire la matrice représentée par le tableau numpy affichée par le court programme
suivant (abs, c’est la valeur absolue. . . ).
2
1 import numpy as np
2 print(np.array( [[ abs(i-j)+1 for j in range(4) ] for i in range(4) ] ))
1 [[1 2 3 4]
2 [2 1 2 3]
3 [3 2 1 2]
4 [4 3 2 1]]
donc ¨ ˛
1 2 3 4
˚ 2 1 2 3 ‹
˚ ‹.
˝ 3 2 1 2 ‚
4 3 2 1
3 (3 points) Ecrire une fonction bezout(a,b) renvoyant un triplet (u,v,d), où d “ PGCDpa, bq, et
au ` bv “ d (a, b ě 0, pa, bq ‰ p0, 0q).
1 def algo14(a,b):
2 (r1,u1,v1,r2,u2,v2)=(a,1,0,b,0,1)
3 while r2!=0:
4 q=r1//r2
5 (r1,u1,v1,r2,u2,v2)=(r2,u2,v2,r1-q*r2,u1-q*u2,v1-q*v2)
6 return r1,u1,v1
7
8 a,b=87,19
9 d,u,v=algo14(a,b) # on vient de déconstruire un tuple
10 print(a*u+b*v==d)
11 print("coeffs trouvés:",u,v)
Le théorème de Bézout assure l’existence d’une solution pu0 , v0 , dq. On peut alors montrer que les
solutions sont exactement les triplets de la forme
3
14 u,v,d=bezout(a,b)
15 print(a*u+b*v==d)
7 (3 points) Reproduire et compléter le tableau suivant qui donne les valeurs des variables utilisées
tout au long du déroulement de l’algorithme pour N “ 13 et x “ 3.
i r N x
0 1 13 3
1
.. .. .. ..
. . . .
La variable i est l’indice de l’itération : les valeurs des variables pour i “ 0 sont celles avant le premier
tour de boucle, puis pour i “ 1 à la fin du premier tour, pour i “ 2 à la fin du deuxième tour, etc.
Votre tableau comportera autant de lignes que nécessaires.
4
Entourez le résultat renvoyé par l’algorithme.
i r N x
0 1 13 3
1
1 3 “3 6 32
2 31 “ 3 3 34
3 31 ˆ 34 “ 243 1 38
Remarquons que si on décompose 13 en binaire en parallèle, les calculs sont les mêmes :
13 “2ˆ6`1
6 “2ˆ3`0
3 “2ˆ1`1
1 “1ˆ1`0
L’action de multiplier r ou non dépend de la présence d’un 1 ou d’un 0 dans l’écriture en binaire, et x
`
contient les puissances 3p2 q successives.
8 (2 points) Expliquez pourquoi le quotient de N dans la division euclidienne par 2 est N {2 si N est
pair et pN ´ 1q{2 si N est impair.
Si N est pair, alors N “ 2k, avec k “ N {2 le quotient recherché.
Si N est impair, alors N “ 2k ` 1, avec k “ pN ´ 1q{2 le quotient recherché.
— et si N est impair, alors a0 “ 1, et le quotient est pN ´ 1q{2, encore égal à la même chose.
Donc la réponse est toujours : ran´1 , an´2 , .., a1 s .
En fait, pour diviser par 2, on supprime le dernier chiffre binaire. Pour comprendre : de la même
manière, prendre le quotient dans la division euclidienne par 10 revient à supprimer le dernier chiffre
décimal.
— Le quotient dans la division euclidienne de 1011102 par 2 est 10111.
— Le quotient dans la division euclidienne de 17893810 par 10 est 17893.
x̃Ñ “ r ˆ xN ,
5
où x, N et r sont les valeurs courantes des variables x et N et r, et x̃ et Ñ sont les valeurs initiales
(c’est-à-dire les valeurs passées en argument à la fonction).
Il s’agit de l’algorithme d’exponentiation rapide, qui utilise le paradigme de programmation “diviser
pour régner”. Il s’agit d’un algorithme beaucoup plus astucieux que la méthode naı̈ve pour le calcul des
puissances.
En MP, et en option informatique en MPSI, on donnera une version récursive plus “naturelle” de cet
algorithme.
Avant le premier tour de boucle, x̃Ñ “ 1 ˆ xN , ce qui initialise la récurrence.
Notons r, x, N les valeurs des variables locales à la fin d’un tour de boucle, pour lesquelles la proposition
est vérifiée, et rp, x
p, N
p les valeurs à la fin du tour de boucle suivant.
N ´1
Si N est impair, alors N//2 “ et
2
` ˘p N ´1 q
rp ˆ x pN “ xr x2 2 “ rxN “ x̃Ñ .
p
N
Et N est pair, alors N//2 “ et
2
` ˘p N q
pN “ r x2 2 “ rxN “ x̃Ñ .
rp ˆ x
p
Concluons : à la fin du dernier tour, N “ 0, donc r “ x̃Ñ . C’est donc que r à la fin de l’algorithme
est égal à x̃Ñ .
11 (3 points) Montrer que le nombre de bits n de N est équivalent à log2 pN q lorsque N tend vers
l’infini.
N a n chiffres en base b ssi bn´1 ď N ă bn ô n ´ 1 ď logb N ă n.
Donc n „ logb pN q.
En particulier, le nombre de bits de N est équivalent à log2 N .
Si on veut être plus précis (mais ce n’est pas demandé), à chaque tour de boucle, 2 multiplications
sont effectuées si N est impair, et 1 seule si N est pair. Ainsi, le nombre de produits faits par l’algorithme
d’exponentiation rapide est
n´1
ÿ
f pN q “ n ` ak .
k“0
Autrement dit, en notant #1 le nombre de 1 dans l’écriture binaire de N , et #0 le nombre de 0, le
nombre de multiplications est
#0 ` 2 ¨ #1 “ n ` #1.
On obtient donc n ` 1 ď f pN q ď 2n.
13 (4 points) Etudiez le pire et le meilleur cas. Donner une valeur de N à n bits pour le meilleur cas ;
et pour le pire cas.
6
— Le pire cas (le plus grand nombre de multiplications) avec N à n bits correspond à N “ r1, 1, 1 ¨ ¨ ¨ , 1s2 “
2n ´ 1, et 2n multiplications sont alors effectuées (n multiplications par x et n carrés ; plus
précisément, n appels récursifs avec N ą 0, et à chacun de ces appels, 1 multiplication par x
et 1 carré).
— Le meilleur cas (le plus petit nombre de multiplications) avec N à n bits correspond à N “
r1, 0, ¨ ¨ ¨ , 0s2 “ 2n´1 . et n`1 multiplications sont alors effectuées (n carrés et 1 seule multiplication
par x ; plus précisément, n appels récursifs avec N ą 0, et à chacun de ces appels 1 carré, et 1
multiplication par x au dernier appel).
7
4 Une équation différentielle (22 points)
On s’intéresse à l’équation différentielle : pEq y 1 “ ´y 2 .
Soit I un intervalle ouvert de R, et a P I.
Soit ϕ une solution de pEq sur I telle que ϕpaq “ 0.
Soit t P I, t ě a. On pose M “ supra,ts |ϕ| (M dépend de t).
żt
14 (3 points) Montrer que |ϕptq| ď M |ϕpxq|dx.
a
Une solution ϕ sur I est dérivable sur I, donc continue sur I, donc ϕ1 “ ´ϕ2 est continue.
Donc d’après le théorème fondamental de l’analyse :
żt żt
ϕptq “ 1
ϕ “ ´ϕ2
a a
pM pt ´ aqqn
15 (3 points) Montrer que pour tout n P N, |ϕptq| ď M .
n!
Par récurrence sur N.
— La proposition au rang 0 découle de la définition de M .
— Supposons que pour un certain n P N, la proposition à démontrer soit vraie.
En injectant dans l’inégalité de la question précédente, on obtient :
M pM px ´ aqqn pM pt ´ aqqn`1
żt
|ϕptq| ď M dx “ M ,
a n! pn ` 1q!
donc la proposition à démontrer est vraie au rang n ` 1.
Finalement, la proposition à démontrer est vraie pour tout n P N.
An
16 (3 points) Montrer que pour tout A P R, ÝÑ 0.
n! nÑ`8
Soit N P N tel que N ą |A|.
Pour tout n ě N , on a :
ˆ ˙ˆ ˙
An AA A A A A
“ ¨¨¨ ¨¨¨
n! 1 2 N ´1 N N `1 n
Donc ˇ nˇ ˇ ˇn´N `1
ˇA ˇ N ´1 ˇ
|A| ˇAˇ
ˇ
ˇ ˇď
ˇ n! ˇ pN ´ 1q! ˇ N ˇ ,
ˇ ˇ ˇ ˇn
ˇAˇ ˇAˇ
et comme ˇˇ ˇˇ ă 1, ˇ ˇ ÝÑ 0, ce qui permet de conclure.
N ˇ N ˇ nÑ`8
8
18 (3 points) Montrer que sur l’intervalle r0, 5s, il existe une unique solution f de E telle que f p0q “ 1
et en donner une expression.
Cette solution ne s’annule pas en 0, donc ne s’annule pas du tout (d’après la question précédente).
On obtient alors
f 1 ptq
´ “1
f ptq2
donc
1
“t`K
f ptq
où K est constante, c’est-à-dire encore :
1
f ptq “ .
t`K
Avec la condition initiale, on trouve K “ 1, donc
1
f ptq “ .
t`1
19 (2 points) Ecrire la formule donnant les points ptk q0ďkďn d’une subdivision régulière de r0, 5s en n
sous-intervalles.
5 5
Pour k P v0, nw, tk “ kh “ k (on a posé h “ le pas de la subdivision).
n n
On désire calculer une valeur de f (on suppose qu’on ne connaı̂t pas son expression !) aux points tk .
On notera yk la valeur approchée de f ptk q obtenue avec la méthode d’Euler classique vue en cours.
20 (2 points) Donner la formule de récurrence pour calculer les yk . On ne demande pas de justification.
y0 “ 1, et pour tout k P v0, n ´ 1w, yk`1 “ yk ´ hyk2 “ yk p1 ´ hyk q, où h a été donné à la réponse
précédente.
21 (4 points) Ecrivez un programme Python pour calculer les tk et les yk (que vous stockerez dans
des listes ou dans des tableaux numpy).
1 def Euler(n):
2 h=5/n
3 Lt = [ k * h for k in range(n+1) ]
4 Ly = [1]
5 for k in range(n):
6 yk=Ly[-1]
7 Ly.append( yk - h * yk**2)
8 return Lt,Ly
9
10 import matplotlib.pyplot as plt
11 for n in [5,7,10,30,40]:
12 Lt,Ly=Euler(n)
13 plt.plot(Lt,Ly,label="méthode d’Euler avec n="+str(n)+" intervalles",linewidth
=3)
14
15 import numpy as np
16 Lt=np.linspace(0,5)
17 plt.plot(Lt,1/(1+Lt), linewidth=4,label=’solution exacte’)
9
18
19 plt.legend()
20 plt.show()
5 Bonus (4 points)
10