comp.lang.ada
 help / color / mirror / Atom feed
* Random numbers in Gnat
@ 1995-03-01 21:51 ab
  1995-03-02  8:31 ` Dave Marshall
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: ab @ 1995-03-01 21:51 UTC (permalink / raw)



I cannot find any discussion of the use of random() procedure
in gnat-2.03 Unix version for SunOS 4.1.3. The only information
that I found is in file a-numran.ads, and as the following
shows I must have misunderstood the intent and use of the objects
in that file.

Here is a little test that I've concocted:

        with text_io; use text_io;
		with ada.numerics.random; use ada.numerics.random;
		procedure randtest is
          package int_io is new integer_io(integer); use int_io;

		  rand_state: state:= make_state;

          -- return random number in 0..up_bound
          function my_random(up_bound: integer) return integer is
                r: Uniformly_Distributed;
          begin
                random( rand_state, r);
                return integer(r*float(up_bound));
          end my_random;          
        begin
          for i in 1..10 loop
                put(my_random(1000)); new_line;
          end loop;
        end randtest;

The program prints out only zeros rather than 10 random numbers in the
0..1000 range. I dislike the use of the global rand_state variable. 
However using it as a parameter is no better either. Indeed, why
should one be bothered with this quantity anyway? (In C one
just seeds the generator, and then calls the random() as a 
parameterless function, why not here?)

I'll appreciate your discussion as to how the random number
generator should be used. Pointers to some documentation/discussion
of the objects in a-numran.ads would also be helpful.

ab

-- 

Dr. A.Bykat
Fuller E. Callaway Professor




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Random numbers in Gnat
  1995-03-01 21:51 Random numbers in Gnat ab
@ 1995-03-02  8:31 ` Dave Marshall
  1995-03-03 19:11   ` Robert Dewar
  1995-03-02 15:50 ` Robert I. Eachus
  1995-03-03 15:08 ` Tucker Taft
  2 siblings, 1 reply; 5+ messages in thread
From: Dave Marshall @ 1995-03-02  8:31 UTC (permalink / raw)


ab@captblood.armstrong.edu () writes:


>I cannot find any discussion of the use of random() procedure

Please, humor me.  Don't put parentheses in when it's not C.

>in gnat-2.03 Unix version for SunOS 4.1.3. The only information
>that I found is in file a-numran.ads, and as the following
>shows I must have misunderstood the intent and use of the objects
>in that file.

Always consult the LRM for definitive discussion.  Read the Rationale, 
too, for a more narrative-type approach.

>Here is a little test that I've concocted:

>        with text_io; use text_io;
>		with ada.numerics.random; use ada.numerics.random;

I hate "use"s.  Thank God for "use types."  Whoever is getting royalties 
on "renames" is going to become poor very soon.

>		procedure randtest is
>          package int_io is new integer_io(integer); use int_io;

I hate Text_IO.Integer_IO, too.

>		  rand_state: state:= make_state;

>          -- return random number in 0..up_bound
>          function my_random(up_bound: integer) return integer is
>                r: Uniformly_Distributed;
>          begin
>                random( rand_state, r);
>                return integer(r*float(up_bound));
>          end my_random;          
>        begin
>          for i in 1..10 loop
>                put(my_random(1000)); new_line;
>          end loop;
>        end randtest;

This is far too complicated.  By the way, my copy of the latest and 
greatest RM just doesn't mention Ada.Numerics.Random.  I see 
Ada.Numerics.Discrete_Random and Ada.Numerics.Float_Random.

>The program prints out only zeros rather than 10 random numbers in the
>0..1000 range. I dislike the use of the global rand_state variable. 
>However using it as a parameter is no better either. Indeed, why
>should one be bothered with this quantity anyway? (In C one
>just seeds the generator, and then calls the random() as a 
>parameterless function, why not here?)

Because different tasks may want different seeds.

>I'll appreciate your discussion as to how the random number
>generator should be used. Pointers to some documentation/discussion
>of the objects in a-numran.ads would also be helpful.

Here's my program that attempts to do the same thing.

with Text_IO;
with Ada.Numerics.Discrete_Random;

   type Some_Numbers is range 0 .. 1_000;

   package Some_Random is new Ada.Numerics.Discrete_Random(Some_Numbers);

   Some_Generator : Some_Random.Generator;

begin

   Some_Random.Reset(Some_Generator);
   for I in 1 .. 10 loop
      Text_IO.Put(Some_Numbers'Image(Some_Random.Random(Some_Generator)));
   end loop;

end Rand_Test;

>Dr. A.Bykat
>Fuller E. Callaway Professor

-- 
Dave Marshall
dmarshal@netcom.com




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Random numbers in Gnat
  1995-03-01 21:51 Random numbers in Gnat ab
  1995-03-02  8:31 ` Dave Marshall
