* Random numbers in tasks
@ 2003-05-31 22:01 Papastefanos Serafeim
2003-06-01 2:09 ` David C. Hoos
0 siblings, 1 reply; 11+ messages in thread
From: Papastefanos Serafeim @ 2003-05-31 22:01 UTC (permalink / raw)
I am trying to model a simulation in Ada95 with gnat.
There are some tasks of the same type that use
random numbers. Is there a way to make every
task get its own sequence of random numbers ?
--
Papastefanos Serafeim
serafeim@otenet.gr
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-05-31 22:01 Random numbers in tasks Papastefanos Serafeim
@ 2003-06-01 2:09 ` David C. Hoos
2003-06-01 3:42 ` Bobby D. Bryant
0 siblings, 1 reply; 11+ messages in thread
From: David C. Hoos @ 2003-06-01 2:09 UTC (permalink / raw)
"Papastefanos Serafeim" <serafeim@otenet.gr> wrote in message
news:bbb8o5$2711$1@ulysses.noc.ntua.gr...
> I am trying to model a simulation in Ada95 with gnat.
> There are some tasks of the same type that use
> random numbers. Is there a way to make every
> task get its own sequence of random numbers ?
>
Yes. The task body should declare the generator object.
Each instance of the task type, therefore will have its own
generator object.
> --
> Papastefanos Serafeim
> serafeim@otenet.gr
>
>
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-01 2:09 ` David C. Hoos
@ 2003-06-01 3:42 ` Bobby D. Bryant
2003-06-01 18:05 ` Papastefanos Serafeim
0 siblings, 1 reply; 11+ messages in thread
From: Bobby D. Bryant @ 2003-06-01 3:42 UTC (permalink / raw)
On Sat, 31 May 2003 21:09:30 -0500, David C. Hoos wrote:
> "Papastefanos Serafeim" <serafeim@otenet.gr> wrote in message
> news:bbb8o5$2711$1@ulysses.noc.ntua.gr...
>> I am trying to model a simulation in Ada95 with gnat. There are some
>> tasks of the same type that use random numbers. Is there a way to make
>> every task get its own sequence of random numbers ?
>>
> Yes. The task body should declare the generator object. Each instance
> of the task type, therefore will have its own generator object.
And initialize them with different seeds, or they'll all spew the same
stream of numbers.
--
Bobby Bryant
Austin, Texas
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-01 3:42 ` Bobby D. Bryant
@ 2003-06-01 18:05 ` Papastefanos Serafeim
2003-06-01 21:31 ` tmoran
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Papastefanos Serafeim @ 2003-06-01 18:05 UTC (permalink / raw)
There is a small problem in that solution, I cannot just
declare the generator in the task type: There is a function in
a different package that is used to return a random
number in a given range and that function is used at
other places too...
Also, those tasks print some things on the screen. Is there a
'smart' way so that each task's output will not get confused
with the output of the others ?
"Bobby D. Bryant" <bdbryant@mail.utexas.edu> wrote in message
news:pan.2003.06.01.03.42.32.191321@mail.utexas.edu...
> On Sat, 31 May 2003 21:09:30 -0500, David C. Hoos wrote:
>
> > "Papastefanos Serafeim" <serafeim@otenet.gr> wrote in message
> > news:bbb8o5$2711$1@ulysses.noc.ntua.gr...
>
> >> I am trying to model a simulation in Ada95 with gnat. There are some
> >> tasks of the same type that use random numbers. Is there a way to make
> >> every task get its own sequence of random numbers ?
> >>
> > Yes. The task body should declare the generator object. Each instance
> > of the task type, therefore will have its own generator object.
>
> And initialize them with different seeds, or they'll all spew the same
> stream of numbers.
>
> --
> Bobby Bryant
> Austin, Texas
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-01 18:05 ` Papastefanos Serafeim
@ 2003-06-01 21:31 ` tmoran
2003-06-02 2:24 ` Bobby D. Bryant
2003-06-02 3:29 ` Robert I. Eachus
2 siblings, 0 replies; 11+ messages in thread
From: tmoran @ 2003-06-01 21:31 UTC (permalink / raw)
>There is a function in
>a different package that is used to return a random
>number in a given range and that function is used at
>other places too...
Just create a protected type to serialize calls from that function
(which presumably could be called simultaneously by multiple tasks)
to the random number generator. If you need reproducability, and
the timing of various tasks' calls for a random number is variable,
then you've got a problem. But if your function doesn't know who
called it, clearly it can't give numbers from a caller-specific
generator.
>Also, those tasks print some things on the screen. Is there a
>'smart' way so that each task's output will not get confused
>with the output of the others ?
If your output is direct to a screen array, each task can
have its own piece of real estate that everyone else stays out of.
If your output is by strings, multiple tasks could result in
funny merges of their output strings. In that case, a protected
type is again the simple solution.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-01 18:05 ` Papastefanos Serafeim
2003-06-01 21:31 ` tmoran
@ 2003-06-02 2:24 ` Bobby D. Bryant
2003-06-02 3:29 ` Robert I. Eachus
2 siblings, 0 replies; 11+ messages in thread
From: Bobby D. Bryant @ 2003-06-02 2:24 UTC (permalink / raw)
On Sun, 01 Jun 2003 21:05:41 +0300, Papastefanos Serafeim wrote:
> There is a small problem in that solution, I cannot just declare the
> generator in the task type: There is a function in a different package
> that is used to return a random number in a given range and that
> function is used at other places too...
If the function accepts a generator as an argument then David's suggestion
will still work correctly.
--
Bobby Bryant
Austin, Texas
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-01 18:05 ` Papastefanos Serafeim
2003-06-01 21:31 ` tmoran
2003-06-02 2:24 ` Bobby D. Bryant
@ 2003-06-02 3:29 ` Robert I. Eachus
2003-06-02 5:32 ` Bobby D. Bryant
2003-06-02 14:35 ` Papastefanos Serafeim
2 siblings, 2 replies; 11+ messages in thread
From: Robert I. Eachus @ 2003-06-02 3:29 UTC (permalink / raw)
Papastefanos Serafeim wrote:
> There is a small problem in that solution, I cannot just
> declare the generator in the task type: There is a function in
> a different package that is used to return a random
> number in a given range and that function is used at
> other places too...
There is magic in Ada for especially this purpose. It is in Annex C, so
it is possible that some compilers don't support it. Look at C.7.2 The
Package Task_Attributes. Here is an example and output using GNAT.
Notice that this version uses a fixed seed for each different task. If
you want different seeds for every run modify the body of
My_Float_Random.Gen_Source. But notice that just using a call to get
seeds based on the clock may not be sufficient, unless you put a delay in.
with Ada.Task_Attributes;
with Ada.Numerics.Float_Random;
package My_Float_Random is
function Random return Ada.Numerics.Float_Random.Uniformly_Distributed;
end My_Float_Random;
package body My_Float_Random is
type Generator_Pointer is access Ada.Numerics.Float_Random.Generator;
protected Gen_Source is
procedure Initialize_Generator(Pointer: in out Generator_Pointer);
private
Init: Integer := 10;
end Gen_Source;
protected body Gen_Source is
procedure Initialize_Generator
(Pointer: in out Generator_Pointer) is
begin
Pointer := new Ada.Numerics.Float_Random.Generator;
Ada.Numerics.Float_Random.Reset(Pointer.all, Init);
Init := Init + 10;
end Initialize_Generator;
end Gen_Source;
function Initialize return Generator_Pointer is
GP : Generator_Pointer;
begin
Gen_Source.Initialize_Generator(GP);
return GP;
end Initialize;
package Per_Task is new
Ada.Task_Attributes(Generator_Pointer, Initialize);
function Random return
Ada.Numerics.Float_Random.Uniformly_Distributed is
begin
return Ada.Numerics.Float_Random.Random(Per_Task.Value.all);
end Random;
end My_Float_Random;
with Ada.Text_IO;
with My_Float_Random;
procedure Test_Task_Random is
package Rand_IO is new Ada.Text_IO.Float_IO(Float);
task type Rand_Task (ID: Integer) is end Rand_Task;
type Task_Pointer is access Rand_Task;
TP : Task_Pointer;
protected IO_Serialize is
procedure Write_Line(S: in String);
end IO_Serialize;
protected body IO_Serialize is
procedure Write_Line (S: in String)
is begin Ada.Text_IO.Put_Line(S); end Write_Line;
end IO_Serialize;
task body Rand_Task is
Rand_String: String(1..10);
begin
for I in 1..10 loop
Rand_IO.Put(Rand_String, My_Float_Random.Random, 7, 0);
IO_Serialize.Write_Line( "Task" & Integer'Image(ID) &
" Random number: " & Rand_String);
end loop;
end Rand_Task;
begin
for I in 1..10 loop
TP := new Rand_Task(I);
end loop;
end Test_Task_Random;
E:\Ada\Random>test_task_random
test_task_random
Task 1 Random number: 0.7443592
Task 1 Random number: 0.1400007
Task 1 Random number: 0.9659407
Task 1 Random number: 0.6070659
...
Task 6 Random number: 0.3006703
Task 7 Random number: 0.5094006
Task 8 Random number: 0.9858680
Task 10 Random number: 0.2958182
Task 9 Random number: 0.7662218
Task 10 Random number: 0.4117813
Task 9 Random number: 0.9709954
Task 10 Random number: 0.2093689
Task 9 Random number: 0.3808535
Task 10 Random number: 0.6235309
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-02 3:29 ` Robert I. Eachus
@ 2003-06-02 5:32 ` Bobby D. Bryant
2003-06-02 14:35 ` Papastefanos Serafeim
1 sibling, 0 replies; 11+ messages in thread
From: Bobby D. Bryant @ 2003-06-02 5:32 UTC (permalink / raw)
On Mon, 02 Jun 2003 03:29:33 +0000, Robert I. Eachus wrote:
> Papastefanos Serafeim wrote:
>> There is a small problem in that solution, I cannot just declare the
>> generator in the task type: There is a function in a different package
>> that is used to return a random number in a given range and that
>> function is used at other places too...
>
> There is magic in Ada for especially this purpose. It is in Annex C, so
> it is possible that some compilers don't support it. Look at C.7.2 The
> Package Task_Attributes. Here is an example and output using GNAT.
> Notice that this version uses a fixed seed for each different task. If
> you want different seeds for every run modify the body of
> My_Float_Random.Gen_Source. But notice that just using a call to get
> seeds based on the clock may not be sufficient, unless you put a delay
> in.
FWIW, I have a GA solver with similar requirements, and I just have the
tasks rendezvous with a 'controller' task that dispenses individual seeds
for them to initialize on. After that they can run independently.
--
Bobby Bryant
Austin, Texas
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-02 3:29 ` Robert I. Eachus
2003-06-02 5:32 ` Bobby D. Bryant
@ 2003-06-02 14:35 ` Papastefanos Serafeim
2003-06-02 20:50 ` Robert I. Eachus
1 sibling, 1 reply; 11+ messages in thread
From: Papastefanos Serafeim @ 2003-06-02 14:35 UTC (permalink / raw)
Thank you for the big answer... I tried your program and
it works just fine, but when I try to convert it to my
requirements it is not working:
I want to use it with discrete rundom numbers with a
variable range... I have made changes to your program
and now looks like this ->
with Ada.Numerics.Discrete_Random;
with Ada.Task_Attributes;
package body Rnds is
function Give_Rnd (
L : Integer;
U : Integer;
) return Integer is
subtype Rng is Integer range L..U;
package Rnd_Num is new Ada.Numerics.Discrete_Random (Rng);
type Generator_Pointer is access Rnd_Num.Generator;
protected Gen_Source is
procedure Initialize_Generator (
Pointer : in out Generator_Pointer );
private
Init: Integer := 10;
end Gen_Source;
protected body Gen_Source is
procedure Initialize_Generator (
Pointer : in out Generator_Pointer ) is
begin
Pointer := new Rnd_Num.Generator;
Rnd_Num.Reset(Pointer.All, Init);
Init := Init + 10;
end Initialize_Generator;
end Gen_Source;
function Initialize return Generator_Pointer is
Gp : Generator_Pointer;
begin
Gen_Source.Initialize_Generator(Gp);
return Gp;
end Initialize;
package Per_Task is new
Ada.Task_Attributes(Generator_Pointer, Initialize);
begin
return Rnd_Num.Random(Per_Task.Value.All);
end Give_Rnd;
end Rnds;
It compiles fine but when I try to call the function Give_Rnd(...)
from inside a task it always returns the same result - Am I doing
something wrong ?
"Robert I. Eachus" <rieachus@attbi.com> wrote in message
news:3EDAC482.40604@attbi.com...
> Papastefanos Serafeim wrote:
> > There is a small problem in that solution, I cannot just
> > declare the generator in the task type: There is a function in
> > a different package that is used to return a random
> > number in a given range and that function is used at
> > other places too...
>
> There is magic in Ada for especially this purpose. It is in Annex C, so
> it is possible that some compilers don't support it. Look at C.7.2 The
> Package Task_Attributes. Here is an example and output using GNAT.
> Notice that this version uses a fixed seed for each different task. If
> you want different seeds for every run modify the body of
> My_Float_Random.Gen_Source. But notice that just using a call to get
> seeds based on the clock may not be sufficient, unless you put a delay in.
>
> with Ada.Task_Attributes;
> with Ada.Numerics.Float_Random;
> package My_Float_Random is
> function Random return Ada.Numerics.Float_Random.Uniformly_Distributed;
> end My_Float_Random;
>
> package body My_Float_Random is
> type Generator_Pointer is access Ada.Numerics.Float_Random.Generator;
>
> protected Gen_Source is
> procedure Initialize_Generator(Pointer: in out Generator_Pointer);
> private
> Init: Integer := 10;
> end Gen_Source;
>
> protected body Gen_Source is
> procedure Initialize_Generator
> (Pointer: in out Generator_Pointer) is
> begin
> Pointer := new Ada.Numerics.Float_Random.Generator;
> Ada.Numerics.Float_Random.Reset(Pointer.all, Init);
> Init := Init + 10;
> end Initialize_Generator;
>
> end Gen_Source;
>
> function Initialize return Generator_Pointer is
> GP : Generator_Pointer;
> begin
> Gen_Source.Initialize_Generator(GP);
> return GP;
> end Initialize;
>
> package Per_Task is new
> Ada.Task_Attributes(Generator_Pointer, Initialize);
>
> function Random return
> Ada.Numerics.Float_Random.Uniformly_Distributed is
> begin
> return Ada.Numerics.Float_Random.Random(Per_Task.Value.all);
> end Random;
>
> end My_Float_Random;
>
> with Ada.Text_IO;
> with My_Float_Random;
> procedure Test_Task_Random is
>
> package Rand_IO is new Ada.Text_IO.Float_IO(Float);
>
> task type Rand_Task (ID: Integer) is end Rand_Task;
>
> type Task_Pointer is access Rand_Task;
> TP : Task_Pointer;
>
> protected IO_Serialize is
> procedure Write_Line(S: in String);
> end IO_Serialize;
>
> protected body IO_Serialize is
> procedure Write_Line (S: in String)
> is begin Ada.Text_IO.Put_Line(S); end Write_Line;
> end IO_Serialize;
>
> task body Rand_Task is
> Rand_String: String(1..10);
> begin
> for I in 1..10 loop
> Rand_IO.Put(Rand_String, My_Float_Random.Random, 7, 0);
> IO_Serialize.Write_Line( "Task" & Integer'Image(ID) &
> " Random number: " & Rand_String);
> end loop;
> end Rand_Task;
>
> begin
>
> for I in 1..10 loop
> TP := new Rand_Task(I);
> end loop;
>
> end Test_Task_Random;
>
> E:\Ada\Random>test_task_random
> test_task_random
> Task 1 Random number: 0.7443592
> Task 1 Random number: 0.1400007
> Task 1 Random number: 0.9659407
> Task 1 Random number: 0.6070659
> ...
> Task 6 Random number: 0.3006703
> Task 7 Random number: 0.5094006
> Task 8 Random number: 0.9858680
> Task 10 Random number: 0.2958182
> Task 9 Random number: 0.7662218
> Task 10 Random number: 0.4117813
> Task 9 Random number: 0.9709954
> Task 10 Random number: 0.2093689
> Task 9 Random number: 0.3808535
> Task 10 Random number: 0.6235309
>
>
>
>
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-02 14:35 ` Papastefanos Serafeim
@ 2003-06-02 20:50 ` Robert I. Eachus
2003-06-03 19:37 ` Papastefanos Serafeim
0 siblings, 1 reply; 11+ messages in thread
From: Robert I. Eachus @ 2003-06-02 20:50 UTC (permalink / raw)
Papastefanos Serafeim wrote:
> Thank you for the big answer... I tried your program and
> it works just fine, but when I try to convert it to my
> requirements it is not working:
> I want to use it with discrete rundom numbers with a
> variable range... I have made changes to your program
> and now looks like this ->
> with Ada.Numerics.Discrete_Random;
> with Ada.Task_Attributes;
> package body Rnds is
> function Give_Rnd (
> L : Integer;
> U : Integer;
> ) return Integer is
> subtype Rng is Integer range L..U;
> package Rnd_Num is new Ada.Numerics.Discrete_Random (Rng);
Never instantiate a random number package inside a function. As you
have noticed, the results are not what you want. Here is a version of
what I gave you before, but with the init generator settings based on
one clock call.
with Ada.Numerics.Discrete_Random;
package body My_Float_Random is
type Generator_Pointer is access Ada.Numerics.Float_Random.Generator;
package Int_Rand is new Ada.Numerics.Discrete_Random(Positive);
protected Gen_Source is
procedure Initialize_Generator(Pointer: in out Generator_Pointer);
private
Int_Gen: Int_Rand.Generator;
Initial: Boolean := True;
end Gen_Source;
protected body Gen_Source is
procedure Initialize_Generator
(Pointer: in out Generator_Pointer) is
begin
if Initial then
Int_Rand.Reset(Int_Gen);
Initial := False; -- use time of day once
end if;
Pointer := new Ada.Numerics.Float_Random.Generator;
Ada.Numerics.Float_Random.Reset
(Pointer.all, Int_Rand.Random(Int_Gen));
end Initialize_Generator;
end Gen_Source;
function Initialize return Generator_Pointer is
GP : Generator_Pointer;
begin
Gen_Source.Initialize_Generator(GP);
return GP;
end Initialize;
package Per_Task is new
Ada.Task_Attributes(Generator_Pointer, Initialize);
function Random return
Ada.Numerics.Float_Random.Uniformly_Distributed is
begin
return Ada.Numerics.Float_Random.Random(Per_Task.Value.all);
end Random;
end My_Float_Random;
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Random numbers in tasks
2003-06-02 20:50 ` Robert I. Eachus
@ 2003-06-03 19:37 ` Papastefanos Serafeim
0 siblings, 0 replies; 11+ messages in thread
From: Papastefanos Serafeim @ 2003-06-03 19:37 UTC (permalink / raw)
Thank you
"Robert I. Eachus" <rieachus@attbi.com> wrote in message
news:3EDBB85D.3050505@attbi.com...
> Papastefanos Serafeim wrote:
> > Thank you for the big answer... I tried your program and
> > it works just fine, but when I try to convert it to my
> > requirements it is not working:
>
> > I want to use it with discrete rundom numbers with a
> > variable range... I have made changes to your program
> > and now looks like this ->
> > with Ada.Numerics.Discrete_Random;
> > with Ada.Task_Attributes;
> > package body Rnds is
> > function Give_Rnd (
> > L : Integer;
> > U : Integer;
> > ) return Integer is
> > subtype Rng is Integer range L..U;
> > package Rnd_Num is new Ada.Numerics.Discrete_Random (Rng);
>
> Never instantiate a random number package inside a function. As you
> have noticed, the results are not what you want. Here is a version of
> what I gave you before, but with the init generator settings based on
> one clock call.
>
> with Ada.Numerics.Discrete_Random;
> package body My_Float_Random is
> type Generator_Pointer is access Ada.Numerics.Float_Random.Generator;
>
> package Int_Rand is new Ada.Numerics.Discrete_Random(Positive);
>
> protected Gen_Source is
> procedure Initialize_Generator(Pointer: in out Generator_Pointer);
> private
> Int_Gen: Int_Rand.Generator;
> Initial: Boolean := True;
> end Gen_Source;
>
> protected body Gen_Source is
> procedure Initialize_Generator
> (Pointer: in out Generator_Pointer) is
> begin
> if Initial then
> Int_Rand.Reset(Int_Gen);
> Initial := False; -- use time of day once
> end if;
> Pointer := new Ada.Numerics.Float_Random.Generator;
> Ada.Numerics.Float_Random.Reset
> (Pointer.all, Int_Rand.Random(Int_Gen));
> end Initialize_Generator;
> end Gen_Source;
>
> function Initialize return Generator_Pointer is
> GP : Generator_Pointer;
> begin
> Gen_Source.Initialize_Generator(GP);
> return GP;
> end Initialize;
>
> package Per_Task is new
> Ada.Task_Attributes(Generator_Pointer, Initialize);
>
> function Random return
> Ada.Numerics.Float_Random.Uniformly_Distributed is
> begin
> return Ada.Numerics.Float_Random.Random(Per_Task.Value.all);
> end Random;
>
> end My_Float_Random;
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2003-06-03 19:37 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-31 22:01 Random numbers in tasks Papastefanos Serafeim
2003-06-01 2:09 ` David C. Hoos
2003-06-01 3:42 ` Bobby D. Bryant
2003-06-01 18:05 ` Papastefanos Serafeim
2003-06-01 21:31 ` tmoran
2003-06-02 2:24 ` Bobby D. Bryant
2003-06-02 3:29 ` Robert I. Eachus
2003-06-02 5:32 ` Bobby D. Bryant
2003-06-02 14:35 ` Papastefanos Serafeim
2003-06-02 20:50 ` Robert I. Eachus
2003-06-03 19:37 ` Papastefanos Serafeim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox