Boo
./1
- Posté le 23/06/2009 à 19:05 Membre depuis le 30/05/2006, 12583 messages
Il doit y avoir un truc que je ne comprends pas. Je compile le programme suivant avec ifort:
program testrand
c -------------------------------
intrinsic random_number
real harvest
integer i
c -------------------------------
do i=1,10
call random_number(harvest)
print *, harvest
enddo
c
end program testrand

J'obtiens bien une série de 10 nombres qui ont l'air aléatoires (flemme de faire des longs tirages et regarder l'écart-type).
Par contre quand je relance j'obtiens exactement la même liste !!!
Même avec des seeds:

program testrand
intrinsic random_seed, random_number
integer size, seed(2), gseed(2), hiseed(2), zseed(2)
real harvest(10)
data seed /123456789, 987654321/
data hiseed /-1, -1/
data zseed /0, 0/

call random_seed(SIZE=size)
print *,"size ",size
call random_seed(PUT=seed(1:size))

do i=1,10
call random_number(harvest)
print *, harvest
enddo
c
end program testrand
(code de la doc Intel)
Et bien pareil !
Alors ça me fait un peu chier, donc je voulais savoir si c'est normal, ou si c'est moi qui fait n'importe quoi encore une fois.
Merci! smile
./2
- Posté le 23/06/2009 à 21:31 Membre depuis le 11/06/2001, 19244 messages
Je dirai que c'est parce qu'il faut que tu seed avec une valeur aléatoire, genre le temps (ou clock).
Mais je ne connais rien au fortran wink
./3
- Posté le 23/06/2009 à 23:54 Membre depuis le 10/06/2001, 34999 messages
Un programme sur ordinateur est chargé depuis le disque dur à chaque fois, donc forcément les variables ne sont pas gardées entre les exécutions, il n'y a pas ce phénomène bizarre des programmes non-archivés non-compressés sur calculatrice ou sur d'autres plateformes embarquées qui exécutent directement en RAM, où les variables globales sont gardées entre exécutions.

Au "mieux" ta variable sera non-initialisée, ce qui en théorie voudrait dire qu'elle peut valoir n'importe quoi, mais en pratique la valeur est plutôt prévisible, souvent 0 ou une autre valeur restée sur la pile qui ne varie pas entre 2 exécutions successives. Et dans ce cas, ou aussi si tu initialises explicitement le seed (ou si ton compilateur Fortran est réglé pour initialiser tout à 0 automatiquement, c'est une option courante parmi les compilateurs Fortran pour faire marcher du code foireux qui traîne), évidemment que la valeur sera toujours la même. Il faut en effet lire une source externe (genre l'horloge comme suggéré par PpHd) pour initialiser ton générateur de nombres pseudo-aléatoires.
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité
./4
- Posté le 24/06/2009 à 00:03 Membre depuis le 12/08/2004, 884 messages
PpHd a vu juste. Quelques explications sur la page là : http://infohost.nmt.edu/tcc/help/lang/fortran/random.html

Les valeurs aléatoires sont identiques (c'est paradoxal) entre deux exécutions consécutives. C'est pour permettre de débuguer plus facilement un code. Pour vérifier la bonne marche du code on a besoin d'avoir la même séquence aléatoire (pseudo-aléatoire dans notre cas), ce qui est possible en initialisant la séquence aléatoire avec la même valeur de graine (seed).

Je ne sais pas si l'algorithme de génération de nombres pseudo-aléatoires est le même d'une machine à une autre ou même entre deux versions différentes d'un compilo. Pour éviter de tels aléas on utilise un fichier de nombres pseudo-aléatoires pour vérifier le comportement du code.
Gare à celui qui touche a mes chips quand je code !
./5
- Posté le 24/06/2009 à 11:48 Membre depuis le 30/05/2006, 12583 messages
En fait il y avait une petite feinte pour initialiser avec la date et l'heure (ce qui était annoncé comme le mode par defaut dans la doc intel)
Il faut faire
call random_seed
et non
call random_seed()
comme j'ai essayé de le faire.
En tout cas merci pour vos explications, j'ai passé pas mal de temps à jouer avec la fonction d'heure (DATE_AND_TIME()) pour voir comment ça marche tout ça.
Au final je retiens le programme suivant:
      program testrand
intrinsic random_seed, random_number
integer i
real harvest
c Initialize with the correect seed size
call random_seed
do i=1,10
call random_number(harvest)
print *, harvest
enddo
c
end program testrand
Ca marche pas mal, excepté quand on lance successivement le programme très rapidement, la graine étant la même car l'heure est toujours dans la même seconde. Ce n'est pas gênant pour moi car le programme réel met plusieurs minutes à tourner, mais 'just in case', vous connaissez une fonction pour avoir des millisecondes? J'en ai pas trouvé à première vue...
./6
- Posté le 29/06/2009 à 08:24 Membre depuis le 12/08/2004, 884 messages
Les fonctions DATE_AND_TIME ou SYSTEM_CLOCK devraient te donner satisfaction.
Gare à celui qui touche a mes chips quand je code !
./7
- Posté le 29/06/2009 à 08:47 Membre depuis le 30/05/2006, 12583 messages
SYSTEM_CLOCK ne retourne que des secondes, mais DATE_AND_TIME donne bien des ms. Je connaissais cette fonction mais j'avais mal lu la doc. couic
Merci!
./8
- Posté le 29/06/2009 à 18:26 Membre depuis le 12/08/2004, 884 messages
melbou (./7) :SYSTEM_CLOCK ne retourne que des secondes

Pas nécessairement, ça dépend de l'implémentation de cette fonction sur la machine. Avec un nombre de périodes d'horloge par seconde élevé on peut avoir les millisecondes.

De rien wink
Gare à celui qui touche a mes chips quand je code !