comp.lang.ada
 help / color / mirror / Atom feed
* 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