07.08.2014 Views

Travaux dirigés de Fortran - LMD

Travaux dirigés de Fortran - LMD

Travaux dirigés de Fortran - LMD

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!