@ 1995-03-02 15:50 ` Robert I. Eachus
  1995-03-03 15:08 ` Tucker Taft
  2 siblings, 0 replies; 5+ messages in thread
From: Robert I. Eachus @ 1995-03-02 15:50 UTC (permalink / raw)


In article <3j2q9t$s3n@solar.Armstrong.EDU> ab@captblood.armstrong.edu () writes:

 > with text_io; use text_io;
 > with ada.numerics.random; use ada.numerics.random;
 >   procedure randtest is
 >   package int_io is new integer_io(integer); use int_io;

 >	     rand_state: state:= make_state;

--     This initialization is wrong! The GNAT people will have to figure
-- out why it got through.  It seems to be a call to the function
-- Make_State in the private package Ada.Numerics.Random.

 >     -- return random number in 0..up_bound
 >     function my_random(up_bound: integer) return integer is
 >	   r: Uniformly_Distributed;
 >     begin
 >	   random( rand_state, r);
 >	   return integer(r*float(up_bound));
 >     end my_random;          
 >   begin

-- At this point you can insert a call to Reset, in theory it is not
-- needed, but the current generator seems to have some problems with
-- degenerate seeds.  I used:

       Reset(rand_state, 1234);
 >     for i in 1..10 loop
 >	   put(my_random(1000)); new_line;
 >     end loop;
 >   end randtest;

-- Under separate cover I'll send you a better generator. ;-)

 > The program prints out only zeros rather than 10 random numbers in the
 > 0..1000 range. I dislike the use of the global rand_state variable. 
 > However using it as a parameter is no better either. Indeed, why
 > should one be bothered with this quantity anyway? (In C one
 > just seeds the generator, and then calls the random() as a 
 > parameterless function, why not here?)

--  Because there is a serious issue involving tasking.  There are two
-- solutions in the tasking case: a single state with atomic updates,
-- or a state per task.  The solution chosen was to allow the Ada
-- language to be used and not force the wrong choice on users.  In
-- the non-tasking case, a pair of declarations like:

   My_Gen: Ada.Numerics.Float_Random.Generator;
   function Rand(Gen: in Ada.Numerics.Float_Random.Generator := My_Gen)
      return Ada.Numerics.Float_Random.Uniformly_Distributed renames
      Ada.Numerics.Float_Random.Random;

--    And all the heavy breathing is in one place.  (This particular
-- example does make a powerful argument for use clauses though.)

> I'll appreciate your discussion as to how the random number
> generator should be used. Pointers to some documentation/discussion
> of the objects in a-numran.ads would also be helpful.

-- Also by e-mail I'll send some documentation of how the generator I
-- use works.


--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Random numbers in Gnat
  1995-03-01 21:51 Random numbers in Gnat ab
  1995-03-02  8:31 ` Dave Marshall
  1995-03-02 15:50 ` Robert I. Eachus
