Vous êtes sur la page 1sur 9

Numéro d’anonymat : 1 2011-03-08 21 :33 :26.

000000000

Reportez votre numéro d’anonymat dans le cadre ci-dessous et en haut à gauche de chaque page de
l’énoncé.

A la fin de l’épreuve glissez ce cahier dans la copie double qui vous a été fournie, qui comporte
votre numéro d’anonymat et sur laquelle vous aurez écrit et masqué votre nom en rabattant dessus
et en collant la languette triangulaire. Vous ne devez rien écrire d’autre sur cette copie double.

Numéro d’anonymat :

UNIVERSITE DE PARIS SUD Centre d’Orsay 2010-2011 première session d’examen

L3 et Magistère 1ère année de Physique fondamentale

Examen d’informatique 28 Février 2011 9h à 11h bât. 337 salle 3

Aucun document n’est autorisé.


Les programmes doivent être écrits en C/C++. Les réponses doivent obligatoirement être écrites sur les feuilles
de l’énoncé, dans l’espace réservé. Il est fortement conseillé de rédiger d’abord le plan des réponses au brouillon.
Respecter les notations de l’énoncé : par exemple la variable notée nt dans l’énoncé devra être écrite nt dans un
programme, n′′ devra être écrite ns.
Ne pas commencer à répondre à un exercice avant de l’avoir entièrement lu.
L’utilisation de fonctions est laissée à l’appréciation de l’étudiant, sauf quelques cas où elle est imposée.
On suppose que tous les #include<stdlib.h> ... #include<bibli fonctions.h> using namespace std ; nécessaires
sont sous-entendus, il n’y a pas à les écrire.
On rappelle qu’on ouvre un fichier en écriture par l’instruction : fstream xxx("nom de fichier.qqc",ios : :out) ;
et en lecture par : fstream yyy("nom de fichier.qqc",ios : :in) ;
Ne pas faire lire les données au clavier ou dans un fichier par un cin >>, ou l’équivalent pour un fichier, sauf si
cela est explicitement demandé. Par défaut, les données seront donc fournies dans le programme lui-même, par
des instructions du type :
dx=0.01;
a=1.7; b=1.1;
etc.
Dans chaque exercice on suppose que le programme principal1 et les fonctions2 sont écrits dans un unique fichier.
Les exercices sont indépendants les uns des autres.
Le nombre d’étoiles (de zéro à trois) donne une indication sur le niveau de l’exercice.
Le nombre de points (sur 40) attribué à chaque exercice est indiqué entre parenthèses après le nom de l’exercice
(c’est un barème indicatif ). Deux points sont réservés à la qualité de la présentation.
A titre indicatif le nombre de lignes du corrigé de chaque exercice est indiqué entre crochets (tout compris, c’est
à dire avec int main(), les accolades, return 0 ;, des commentaires éventuels).
Le corrigé pourra être consulté sur le site du cours.

1 s’il y en a un
2 s’il y en a

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 2 2011-03-08 21 :33 :26.000000000

Droite des moindres carrés * (6) [23 lignes]


On mesure une grandeur y en fonction d’une autre grandeur x. On obtient n points expérimentaux xi , yi , chaque
valeur de yi étant mesurée avec une incertitude ±σi . On cherche la droite y = ax + b qui passe au plus près des points
expérimentaux au sens des moindres carrés.

20

15

10

-5
0 1 2 3 4 5 6 7 8 9

Fig. 1 –

Les valeurs de a et b et leurs incertitudes sont données par les formules suivantes :
r r
1 c2 1 c1
a= (c4 c2 − c5 c3 ) ∆a = b= (c5 c1 − c4 c3 ) ∆b =
∆ ∆ ∆ ∆
avec :
n n n n n
X x2i X 1 X xi X xi yi X yi
c1 = c2 = c3 = c4 = c5 = ∆ = c1 c2 − c23
σ2
i=1 i
σ
i=1 i
2 σ
i=1 i
2
i=1
σi2 σ
i=1 i
2

Question : on suppose que les résultats des mesures sont écrits dans le fichier nommé mc.dat en mettant un triplet
xi , yi , σi par ligne comme dans l’exemple suivant :
0.9 0.8 1.5
1.8 3.9 1.8
3.1 4.7 1.9
...
Écrire un programme qui lit les valeurs dans le fichier m c.dat et affiche à l’écran les valeurs de a, ∆a, b, ∆b. Comme
on ne connaı̂t pas à priori le nombre de mesures donc le nombre de lignes du fichier, on lira les valeurs par une
boucle :
while(dat >> x >> y >> sig)
le fichier de données ayant été ouvert par :
fstream dat("m c.dat",ios : :in) ;

Réponse à la question :
int main()
{
double xx,yy,sig,c1,c2,c3,c4,c5,ss,a,da,b,db,del;
c1=0; c2=0; c3=0; c4=0; c5=0;
fstream dat("m_c.dat",ios::in);
while(dat >> xx >> yy >> sig)
{

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 3 2011-03-08 21 :33 :26.000000000

ss=sig*sig; c1=c1+xx*xx/ss; c2=c2+1/ss; c3=c3+xx/ss; c4=c4+xx*yy/ss; c5=c5+yy/ss;


}
del=c1*c2-c3*c3;
a=(c4*c2-c5*c3)/del;
da=sqrt(c2/del);
b=(c5*c1-c4*c3)/del;
db=sqrt(c1/del);
cout << "a=" << a << " da=" << da << " b=" << b << " db=" << db << endl;
return 0;
}

Distance minimale d’un ensemble de points ** (10) [31 lignes]


Soit (E) un ensemble de n (on prendra par exemple n = 8) points répartis aléatoirement selon une distribution
uniforme dans un carré de côté 1.

Question 1 : [17 lignes] écrire un programme qui génère cet ensemble par tirage aléatoire et calcule la distance d
séparant les deux points de (E) les plus proches l’un de l’autre.
Réponse à la question :
int main()
{
const int n=8;
int i,j;;
double x[n],y[n],dd,dmin,ddmin,dmax,ddmax;
ddmax=2; dmax=sqrt(ddmax);
for(i=0;i<n;i++){x[i]=drand48(); y[i]=drand48();}
ddmin=ddmax;
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
dd=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
if(dd<ddmin) ddmin=dd;
}
}
dmin=sqrt(ddmin);
cout << "dmin=" << dmin << endl;
return 0;
}
On peut utiliser aussi bien drand48() ou alea().
Question 2 : [14 lignes] on considère maintenant p (on prendra par exemple p = 100000) ensembles du type de (E),
notés (Ei ), chacun étant généré par un nouveau tirage aléatoire. La distance des deux points les plus proches de (Ei )
est notée di . Écrire une suite au programme de la question 1 qui calcule la valeur moyenne et q l’écart type des di et
constitue leur distribution statistique dans un tableau. On rappelle que l’écart type peut s’écrire < d2i > − < di >2 ,
le symbole <> désignant la valeur moyenne.
Réponse à la question :
int main()
{
const int n=8; // Ce sont les lignes 1 à 4
int i,j; // du programme de la question 1
double x[n],y[n],dd,dmin,ddmin,dmax,ddmax; // ce n’était pas nécessaire de
ddmax=2; dmax=sqrt(ddmax); // les ré-écrire
const int ntr=100;

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 4 2011-03-08 21 :33 :26.000000000

int k,l,ntir=100000,nn[ntr];
double moy=0,moy2=0;
for(i=0;i<ntr;i++) nn[i]=0;
for(k=1;k<=ntir;k++)
{
for(i=0;i<n;i++){x[i]=drand48(); y[i]=drand48();} // Ce sont les lignes 7 à 17
ddmin=ddmax; // du programme de la question 1
for(i=0;i<n;i++) // ce n’était pas nécessaire de
{ // les ré-écrire
for(j=0;j<i;j++) //
{ //
dd=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); //
if(dd<ddmin) ddmin=dd; //
} //
} //
dmin=sqrt(ddmin); //
moy=moy+dmin; moy2=moy2+ddmin;
l=dmin/dmax*ntr;
if(l<0) l=0; else if(l>=ntr) l=ntr-1;
nn[l]=nn[l]+1;
}
cout << "ntir=" << ntir << " moyenne=" << moy/ntir << " écart type=" << sqrt(moy2/ntir-moy*moy/ntir/nt
for(i=0;i<ntr;i++) cout << i << " " << nn[i] << endl;
return 0;
}
On peut aussi mettre le programme de la question 1 sous forme d’une fonction double d(const int n) qui, à
chaque fois qu’elle est appelée, crée un nouvel ensemble (E) et a pour valeur la valeur de d associée à ce nouvel
√ (E).
Le tracé, qui n’était pas demandé, de la distribution statistique des di , donne, sur l’intervalle [0, dmax = 2] :

12000

10000

8000

6000

4000

2000

0
0 10 20 30 40 50 60 70 80 90 100

Fig. 2 –

Question 3 : [1 ligne] que faudrait-il modifier dans les programmes précédents si les points des (Ei ) étaient répartis
aléatoirement selon une distribution uniforme dans un cercle de rayon 1 et non plus un carré de côté 1 ?
Réponse à la question :
Il suffirait d’ajouter un test pour n’accepter le point que s’il se trouve à l’intérieur du cercle de rayon 1. La ligne :

for(i=0;i<n;i++){x[i]=drand48(); y[i]=drand48();}
serait remplacée par :
for(i=0;i<n;i++){do {x[i]=2*drand48()-1; y[i]=2*drand48()-1;} while(x[i]*x[i]+y[i]*y[i]>1);}

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 5 2011-03-08 21 :33 :26.000000000

Fonctions * (8)
Indiquer les résultats affichés à l’écran par les huit programmes suivants. Les seules lignes qui diffèrent entre deux
programmes écrits côte à côte sont repérées par //. Tous ces programmes sont sans erreur et fournissent un résultat.
Question 1 :
void f(int y) void f(int *y) //
{ {
y=y+1; *y=*y+1; //
} }
int main() int main()
{ {
int x; int x;
x=0; x=0;
cout << x << endl; cout << x << endl;
f(x); f(&x); //
cout << x << endl; cout << x << endl;
return 0; return 0;
} }

Réponse : Réponse :
0 0
0 1

Question 2 :
void f(int y[],int p) void f(int *y,int p) //
{ {
int i; int i;
for(i=0;i<p;i++) y[i]=y[i]+1; for(i=0;i<p;i++) y[i]=y[i]+1;
} }
int main() int main()
{ {
const int n=2; const int n=2;
int i; int i;
int x[n]; int x[n];
for(i=0;i<n;i++) x[i]=i; for(i=0;i<n;i++) x[i]=i;
for(i=0;i<n;i++) cout << x[i] << " "; for(i=0;i<n;i++) cout << x[i] << " ";
cout << endl; cout << endl;
f(x,n); f(x,n);
for(i=0;i<n;i++) cout << x[i] << " "; for(i=0;i<n;i++) cout << x[i] << " ";
cout << endl; cout << endl;
return 0; return 0;
} }

Réponse : Réponse :
0 1 0 1
1 2 1 2

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 6 2011-03-08 21 :33 :26.000000000

Question 3 :
void f(int *y,int p) void f(int y[],int p) //
{ {
int i; int i;
for(i=0;i<p;i++) y[i]=y[i]+1; for(i=0;i<p;i++) y[i]=y[i]+1;
} }
int main() int main()
{ {
int n=2; int n=2;
int i; int i;
int *x=(int *)malloc(n*sizeof(int)); int *x=(int *)malloc(n*sizeof(int));
for(i=0;i<n;i++) x[i]=i; for(i=0;i<n;i++) x[i]=i;
for(i=0;i<n;i++) cout << x[i] << " "; for(i=0;i<n;i++) cout << x[i] << " ";
cout << endl; cout << endl;
f(x,n); f(x,n);
for(i=0;i<n;i++) cout << x[i] << " "; for(i=0;i<n;i++) cout << x[i] << " ";
cout << endl; cout << endl;
return 0; return 0;
} }

Réponse : Réponse :
0 1 0 1
1 2 1 2

Question 4 :
void f() void f()
{ {
int i=0; static int i=0; //
cout << i << endl; cout << i << endl;
i=i+1; i=i+1;
cout << i << endl; cout << i << endl;
} }
int main() int main()
{ {
f(); f();
f(); f();
return 0; return 0;
} }

Réponse : Réponse :
0 0
1 1
0 1
1 2

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 7 2011-03-08 21 :33 :26.000000000

Équation différentielle du premier ordre * (4) [17 lignes]


Question : écrire un programme qui calcule, par la méthode d’Euler, et affiche à l’écran, une valeur approchée de
la solution y(x) de l’équation différentielle :

y ′ = xy(xy − 1)(xy − 2) avec la condition initiale y(0) = 1

en np points répartis à intervalles réguliers de x = 0 à x = 10.


Réponse à la question :
int main()
{
int i,np;
double x,xfin,dx,y,z;
np=100000; xfin=10;
dx=xfin/(np-1);
x=0; y=1;
for(i=1;i<=np;i++)
{
cout << x << " " << y << endl;
z=x*y;
y=y+dx*z*(z-1)*(z-2);
x=x+dx;
}
return 0;
}
On obtient la courbe suivante, qui n’était pas demandée :

1.4

1.2

0.8

0.6

0.4

0.2

0
0 1 2 3 4 5 6 7 8 9 10

Fig. 3 –

Tir d’un obus *** (12)


On considère un obus lancé dans le champ de gravitation de la Terre. Celle-ci est supposée isolée dans l’espace, il
existe donc un repère galiléen Oxyz dont l’origine O coı̈ncide avec le centre de la Terre. L’obus est repéré par ses
coordonnées sphériques r(t), θ(t), ϕ(t) dans Oxyz 3 , qui d’après la relation fondamentale de la dynamique, satisfont
3 Dans cet exercice on ne s’occupe pas des coordonnées de l’obus dans un repère lié à la Terre qui tournerait avec celle-ci, contrairement

au repère Oxyz.

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 8 2011-03-08 21 :33 :26.000000000

au système différentiel de trois équations du second ordre à trois fonctions inconnues suivant :
GMt  
r̈ = − 2
+ r θ̇2 + ϕ̇2 sin2 θ
r
2ṙθ̇ ϕ̇2 sin 2θ
θ̈ = − +
r 2 !
ṙ θ̇
ϕ̈ = −2ϕ̇ +
r tan θ

avec :
G constante de la gravitation universelle
Mt masse de la Terre
Question 1 : [6 lignes] écrire ce système sous la forme d’un système de six équations du premier ordre à six fonctions
inconnues (ce n’est pas une question de programmation mais de ré-écriture mathématique des équations).
Réponse à la question :
On pose rp = ṙ, θp = θ̇, ϕp = ϕ̇ et le système précédent peut s’écrire :

ṙ = rp
θ̇ = θp
ϕ̇ = ϕp
GMt
+ r θp2 + ϕ2p sin2 θ

r˙p = − 2
r
2rp θp ϕ2p sin 2θ
˙
θp = − +
r  2 
rp θp
ϕ˙p = −2ϕp +
r tan θ

Question 2 : [26 lignes] écrire un programme qui calcule une valeur approchée, par la méthode d’Euler, de r(t),
θ(t), ϕ(t), ṙ(t), θ̇(t), ϕ̇(t), pour np instants répartis à intervalles réguliers de t = 0 à t = tfin . Les variables contenant
les valeurs des conditions initiales r(0), θ(0), ϕ(0), ṙ(0), θ̇(0), ϕ̇(0) sont notées respectivement r0, tet0, phi0, rp0,
tetp0, phip0 dans le programme. Les valeurs de t, r(t), θ(t), ϕ(t) seront écrites dans un fichier en mettant un
quadruplet par ligne de façon à obtenir par exemple :
0 6.371e+06 0.785398 0
0.00300003 6.371e+06 0.785398 2.18168e-07
0.00600006 6.37101e+06 0.785398 4.36336e-07
...
La déclaration des variables np, G, Mt, tfin, r0, tet0, phi0, rp0, tetp0, phip0 est déjà écrite dans la réponse et
leur initialisation est supposée déjà faite par des valeurs numériques symbolisées par .... Le candidat n’a donc pas
à faire cette initialisation. Les autres variables devront être déclarées à la suite.
Le programme peut être écrit avec ou sans fonctions mais la lisibilité et la brièveté seront appréciées.
Réponse à la question :
Pour permettre une écriture plus condensée avec des boucles on pose q0 = r, q1 = θ, q2 = ϕ, q3 = rp , q4 = θp ,
q5 = ϕp .
int main()
{
int np=...;
double G=...,Mt=...,tfin=...;
double r0=...,tet0=...,phi0=...,rp0=...,tetp0=...,phip0=...;
const int n=6; int i,j;
double q[n],qp[n];
double t,dt,x;
q[0]=r0; q[1]=tet0; q[2]=phi0; q[3]=rp0; q[4]=tetp0; q[5]=phip0;
dt=tfin/(np-1);

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session
Numéro d’anonymat : 9 2011-03-08 21 :33 :26.000000000

t=0;
fstream res("obus_spheriques_euler.res",ios::out);
for(i=1;i<=np;i++)
{
res << t << " " << q[0] << " " << q[1] << " " << q[2] << endl;
for(j=0;j<3;j++) qp[j]=q[j+3];
x=q[0]*q[5]*q[5]*sin(q[1]);
qp[3]=-G*Mt/q[0]/q[0]+q[0]*q[4]*q[4]+x*sin(q[1]);
qp[4]=(-2*q[3]*q[4]+x*cos(q[1]))/q[0];
qp[5]=-2*q[3]*q[5]/q[0]-2*q[4]*q[5]/tan(q[1]);
for(j=0;j<n;j++) q[j]=q[j]+dt*qp[j];
t=t+dt;
}
return 0;
}
Question 3 : [1 ligne] l’énergie totale de l’obus divisée par sa masse s’écrit :

1h 2  i GM
t
ṙ + r2 θ̇2 + sin2 (θ)ϕ̇2 −
2 r
Comment peut-on utiliser cette quantité pour vérifier partiellement la justesse du calcul ?
Réponse à la question :
L’énergie totale de l’obus est conservée, sa masse est une constante, on peut donc vérifier avec quelle précision le
calcul respecte cette conservation. Cette précision est évidemment meilleure si on fait le calcul par Runge-Kutta
d’ordre 4 plutôt qu’avec Euler.

Licence et Magistère 1ère année de Physique fondamentale Examen d’informatique 2010-2011 première session

Vous aimerez peut-être aussi