Travaux dirigés de Fortran - LMD
Travaux dirigés de Fortran - LMD
Travaux dirigés de Fortran - LMD
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
École normale supérieure<br />
L3 sciences <strong>de</strong> la planète Terre<br />
<strong>Travaux</strong> <strong>dirigés</strong> <strong>de</strong> <strong>Fortran</strong><br />
2012/2013<br />
Table <strong>de</strong>s matières<br />
1 Conversion entre francs et euros 2<br />
2 Année bissextile 2<br />
3 Nombre <strong>de</strong> jours d’un mois 2<br />
4 Suite <strong>de</strong> Fibonacci 2<br />
5 Somme d’une série 3<br />
6 Âge en jours, heures, minutes, secon<strong>de</strong>s 3<br />
7 Conversion entre un nombre quelconque <strong>de</strong> monnaies 4<br />
8 Quantième d’une date 4<br />
9 Nombres <strong>de</strong> nucléoti<strong>de</strong>s 4<br />
10 Le carré magique 4<br />
11 Recherche par bissection 4<br />
12 Graphique <strong>de</strong> la somme d’une série 6<br />
13 Nombre <strong>de</strong> gènes 6<br />
14 Naissances 6<br />
15 Population 6<br />
16 Attracteur 7<br />
1
Si vous avez besoin <strong>de</strong> consulter la norme <strong>Fortran</strong> 95, par exemple pour<br />
connaître la <strong>de</strong>scription d’une procédure intrinsèque, vous pouvez trouvez sa version<br />
quasi-définitive en ligne : http://j3-fortran.org/doc/standing/archive/<br />
007/97-007r2/pdf/97-007r2.pdf.<br />
1 Conversion entre francs et euros<br />
1. Fichier currency_1.f. Écrivez un programme permettant <strong>de</strong> convertir les<br />
francs en euros. La somme en francs sera <strong>de</strong>mandée à l’utilisateur par le<br />
programme. Le programme donnera la somme en euros. Rappel : 1 e =<br />
6,559 57 F.<br />
2. Fichier currency_2.f. Modifiez le programme pour que l’utilisateur puisse<br />
utiliser la conversion dans les <strong>de</strong>ux sens (euros ⇀↽ francs). L’utilisateur doit<br />
entrer une valeur suivie d’une <strong>de</strong>vise, sous la forme <strong>de</strong> trois lettres : EUR ou<br />
FRA. Le programme reconnaîtra la <strong>de</strong>vise entrée et fera la conversion dans<br />
l’autre <strong>de</strong>vise. Le programme affichera un message d’erreur si la <strong>de</strong>vise<br />
entrée n’est pas une <strong>de</strong>s <strong>de</strong>ux attendues.<br />
2 Année bissextile<br />
Fichier leap_year.f. Écrivez un programme permettant <strong>de</strong> vérifier si une<br />
année est bissextile. L’utilisateur <strong>de</strong>vra entrer une année et le programme <strong>de</strong>vra<br />
lui répondre si cette année est bissextile ou non.<br />
Définition. Pour être bissextile, une année doit avoir son millésime divisible<br />
par 4. Toutefois, une année dont le millésime est divisible par 100 n’est bissextile<br />
que si son millésime est aussi divisible par 400.<br />
Dans le programme, synthétisez le critère “année bissextile” en une seule<br />
expression logique, et utilisez cette expression logique dans un test unique. Procédure<br />
intrinsèque <strong>Fortran</strong> pouvant vous être utile : mod.<br />
3 Nombre <strong>de</strong> jours d’un mois<br />
Fichier month_length.f. Écrivez un programme indiquant, pour un numéro<br />
<strong>de</strong> mois fourni par l’utilisateur, le nombre <strong>de</strong> jours dans ce mois (utilisez ici<br />
l’instruction select case). Pour le mois <strong>de</strong> février, le programme répondra<br />
simplement “28 or 29 days”. Le programme affichera un message d’erreur pour<br />
un numéro <strong>de</strong> mois incorrect.<br />
4 Suite <strong>de</strong> Fibonacci<br />
La suite <strong>de</strong> Fibonacci est définie par :<br />
u 0 = 1<br />
u 1 = 1<br />
u n = u n−1 + u n−2 pour n ≥ 2<br />
2
1. Fichier fibonacci_1.f. Écrivez un programme <strong>de</strong>mandant un indice n et<br />
écrivant la valeur <strong>de</strong> u n . Après le calcul <strong>de</strong> u n , le programme doit re<strong>de</strong>man<strong>de</strong>r<br />
une valeur <strong>de</strong> n à l’utilisateur, pour un nouveau calcul. Le programme<br />
doit s’arrêter si l’utilisateur entre une valeur strictement négative.<br />
2. Fichier fibonacci_2.f. Le calcul <strong>de</strong> u n reste-t-il correct quand n est<br />
grand ? Comment tester dans le programme la validité du calcul ? Si l’utilisateur<br />
<strong>de</strong>man<strong>de</strong> une valeur <strong>de</strong> n trop gran<strong>de</strong>, le programme fera le calcul<br />
jusqu’au plus grand indice possible, affichera le terme correspondant <strong>de</strong> la<br />
suite <strong>de</strong> Fibonacci et re<strong>de</strong>man<strong>de</strong>ra une valeur <strong>de</strong> n.<br />
3. Fichier fibonacci_3.f. Choisir un sous-type entier permettant <strong>de</strong> calculer<br />
u 80 .<br />
Procédures intrinsèques <strong>Fortran</strong> pouvant vous être utiles : selected_int_kind,<br />
huge.<br />
5 Somme d’une série<br />
Soit la série :<br />
Cette série converge vers π 2 /6.<br />
S n =<br />
n∑<br />
i=1<br />
1. Fichier sum_series_1.f. Calculez et affichez la valeur <strong>de</strong> S n pour n donné.<br />
Comment éviter le dépassement <strong>de</strong> valeur maximale d’un entier ? Faites<br />
calculer par le programme la valeur maximale <strong>de</strong> n donnant un résultat<br />
significatif. Procédures intrinsèques <strong>Fortran</strong> pouvant vous être utiles :<br />
floor, sqrt, epsilon, real.<br />
2. Fichier sum_series_2.f. Pour quelle valeur <strong>de</strong> n converge-t-on vers π 2 /6<br />
à ɛ près (la valeur <strong>de</strong> ɛ sera fixée par l’utilisateur) ? Faites un test dans<br />
le programme pour vérifier que la précision <strong>de</strong>mandée peut être atteinte.<br />
Procédure intrinsèque <strong>Fortran</strong> pouvant vous être utile : acos.<br />
3. Fichier sum_series_3.f. Comment modifier ce programme si on ne connaît<br />
pas la valeur <strong>de</strong> convergence <strong>de</strong> la série ?<br />
6 Âge en jours, heures, minutes, secon<strong>de</strong>s<br />
Fichiers age_in_days.f (programme principal) et julian_date.f (procédure).<br />
Écrivez un programme qui :<br />
– <strong>de</strong>man<strong>de</strong> à l’utilisateur sa date <strong>de</strong> naissance exacte (jour et heure) ;<br />
– retourne à l’écran le nombre <strong>de</strong> jours, heures, minutes et secon<strong>de</strong>s qui se<br />
sont écoulés <strong>de</strong>puis sa naissance.<br />
Une solution économique consiste à utiliser la date julienne. La date julienne<br />
est le nombre <strong>de</strong> jours <strong>de</strong>puis le 1 er janvier 4713 avant J.-C., à 12 h, temps<br />
universel, dans un calendrier proleptique grégorien. (Elle est utilisée en astronomie.)<br />
Cf. par exemple http://www.ton<strong>de</strong>ring.dk/claus/cal/julperiod.<br />
php#formula. Écrivez une procédure qui reçoit une date quelconque sous la<br />
forme année, mois etc. et qui calcule la date julienne. Procédures intrinsèques<br />
<strong>Fortran</strong> pouvant vous être utiles : date_and_time, int.<br />
1<br />
i 2<br />
3
7 Conversion entre un nombre quelconque <strong>de</strong><br />
monnaies<br />
Fichier currency_3.f. Modifiez le programme <strong>de</strong> l’exercice 1 pour que l’utilisateur<br />
ait maintenant le choix entre quatre <strong>de</strong>vises : francs, euros, dollars, livres<br />
sterling, et puisse faire une conversion dans n’importe quel sens entre <strong>de</strong>ux <strong>de</strong> ces<br />
<strong>de</strong>vises. On pourra utiliser les chaînes <strong>de</strong> caractères FRA, EUR, USD et GBP<br />
pour i<strong>de</strong>ntifier les <strong>de</strong>vises lors <strong>de</strong>s entrées et sorties. Prendre par exemple : 1 e<br />
= 1,4 $ et 1 £ = 1,25 e. Choisir un algorithme pouvant s’étendre à un nombre<br />
quelconque <strong>de</strong> <strong>de</strong>vises. Procédure intrinsèque <strong>Fortran</strong> pouvant vous être utile :<br />
product.<br />
8 Quantième d’une date<br />
1. Fichier day_number_1.f. Écrivez un programme permettant <strong>de</strong> déterminer<br />
le quantième d’une date (c’est-à-dire le numéro du jour dans l’année).<br />
Le programme <strong>de</strong>man<strong>de</strong>ra à l’utilisateur l’année, le mois et le jour dont<br />
il veut connaitre le quantième. Tenez bien compte <strong>de</strong>s années bissextiles.<br />
Procédure intrinsèque <strong>Fortran</strong> pouvant vous être utile : sum.<br />
2. Fichier day_number_2.f. Écrivez un programme permettant d’effectuer<br />
l’opération inverse. L’utilisateur <strong>de</strong>vra fournir une année et un quantième<br />
et le programme <strong>de</strong>vra indiquer le mois et le jour correspondant.<br />
9 Nombres <strong>de</strong> nucléoti<strong>de</strong>s<br />
Fichier adn_1.f. Une séquence d’ADN est formée d’une succession <strong>de</strong> nucléoti<strong>de</strong>s<br />
: l’adénine, la cytosine, la guanine et la thymine. Les abrévations <strong>de</strong><br />
chacun <strong>de</strong> ces nucléoti<strong>de</strong>s sont A, C, G et T. Le fichier virus.txt contient une<br />
suite <strong>de</strong> nucléoti<strong>de</strong>s du virus “alien27”. Écrire un programme qui comptabilise le<br />
nombre <strong>de</strong> chacun <strong>de</strong>s nucléoti<strong>de</strong>s. Quelles comman<strong>de</strong>s du shell vous permettent<br />
d’obtenir également ce résultat ?<br />
10 Le carré magique<br />
Fichier magic_square.f. Le but est <strong>de</strong> créer un carré magique <strong>de</strong> dimension<br />
N, N étant impair et fourni par l’utilisateur. Le carré magique <strong>de</strong>vra être écrit<br />
dans un fichier sous la forme d’un carré. Des algorithmes <strong>de</strong> fabrication <strong>de</strong> carré<br />
magique sont expliqués sur Wikipédia en Français. Vous pouvez utiliser par<br />
exemple la métho<strong>de</strong> Siamoise. Procédure intrinsèque <strong>Fortran</strong> pouvant vous être<br />
utile : merge.<br />
11 Recherche par bissection<br />
Dans un problème d’interpolation, nous avons à calculer la valeur d’une<br />
fonction f en un point x quelconque, à partir <strong>de</strong> la connaissance <strong>de</strong> la valeur<br />
<strong>de</strong> f en un nombre fini <strong>de</strong> points x i . Avant l’interpolation à proprement parler,<br />
4
nous avons besoin <strong>de</strong> localiser x parmi les x i . C’est sur ce problème particulier<br />
<strong>de</strong> localisation que nous nous penchons ici.<br />
Plus formellement, nous nous donnons un tableau <strong>de</strong> réels xx, indicé <strong>de</strong> 1 à<br />
n, avec n ≥ 2. Nous supposons pour simplifier que les valeurs xx(1), . . . , xx(n)<br />
forment une suite croissante (pas forcément strictement croissante). Cf. figure<br />
(1). Pour un réel x donné, nous cherchons l’indice j tel que x soit compris<br />
x<br />
(xx(0)=-∞)<br />
xx(1) … xx(j) xx(j+1) … xx(n)<br />
(xx(n+1)=+∞)<br />
Figure 1 – Recherche par bissection.<br />
entre xx(j) et xx(j + 1). Nous définissons <strong>de</strong>s éléments fictifs xx(0) = −∞<br />
et xx(n + 1) + ∞ (<strong>de</strong> sorte que xx(0), xx(1), . . . , xx(n), xx(n + 1) est toujours<br />
croissante). Alors il existe toujours un indice j ∈ {0, . . . , n} solution, j = 0 ou<br />
j = n indiquant que la valeur x est hors <strong>de</strong>s limites du tableau xx, d’un côté ou<br />
<strong>de</strong> l’autre.<br />
Nous nous proposons d’effectuer la recherche <strong>de</strong> l’indice j solution par bissection.<br />
Cf. figure (2). L’idée est d’encadrer x entre <strong>de</strong>ux éléments xx(jd) et<br />
1 32 n=64<br />
j=51<br />
Figure 2 – Exemple <strong>de</strong> séquence <strong>de</strong> recherche par bisection. L’axe représente<br />
les valeurs <strong>de</strong>s indices (type entier) et non les valeurs <strong>de</strong>s éléments <strong>de</strong> tableau.<br />
Dans cet exemple, n = 64 et la séquence converge vers l’indice solution j = 51.<br />
xx(ju), et <strong>de</strong> comparer x à xx(jm), où jm est la <strong>de</strong>mi-somme <strong>de</strong> jd et ju. Selon<br />
le résultat <strong>de</strong> la comparaison, on peut remplacer jd ou bien ju par jm. On a<br />
ainsi divisé par <strong>de</strong>ux la longueur <strong>de</strong> l’intervalle d’indices dans lequel se trouve<br />
l’indice solution. C’est donc une démarche itérative.<br />
(Explication <strong>de</strong>s notations : jd, “d” comme down ; ju, “u” comme up ; jm,<br />
“m” comme middle.)<br />
Répon<strong>de</strong>z sur papier aux questions suivantes.<br />
– Écrivez l’invariant <strong>de</strong> boucle correspondant à la recherche par bissection<br />
décrite ci-<strong>de</strong>ssus.<br />
– Quelle est la condition <strong>de</strong> sortie <strong>de</strong> la boucle ?<br />
5
– Écrivez l’initialisation précédant la boucle.<br />
– Écrivez enfin l’algorithme complet, en langage <strong>de</strong> <strong>de</strong>scription d’algorithme.<br />
– Vérifiez que l’algorithme est tel qu’on ne cherche jamais à accé<strong>de</strong>r au<br />
tableau xx avec un indice hors <strong>de</strong> {1, . . . , n}.<br />
La suite <strong>de</strong> l’exercice est à faire sur ordinateur.<br />
– Fichier locate.f. Traduisez en une procédure <strong>Fortran</strong> l’algorithme <strong>de</strong> recherche<br />
par bissection que vous avez écrit. Vous appellerez cette procédure<br />
locate. La procédure locate doit prendre en entrée le tableau xx et la<br />
valeur x et donner comme résultat un indice.<br />
– Fichier test_locate.f. Écrivez un programme principal pour tester la<br />
procédure locate. Le programme définira un tableau pressure_limits<br />
contenant les valeurs :<br />
1e-3, 0.04, 0.8, 1.5, 10., 1000., 1000.<br />
puis <strong>de</strong>man<strong>de</strong>ra à l’utilisateur d’entrer une valeur p au clavier. Le programme<br />
appellera locate pour localiser p dans pressure_limits.<br />
12 Graphique <strong>de</strong> la somme d’une série<br />
Fichier sum_series_4.f. Modifiez le programme du § 5 pour enregistrer<br />
dans un fichier les valeurs <strong>de</strong> n et S n . Représentez l’évolution <strong>de</strong> la série à l’ai<strong>de</strong><br />
du programme Grace ou Gnuplot.<br />
13 Nombre <strong>de</strong> gènes<br />
1. Fichier adn_2.f. Modifiez le programme du § 9 pour qu’il indique le<br />
nombre et la position <strong>de</strong>s occurences du gène constitué par la suite <strong>de</strong><br />
nucléoti<strong>de</strong>s GAG. GAGAG compte pour une seule occurence <strong>de</strong> GAG.<br />
Procédure intrinsèque <strong>Fortran</strong> pouvant vous être utile : all.<br />
2. Fichier adn_3.f. Modifiez le programme pour que l’utilisateur puisse saisir<br />
le gène à rechercher, <strong>de</strong> longueur quelconque.<br />
14 Naissances<br />
Fichier births.f. Écrire un programme permettant <strong>de</strong> saisir et d’enregistrer<br />
dans un tableau le nombre <strong>de</strong> naissances dans une commune pour chaque année<br />
(<strong>de</strong>puis une année donnée). La saisie se terminera lorsque l’utilisateur entrera<br />
control D, la marque <strong>de</strong> fin <strong>de</strong> fichier. Puis affichez le nombre total <strong>de</strong> naissances,<br />
la moyenne, l’écart-type et l’année ayant vu le plus grand nombre <strong>de</strong><br />
naissances. Procédure intrinsèque <strong>Fortran</strong> pouvant vous être utile : maxloc.<br />
15 Population<br />
Fichier population.f. Le fichier recensement.txt contient pour chaque<br />
département (colonne 1) la population en 1999 (colonne 2) et celle en 1990 (colonne<br />
3) (source INSEE). Écrire un programme qui enregistre ces données dans<br />
un tableau à <strong>de</strong>ux dimensions et qui affiche le numéro <strong>de</strong>s départments dont<br />
l’évolution <strong>de</strong> la population entre 1990 et 1999 est soit supérieure à 5 %, soit<br />
6
inférieure à - 5 %. On pourra supposer dans le programme que le nombre <strong>de</strong><br />
départements dans recensement.txt est <strong>de</strong> 99. Le programme <strong>de</strong>man<strong>de</strong>ra ensuite<br />
à l’utilisateur <strong>de</strong> saisir un numéro <strong>de</strong> départment et affichera l’évolution<br />
<strong>de</strong> sa population et son rang en terme <strong>de</strong> nombre d’habitants en 1999 et 1990.<br />
On pourra supposer dans le programme que les départements apparaissent dans<br />
recensement.txt dans l’ordre croissant <strong>de</strong> leurs numéros. Procédures intrinsèques<br />
<strong>Fortran</strong> pouvant vous être utiles : abs, count.<br />
16 Attracteur<br />
Fichier attractor.f. Écrivez un programme qui permette d’enregistrer dans<br />
un fichier les termes <strong>de</strong> la suite suivante :<br />
avec :<br />
x n+1 = by n + f(x n )<br />
y n+1 = −x n + f(x n+1 )<br />
f(x) = ax +<br />
2(1 − a)x2<br />
1 + x 2<br />
et les conditions initiales x 0 = 0,09 et y 0 = 2,76 et les constantes a = −0,6 et<br />
b = 0,99. Écrivez la fonction f dans une procédure <strong>de</strong> type function. Utilisez<br />
Grace ou Gnuplot pour visualiser le résultat pour différentes valeurs <strong>de</strong> n. Vous<br />
pourrez tester l’influence <strong>de</strong>s valeurs <strong>de</strong> x 0 et y 0 .<br />
7