@ 1995-03-03 15:08 ` Tucker Taft
  2 siblings, 0 replies; 5+ messages in thread
From: Tucker Taft @ 1995-03-03 15:08 UTC (permalink / raw)


ab@captblood.armstrong.edu wrote:

: I cannot find any discussion of the use of random() procedure
: in gnat-2.03 Unix version for SunOS 4.1.3. The only information
: that I found is in file a-numran.ads, and as the following
: shows I must have misunderstood the intent and use of the objects
: in that file.

: Here is a little test that I've concocted:

:         with text_io; use text_io;
: 		with ada.numerics.random; use ada.numerics.random;

In the final Ada 95 version, there are two random-number
packages, "Float_Random" and "Discrete_Random" (actually,
Discrete_Random is a generic package).
Float_Random is pretty much a direct replacement for the earlier
"Random."  Discrete_Random would actually do just what you
want without your having to fiddle with floating point.

: 		procedure randtest is
:           package int_io is new integer_io(integer); use int_io;

: 		  rand_state: state:= make_state;

This is called "Generator" in the final version.  "State" is
just used for saving and restoring the state of a generator.
So this would be:

                  Rand_Generator : Generator;

:           -- return random number in 0..up_bound
:           function my_random(up_bound: integer) return integer is
:                 r: Uniformly_Distributed;
:           begin
:                 random( rand_state, r);

Random is now a function in Float_Random.  So this
would be "R := Random(Rand_Generator);

:                 return integer(r*float(up_bound));

Conversion to Integer rounds, so you will not get a perfectly
uniform distribution with this.  0 and up_bound will each occur
half as often as the values between then.  Perhaps that is
what you wanted anyway.  

Ada 95 also has functions that will truncate (without 
conversion), and you can then convert after truncation.  
E.g. Integer(Float'Truncation(R * Float(Up_Bound))).
In this case, 0 will be as likely to occur as 1..Up_Bound-1,
and Up_Bound itself will almost never occur.  You can
use "mod" to ensure that Up_Bound never occurs (and then
you can eliminate the call on Float'Truncation as well).
Because this whole area of producing a discrete uniform distribution
is a bit subtle, Ada 95 includes a generic package
designed just for that.  See Discrete_Random in RM A.5.2.

:           end my_random;          
:         begin
:           for i in 1..10 loop
:                 put(my_random(1000)); new_line;
:           end loop;
:         end randtest;

: The program prints out only zeros rather than 10 random numbers in the
: 0..1000 range. I dislike the use of the global rand_state variable. 
: However using it as a parameter is no better either. Indeed, why
: should one be bothered with this quantity anyway? (In C one
: just seeds the generator, and then calls the random() as a 
: parameterless function, why not here?)

The important thing to remember is that Ada is a multitasking
language.  If there is global state (like the current random number
generator), then you get into problems if multiple tasks reference
it.  Hence, we have tried to avoid having "implicit" state in
language-defined packages ("Text_IO.Current_Input/Output" are 
exceptions to this, for historical reasons), but instead require the
programmer to declare and pass explicitly in state such as
a random number generator.

Note that you can create your own package with a 
parameterless random number function if you want,
either by presuming there are not going to be multiple tasks, 
or by using a protected object to guard the global generator, or 
by using the Task_Attributes package to create a separate 
generator for each task.

: I'll appreciate your discussion as to how the random number
: generator should be used. Pointers to some documentation/discussion
: of the objects in a-numran.ads would also be helpful.

The Ada 95 Reference Manual, subclause A.5.2, is the best
place to look.  The final reference manual is available
online at sw-eng.falls-church.va.us via anonymous FTP in directory
public/adaic/docs/standard/95lrm_rat/v6.0

: Dr. A.Bykat
: Fuller E. Callaway Professor

-Tucker Taft  stt@inmet.com
Intermetrics, Inc.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Random numbers in Gnat
  1995-03-02  8:31 ` Dave Marshall
@ 1995-03-03 19:11   ` Robert Dewar
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Dewar @ 1995-03-03 19:11 UTC (permalink / raw)



"the only information I have found is in a-numran.ads"

If you rummage around in the specs this way, please respect:

private package Ada.Numerics.Random is

the private here means MYOB, or more accurately, that this package is only
for internal use. It is wrong to try to use it directly. A program that
with's this package is illegal. As we observe from the attempt, there is
a missing check in GNAT which will be remedied forthwith :-)

Meanwhile, if you want to know what's in the libraries, look in Appendix A
of the RM. With rare exceptions you do NOT need to be a language lawyer
to understand this section, so it should be a primary reference source
for all Ada programmers.




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1995-03-03 19:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-03-01 21:51 Random numbers in Gnat ab
1995-03-02  8:31 ` Dave Marshall
1995-03-03 19:11   ` Robert Dewar
1995-03-02 15:50 ` Robert I. Eachus
1995-03-03 15:08 ` Tucker Taft

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox