comp.lang.ada
 help / color / mirror / Atom feed
* Random Number Generation
@ 1996-09-23  0:00 Nigel J. Tracey
  1996-09-23  0:00 ` Tucker Taft
                   ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: Nigel J. Tracey @ 1996-09-23  0:00 UTC (permalink / raw)



Can anyone point me in the direction of a routines to do
random number generation. The requirements are as follows.

	A routine which will generate a integer between a given
		minimum and maximum value. Up to Integer'First and Integer'Last

	A routine which will do the same for floats i.e. a random
		value from Float'First to Float'Last but between two
		given values.

The values of the min and max value for the above routines
are not known at compile time, hence why I don't thing
I can use Ada.Numerics.Discrete_Random

Any help would be very much appreciated (please also e-mail
a copy of relies as the news feed is a little unreliable here)

Thanks a lot,

	Nigel

--------------------
Nigel J. Tracey MEng, Research Associate (High Integrity Systems Group).
Department of Computer Science,   Office: X/D016
University of York,               Tel   : [0|+44]1904 432769
York, England.                    E-Mail: njt@minster.york.ac.uk
YO1 5DD.                          URL   : http://sv1pc161.cs.york.ac.uk/~njt




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

* Re: Random Number Generation
  1996-09-23  0:00 Nigel J. Tracey
@ 1996-09-23  0:00 ` Tucker Taft
  1996-10-02  0:00   ` Nigel J. Tracey
                     ` (2 more replies)
  1996-09-25  0:00 ` James_Rogers
  1996-09-30  0:00 `  Dr J Parker
  2 siblings, 3 replies; 57+ messages in thread
From: Tucker Taft @ 1996-09-23  0:00 UTC (permalink / raw)
  Cc: njt


Nigel J. Tracey (njt@minster.york.ac.uk) wrote:

: Can anyone point me in the direction of a routines to do
: random number generation. The requirements are as follows.

: 	A routine which will generate a integer between a given
: 		minimum and maximum value. Up to Integer'First and Integer'Last

: 	A routine which will do the same for floats i.e. a random
: 		value from Float'First to Float'Last but between two
: 		given values.

: The values of the min and max value for the above routines
: are not known at compile time, hence why I don't thing
: I can use Ada.Numerics.Discrete_Random

Discrete_Random does not require compile-time-known values.
However, it does require that the values be known at the time
of the instantiation.  Hence, the following is legal:

    subtype Random_Range is Integer range F(x) .. G(y);
    package Dyn_Random is new Ada.Numerics.Discrete_Random(Random_Range);

However, it may be want to change the range after the instantiation
takes place, or the instantiation needs to be at the library level,
and you won't know these values until you are inside the main
subprogram.

In any case, Ada.Numerics.Float_Random is the easiest one to adapt to your
use, since it always generates values between 0.0 and 1.0.  You
can then multiply that value by an appropriate integer or float
and add the low bound to produce the desired dynamic range.
Some care may be needed when converting from float back to integer,
to provide the desired distribution, if you want the end points to
be just as likely as any other value.  Conversion from
float to integer rounds, so you may want to use the following
trick (using "mod") to get the desired range, with no spillover to 
High_Bound+1 (this trick originates with Robert Eachus, I believe):

  declare
    Result : Integer range Low_Bound .. High_Bound;
    Range_Length : constant Integer := High_Bound - Low_Bound + 1;
  begin
    Result := (Integer(Float(Range_Length) * 
      Ada.Numerics.Float_Random.Random(Gen)) mod Range_Length) + Low_Bound;
    ...

: Any help would be very much appreciated (please also e-mail
: a copy of relies as the news feed is a little unreliable here)

: Thanks a lot,

: 	Nigel

: --------------------
: Nigel J. Tracey MEng, Research Associate (High Integrity Systems Group).
: Department of Computer Science,   Office: X/D016
: University of York,               Tel   : [0|+44]1904 432769
: York, England.                    E-Mail: njt@minster.york.ac.uk
: YO1 5DD.                          URL   : http://sv1pc161.cs.york.ac.uk/~njt

-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Cambridge, MA  USA




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

* Re: Random Number Generation
  1996-09-23  0:00 Nigel J. Tracey
  1996-09-23  0:00 ` Tucker Taft
@ 1996-09-25  0:00 ` James_Rogers
  1996-09-26  0:00   ` Dale Stanbrough
  1996-10-01  0:00   ` Robert I. Eachus
  1996-09-30  0:00 `  Dr J Parker
  2 siblings, 2 replies; 57+ messages in thread
From: James_Rogers @ 1996-09-25  0:00 UTC (permalink / raw)



Nigel J. Tracey wrote:
> 
> Can anyone point me in the direction of a routines to do
> random number generation. The requirements are as follows.
> 
>         A routine which will generate a integer between a given
>                 minimum and maximum value. Up to Integer'First and Integer'Last
> 
>         A routine which will do the same for floats i.e. a random
>                 value from Float'First to Float'Last but between two
>                 given values.
> 
> The values of the min and max value for the above routines
> are not known at compile time, hence why I don't thing
> I can use Ada.Numerics.Discrete_Random
> 
> Any help would be very much appreciated (please also e-mail
> a copy of relies as the news feed is a little unreliable here)
> 
> Thanks a lot,
> 

The solution is really quite simple.  Wrap your random number
generator calls inside a function in the following manner:

-------------------------------------------------------------
-- Flexible generic example
-------------------------------------------------------------
with Ada.Numerics.Discrete_Random;
with Ada.Text_IO; use Ada.Text_IO;

procedure example is

   package int_io is new integer_io(integer);

   function flex_rand (Low, High : Integer) return Integer is
      subtype rand_type is Integer range Low..High;
      package myrand is new Ada.Numerics.Discrete_Random(rand_type);
      seed : myrand.generator;
      Result : rand_type;
   begin
      myrand.reset(seed);
      Result := myrand.random(seed);
      return Result;
   end flex_rand;

   Low, High : Integer;

begin

   put("Enter the low bounds: ");
   int_io.get(Low);
   put("Enter the high bounds: ");
   int_io.get(High);
   put("Random number in the range of ");
   int_io.put(Low, Width => 1);
   put(" to ");
   int_io.put(High, Width => 1);
   put(" = ");
   int_io.put(flex_rand(Low, High), Width => 1);
end example;

-----------------------------------------------------------------
The wrapper function "flex_rand" provides all the flexibility you
reqest.  Of course, the same approach can be used for float types.

-- 
Jim Rogers
*************************************************************
Celebrate Diplomacy




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

* Re: Random Number Generation
  1996-09-25  0:00 ` James_Rogers
@ 1996-09-26  0:00   ` Dale Stanbrough
  1996-10-01  0:00   ` Robert I. Eachus
  1 sibling, 0 replies; 57+ messages in thread
From: Dale Stanbrough @ 1996-09-26  0:00 UTC (permalink / raw)



James_Rogers writes:
------------------------------------------------------------
-- Flexible generic example
-------------------------------------------------------------
with Ada.Numerics.Discrete_Random;
with Ada.Text_IO; use Ada.Text_IO;

procedure example is

   package int_io is new integer_io(integer);



Just a note - it's probably better to with the preinstantiated
version of integer_io...


	with Ada.Integer_Text_IO;
	
in any examples - it certainly reduces the clutter of a program
example if you do.


Dale




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

* Re: Random Number Generation
  1996-09-23  0:00 Nigel J. Tracey
  1996-09-23  0:00 ` Tucker Taft
  1996-09-25  0:00 ` James_Rogers
@ 1996-09-30  0:00 `  Dr J Parker
  1996-10-01  0:00   ` Tucker Taft
  2 siblings, 1 reply; 57+ messages in thread
From:  Dr J Parker @ 1996-09-30  0:00 UTC (permalink / raw)



Tucker Taft suggests: 

"In any case, Ada.Numerics.Float_Random is the easiest one to adapt to your
use, since it always generates values between 0.0 and 1.0.  You
can then multiply that value by an appropriate integer or float
and add the low bound to produce the desired dynamic range.

  declare
    Result : Integer range Low_Bound .. High_Bound;
    Range_Length : constant Integer := High_Bound - Low_Bound + 1;
  begin
    Result := (Integer(Float(Range_Length) *
      Ada.Numerics.Float_Random.Random(Gen)) mod Range_Length) + Low_Bound;
    ...
"


Careful, there are some limits in which this fails. Simple example:
Suppose you have a high quality random number generator R1 in the range
0 .. 127
and you want to turn it into a high quality random number generator R2
in the range 0 .. 82.
Only the rejection method works: you must throw out at least
45 of the values returned by R1.  eg, if R1 returns a number in the range
83..127, then reject it and keep calling R1 until you get
a number in the range 0 .. 82.  You'll get a stream of high quality random
numbers in the range 0 .. 82.  In general, you reject just enough to make
the number of elements (think bins) in range of R1 an integer multiple of
the number of elements in the range of R2 (you reject never more than 50% of
the number of elements in range of R1).  Then you
can use "*"'s, etc to transform R1 into R2. Floating point doesn't
change the problem.




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

* Re: Random Number Generation
  1996-10-01  0:00   ` Tucker Taft
@ 1996-10-01  0:00     ` Keith Thompson
  0 siblings, 0 replies; 57+ messages in thread
From: Keith Thompson @ 1996-10-01  0:00 UTC (permalink / raw)



In <DyKpEz.FnB.0.-s@inmet.camb.inmet.com> stt@houdini.camb.inmet.com (Tucker Taft) writes:
[...]
> The standard Float random number generator generates values uniformly
> distributed from 0.0 to 1.0.  By multiplying these values by the number
> of distinct integers wanted, and then (carefully) "pushing" them to a
> neighboring exact integral value, you can get a uniform distribution
> across any desired sequence of integers, provided the number of distinct
> integers is significantly less than the period of the underlying generator.

And provided that type Float has more significant mantissa bits than
the size of the integral type.  If you're generating 32-bit integers by
scaling 32-bit floating-point values, the large-scale distribution will
be ok but all the results are likely to be multiples of some large power
of 2.

-- 
Keith Thompson (The_Other_Keith) kst@thomsoft.com <*>
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2706
FIJAGDWOL




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

* Re: Random Number Generation
  1996-09-25  0:00 ` James_Rogers
  1996-09-26  0:00   ` Dale Stanbrough
@ 1996-10-01  0:00   ` Robert I. Eachus
  1 sibling, 0 replies; 57+ messages in thread
From: Robert I. Eachus @ 1996-10-01  0:00 UTC (permalink / raw)




In article <DyD3DF.Exo@thomsoft.com> kst@thomsoft.com (Keith Thompson) writes:

  > It might have been nice if the Random function had been declared like
  > this:

  >     function Random
  >	  ( Gen   : Generator; 
  >	    First : Result_Subtype := Result_Subtype'First;
  >	    Last  : Result_Subtype := Result_Subtype'Last );

  > allowing successive calls to Random with different specified bounds to
  > share the same generator, but this wasn't done.

   This wasn't done because defining the required behavior of such a
generator is beyond the state of the art.  (Not defining the
generator, THAT part is easy.)  We could have tried to extent the art
by defining tests for randomness for such a generator, but that is not
a job for a programming language standards committee.

  > Probably the best way to handle this is to use Ada.Numerics.Float_Random
  > and scale the result to the desired discrete range.  I think someone
  > else has posted code that does this.  Watch for rounding errors near
  > the endpoints!

  Yes, this can usually be done as a "one-liner," but if you think you
need the capability, think the issue through carefully.  There are
some cases where you need such behavior, but precious few.  (The bias
that can be introduced by rounding from float to integer is why I
don't want to post code without knowing the hardware, and the RNG
used.  But as long as there are hundreds of values from the generator
mapped to each possible integer value, the bias shouldn't cause a
problem.)

--

					Robert I. Eachus

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




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

* Re: Random Number Generation
  1996-09-30  0:00 `  Dr J Parker
@ 1996-10-01  0:00   ` Tucker Taft
  1996-10-01  0:00     ` Keith Thompson
  0 siblings, 1 reply; 57+ messages in thread
From: Tucker Taft @ 1996-10-01  0:00 UTC (permalink / raw)



Dr J Parker (jp3@rl.ac.uk) wrote:
: Tucker Taft suggests: 

: "In any case, Ada.Numerics.Float_Random is the easiest one to adapt to your
: use, since it always generates values between 0.0 and 1.0.  You
: can then multiply that value by an appropriate integer or float
: and add the low bound to produce the desired dynamic range.

:   declare
:     Result : Integer range Low_Bound .. High_Bound;
:     Range_Length : constant Integer := High_Bound - Low_Bound + 1;
:   begin
:     Result := (Integer(Float(Range_Length) *
:       Ada.Numerics.Float_Random.Random(Gen)) mod Range_Length) + Low_Bound;
:     ...
: "


: Careful, there are some limits in which this fails. Simple example:
: Suppose you have a high quality random number generator R1 in the range
: 0 .. 127
: and you want to turn it into a high quality random number generator R2
: in the range 0 .. 82.
: Only the rejection method works: you must throw out at least
: 45 of the values returned by R1.  eg, if R1 returns a number in the range
: 83..127, then reject it and keep calling R1 until you get
: a number in the range 0 .. 82.  You'll get a stream of high quality random
: numbers in the range 0 .. 82.  In general, you reject just enough to make
: the number of elements (think bins) in range of R1 an integer multiple of
: the number of elements in the range of R2 (you reject never more than 50% of
: the number of elements in range of R1).  Then you
: can use "*"'s, etc to transform R1 into R2. Floating point doesn't
: change the problem.

I don't believe my suggestion suffers from the problem you fear.

The standard Float random number generator generates values uniformly
distributed from 0.0 to 1.0.  By multiplying these values by the number
of distinct integers wanted, and then (carefully) "pushing" them to a
neighboring exact integral value, you can get a uniform distribution
across any desired sequence of integers, provided the number of distinct
integers is significantly less than the period of the underlying generator.

The only trickiness above is that Ada rounds on conversion from float
to integer, so after multiplying by N and rounding to integer, you end 
up with 0 and N each occuring half as often as the values 1..N-1.  The
"mod" folds the N and 0 together, providing the desired uniform distribution
from 0 .. N-1, and then adding the low bound gives the desired low .. high
distribution.  If N is a very large number, on the order of the
underlying period of the Float random number generator, then clearly
the "uniformity" of the generator will not be as good, but provided
N << period, there is no need to use "rejection" to produce reasonable
uniformity.

-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Cambridge, MA  USA




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

* Re: Random Number Generation
  1996-09-23  0:00 ` Tucker Taft
@ 1996-10-02  0:00   ` Nigel J. Tracey
  1996-10-02  0:00   ` Robert I. Eachus
  1996-10-03  0:00   ` Nigel J. Tracey
  2 siblings, 0 replies; 57+ messages in thread
From: Nigel J. Tracey @ 1996-10-02  0:00 UTC (permalink / raw)



Thanks for all the replies on this issue. I now have the problem
sorted for discrete random values. However nobody has suggested
a solution for generating large random reals. I really need
to be able to generate random values in the range of
Float'Safe_First..Float'Safe_Last. Or perhaps a variable
sub-range of these. Any idea...

Thanks once more

	Nigel.

--------------------
Nigel J. Tracey MEng, Research Associate (High Integrity Systems Group).
Department of Computer Science,   Office: X/D016
University of York,               Tel   : [0|+44]1904 432769
York, England.                    E-Mail: njt@minster.york.ac.uk
YO1 5DD.                          URL   : http://sv1pc161.cs.york.ac.uk/~njt




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

* Re: Random Number Generation
@ 1996-10-02  0:00  Dr J Parker
  1996-10-03  0:00 ` Mats Weber
  1996-10-07  0:00 ` Geert Bosch
  0 siblings, 2 replies; 57+ messages in thread
From:  Dr J Parker @ 1996-10-02  0:00 UTC (permalink / raw)



Another simple example:

Suppose you have a high quality random number generator R1 in the range
0 .. 1023
and you want to turn it into a high quality random number generator R2
in the range 0 .. 2.

R1 has 8 more bits than R2.

Suppose you try R2  =  R1 / 342.

this maps
0..341    to 0,
342..683  to 1
684..1023 to 2

0 has probability 342/1024, 1 has probability 342/1024, and
2 has probability 340/1024.

You can use  R1 mod 3, get same problem.
You can use  R1 * 3.0, with floating point R1 in [0.0..1.0)
and you get same problem if R1 has 1024  elements in its range.

Suppose you think R2 is uniformly distributed in 0,1, 2.
How many trials (N) would it take to detect the bias?

In under 5 miinutes you can generate N = 3 * 10**8 random numbers on
a PC.  expect 10**8 0's, 10**8 1's 10**8 2's , with stnd deviation
around 10**4 and error = 3 * 10**8 * 1.333/1024.0.

You get wrong answer by about 30 stnd deviations!

And all you had to do was reject number 1023 from the range of R2!
(because the number of elements in the range of 0..1022 is
divisible by 3.)

x := random;
while x > R1'Last - 1024 rem 3 loop
   x := random;
end loop;
return x rem 3;





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

* Re: Random Number Generation
  1996-09-23  0:00 ` Tucker Taft
  1996-10-02  0:00   ` Nigel J. Tracey
@ 1996-10-02  0:00   ` Robert I. Eachus
  1996-10-03  0:00   ` Nigel J. Tracey
  2 siblings, 0 replies; 57+ messages in thread
From: Robert I. Eachus @ 1996-10-02  0:00 UTC (permalink / raw)



In article <52ten0$ish@netty.york.ac.uk> njt@minster.york.ac.uk (Nigel J. Tracey) writes:

  > Thanks for all the replies on this issue. I now have the problem
  > sorted for discrete random values. However nobody has suggested
  > a solution for generating large random reals. I really need
  > to be able to generate random values in the range of
  > Float'Safe_First..Float'Safe_Last. Or perhaps a variable
  > sub-range of these. Any idea...

  With what distribution?  If you are using this for testing
arithmetic units, I suggest unchecked converting a string of random
bits of the right length.  This will be a distribution which covers
all representable numbers equally. (To save Robert Dewar the
trouble...Certain bit patterns do not correspond to legal floating
point values.  This a legitimate use for 'VALID).  However if you want
a numerically uniform distribution:

   2.0 * Float'Safe_Last * (Ada.Numerics.Float_Random.Random(Gen) - 0.5);

   Actually you may want to add more bits to the typical floating
point generator value.


--

					Robert I. Eachus

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




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

* Re: Random Number Generation
  1996-09-23  0:00 ` Tucker Taft
  1996-10-02  0:00   ` Nigel J. Tracey
  1996-10-02  0:00   ` Robert I. Eachus
@ 1996-10-03  0:00   ` Nigel J. Tracey
  2 siblings, 0 replies; 57+ messages in thread
From: Nigel J. Tracey @ 1996-10-03  0:00 UTC (permalink / raw)



Robert I. Eachus (eachus@spectre.mitre.org) wrote:
: In article <52ten0$ish@netty.york.ac.uk> njt@minster.york.ac.uk (Nigel J. Tracey) writes:
: 
:   > I really need
:   > to be able to generate random values in the range of
:   > Float'Safe_First..Float'Safe_Last. Or perhaps a variable
:   > sub-range of these. Any idea...
: 
:   With what distribution?  If you are using this for testing
: arithmetic units, I suggest unchecked converting a string of random
: bits of the right length.  This will be a distribution which covers
: all representable numbers equally. (To save Robert Dewar the
: trouble...Certain bit patterns do not correspond to legal floating
: point values.  This a legitimate use for 'VALID).  However if you want
: a numerically uniform distribution:
: 
:    2.0 * Float'Safe_Last * (Ada.Numerics.Float_Random.Random(Gen) - 0.5);
: 
:    Actually you may want to add more bits to the typical floating
: point generator value.
: 
: 
: --
: 
: 					Robert I. Eachus

I have managed to write something which works with some limitations.
The problem this has is that if the range includes 0.0 and is not
sufficiently large then there is a stong bias towards 0.0. e.g
numbers in the range -1.0..1.0 are most often 0.0. However for
larger ranges or ranges not including 0.0 it seem okay. An ideas
on an improvement to the 0.0 bias...

The code is as follows (Random_Seed is declared in the package
body, it is initialised to a random integer on ellaboration
and incremented after each reset so that repeated calls to
the routine do no give non random results, due to granularity
of the reset(Gen) function):

with  Ada.Numerics.Discrete_Random,
      Ada.Numerics.Float_Random;

   function Random(Min, Max : Float) return Float is

      subtype Exponent_Type is Integer range
         Float'Machine_EMin..Float'Machine_EMax;

      package Exp_Random is new
         Ada.Numerics.Discrete_Random(Exponent_Type);

      Gen1 		: Ada.Numerics.Float_Random.Generator;
      Gen2 		: Exp_Random.Generator;
      Mantissa : Float range -1.0..1.0;
      Result   : Float;

   begin
      Ada.Numerics.Float_Random.Reset(Gen1, Random_Seed);
      Random_Seed := Random_Seed + 1;
      Exp_Random.Reset(Gen2, Random_Seed);
      Random_Seed := Random_Seed + 1;

      loop
         Mantissa := -1.0;
         Mantissa := Mantissa + Ada.Numerics.Float_Random.Random(Gen1);
         Mantissa := Mantissa + Ada.Numerics.Float_Random.Random(Gen1);

         Result := Float'Compose(Mantissa, Exp_Random.Random(Gen2));
      exit when Result > Min and Result < Max;
      end loop;

      return Result;
   end Random;





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

* Re: Random Number Generation
  1996-10-02  0:00  Dr J Parker
@ 1996-10-03  0:00 ` Mats Weber
  1996-10-07  0:00 ` Geert Bosch
  1 sibling, 0 replies; 57+ messages in thread
From: Mats Weber @ 1996-10-03  0:00 UTC (permalink / raw)



>Suppose you have a high quality random number generator R1 in the range
>0 .. 1023
>and you want to turn it into a high quality random number generator R2
>in the range 0 .. 2.

[...]

The problem here is that you rarely have a high quality generator on all
bits of the result. Generators usually are high quality on their most
significant bits, and it is very important to use the leftmost bits of the
original generator during the range reduction.




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

* Re: Random Number Generation
  1996-10-02  0:00  Dr J Parker
  1996-10-03  0:00 ` Mats Weber
@ 1996-10-07  0:00 ` Geert Bosch
  1 sibling, 0 replies; 57+ messages in thread
From: Geert Bosch @ 1996-10-07  0:00 UTC (permalink / raw)



Dr J Parker (jp3@rl.ac.uk) wrote:
`` Another simple example:

   Suppose you have a high quality random number generator R1 in the range
   0 .. 1023 and you want to turn it into a high quality random number
   generator R2 in the range 0 .. 2. ''

This is not a simple example. It is not possible to write an
Ada program that does convert R1 to R2 and is guaranteed to
finish in finite time.

Regards,
   Geert
-- 
E-Mail: geert@sun3.iaf.nl    
      ``I think there is a world market for maybe five computers.''
        Thomas Watson,  chairman of IBM, 1943





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

* Re: Random Number Generation
@ 1996-10-10  0:00  Dr J Parker
  1996-10-12  0:00 ` Keith Thompson
  1996-10-12  0:00 ` Geert Bosch
  0 siblings, 2 replies; 57+ messages in thread
From:  Dr J Parker @ 1996-10-10  0:00 UTC (permalink / raw)



Jonathan Parker (jp3@rl.ac.uk) wrote:
-`` Another simple example:
-
-   Suppose you have a high quality random number generator R1 in the range
-   0 .. 1023 and you want to turn it into a high quality random number
-   generator R2 in the range 0 .. 2. ''
-
-This is not a simple example. It is not possible to write an
-Ada program that does convert R1 to R2 and is guaranteed to
-finish in finite time.
-
-Regards,
-   Geert
--
-E-Mail: geert@sun3.iaf.nl


Nah... the rejection method is rigorously correct, and so is
the subsequent use of x rem 3 in the code fragment below.

The original post never reached some newsreaders so I repeat it below.
btw, the answer to the ? below is about N = 10**7, about 10 secs
on a PC.  If R1 has range
0..2**15-1 instead then it takes about an hour to detect the bias.
The method Tucker suggests is one of best, provided
you know how it can fail and you know how to avoid it.

cheers, Jonathan


*******************************************************8
Another Simple example:

Suppose you have a high quality random number generator R1 in the range
0 .. 1023
and you want to turn it into a high quality random number generator R2
in the range 0 .. 2.

R1 has 8 more bits than R2.

Suppose you try R2  =  R1 / 342.

this maps
0..341    to 0,
342..683  to 1
684..1023 to 2

0 has probability 342/1024, 1 has probability 342/1024, and
2 has probability 340/1024.

You can use  R1 mod 3, get same problem.
You can use  R1 * 3.0, with floating point R1 in [0.0..1.0)
and you get same problem if R1 has 1024  elements in its range.

Suppose you think R2 is uniformly distributed in 0,1, 2.
How many trials (N) would it take to detect the bias?

In under 5 miinutes you can generate N = 3 * 10**8 random numbers on
a PC.  expect 10**8 0's, 10**8 1's 10**8 2's , with stnd deviation
about 10**4 and error = 10**8 * 1.333/1024.0.

You get wrong answer by about 10 stnd deviations!

And all you had to do was reject number 1023 from the range of R2!
(because the number of elements in the range of 0..1022 is
divisible by 3.)

x := random;
while x > R1'Last - 1024 rem 3 loop
   x := random;
end loop;
return x rem 3;
*********************************************************




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

* Re: Random Number Generation
@ 1996-10-10  0:00  Dr J Parker
  0 siblings, 0 replies; 57+ messages in thread
From:  Dr J Parker @ 1996-10-10  0:00 UTC (permalink / raw)



I wrote

-In under 5 miinutes you can generate N = 3 * 10**8 random numbers on
-a PC.  expect 10**8 0's, 10**8 1's 10**8 2's , with stnd deviation
-about 10**4 and error = 10**8 * 1.333/1024.0.

meaning of course:

error = 3 * 10**8 * 1.333/1024.0 in one of the 3 bins.






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

* Re: Random Number Generation
  1996-10-10  0:00  Dr J Parker
  1996-10-12  0:00 ` Keith Thompson
@ 1996-10-12  0:00 ` Geert Bosch
  1 sibling, 0 replies; 57+ messages in thread
From: Geert Bosch @ 1996-10-12  0:00 UTC (permalink / raw)



I wrote:
`` This is not a simple example. It is not possible to write an
   Ada program that does convert R1 to R2 and is guaranteed to
   finish in finite time. ''

Dr J Parker (jp3@rl.ac.uk) responded:
`` Nah... the rejection method is rigorously correct, and so is
   the subsequent use of x rem 3 in the code fragment below. ''

I don't say it is not possible to present a correct algorithm
to convert R1 to R2. Such a correct algorithm just is not guaranteed to
finish in finite time.

Your algorithm:
`` x := random;
   while x > R1'Last - 1024 rem 3 loop
      x := random;
   end loop;
   return x rem 3; ''

You can't give an upper boundary for the number of iterations
of the while loop if R1 is a truly random generator.

Of course in practise you're only interested in having an
algorithm that has a good probability to finish in a certain
amount of time.

I just pointed out that the example wasn't that simple.
Somebody using this code should be aware of that.

Regards,
   Geert
-- 
E-Mail: geert@sun3.iaf.nl    
      ``I think there is a world market for maybe five computers.''
        Thomas Watson,  chairman of IBM, 1943





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

* Re: Random Number Generation
  1996-10-10  0:00  Dr J Parker
@ 1996-10-12  0:00 ` Keith Thompson
  1996-10-12  0:00 ` Geert Bosch
  1 sibling, 0 replies; 57+ messages in thread
From: Keith Thompson @ 1996-10-12  0:00 UTC (permalink / raw)



In <53jgrh$r20@newton.cc.rl.ac.uk> jp3@rl.ac.uk ( Dr J Parker) writes:
> Jonathan Parker (jp3@rl.ac.uk) wrote:
> -`` Another simple example:
> -
> -   Suppose you have a high quality random number generator R1 in the range
> -   0 .. 1023 and you want to turn it into a high quality random number
> -   generator R2 in the range 0 .. 2. ''
> -
> -This is not a simple example. It is not possible to write an
> -Ada program that does convert R1 to R2 and is guaranteed to
> -finish in finite time.
> -
> -Regards,
> -   Geert
> --
> -E-Mail: geert@sun3.iaf.nl
> 
> Nah... the rejection method is rigorously correct, and so is
> the subsequent use of x rem 3 in the code fragment below.

I think the point is that you can't convert R1 into R2 without rejecting
some value from R1; typically, you'd reject the value 1023 and map

       0 ..  340 => 0
     341 ..  681 => 1
     682 .. 1022 => 2

If R1 is truly random, there's no guarantee that it won't generate an
arbitrarily long sequence of 1023's; therefore the conversion is not
guaranteed to finish in finite time.  Geert: is this what you meant?

In practice, of course, this probably won't matter; long sequences of a
single value are vanishingly rare.  It might matter for a hard realtime
system.  In that case, you could give up and return an arbitrary value
after N failed attempts; the choice of N is a tradeoff between worst-case
behavior and the quality of the random output.

I think there may actually be a way around this, similar to the way
uuencode maps 3 input bytes (base 256) to 4 output characters (base
64).  The first R1 value (0..1023) would give you 6 R2 values (0..2)
with a little bit of randomness to spare.  It's more difficult than
uuencode since the input and output will never actually resynchronize.
(There must be a way to state this more precisely.)  I'm too lazy to
figure out the details.

-- 
Keith Thompson (The_Other_Keith) kst@thomsoft.com <*>
TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2706
FIJAGDWOL




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

* Re: Random Number Generation
  1996-10-13  0:00 Random Number Generation parker
@ 1996-10-13  0:00 ` Robert Dewar
  1996-10-14  0:00 ` Robert A Duff
  1 sibling, 0 replies; 57+ messages in thread
From: Robert Dewar @ 1996-10-13  0:00 UTC (permalink / raw)



Geert said

""I don't say it is not possible to present a correct algorithm
to convert R1 to R2. Such a correct algorithm just is not guaranteed to
finish in finite time.
"

Yes, this is guaranteed to finish in finite time if you are using a
compiler that meets the requirements of the numerics annex with regard
to the random number generator performance.





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

* Re: Random Number Generation
@ 1996-10-13  0:00 parker
  1996-10-13  0:00 ` Robert Dewar
  1996-10-14  0:00 ` Robert A Duff
  0 siblings, 2 replies; 57+ messages in thread
From: parker @ 1996-10-13  0:00 UTC (permalink / raw)




Geert Bosch wrote:

"I don't say it is not possible to present a correct algorithm
to convert R1 to R2. Such a correct algorithm just is not guaranteed to
finish in finite time.

Your algorithm:
`` x := random;
   while x > R1'Last - 1024 rem 3 loop
      x := random;
   end loop;
   return x rem 3; ''

You can't give an upper boundary for the number of iterations
of the while loop if R1 is a truly random generator.

Of course in practise you're only interested in having an
algorithm that has a good probability to finish in a certain
amount of time.

I just pointed out that the example wasn't that simple.
Somebody using this code should be aware of that. "


Now I see what you're getting at.
I wouldn't worry about it tho.....overhead from M rejections goes linearly
with M (M calls to R1), probability of M rejections goes as 2**(-M*10)...

Keith and Geert are concerned about fluctuating overhead in the rejection
method.  I like Keith's solution: an upper limit on the number of
rejections.  In this case, if the upper limit is set to 2, then the error
is undetectable: ie if you reject 2 1023's in a row, then accept whatever 
comes next; the offending 3 1023's come with a probability of 2**(-30)
for an undetectable bias.  So max overhead is 3 calls to R1, average
overhead is 1.001 calls to R1 (plus the if, and the rem).

An alterative with same error, but constant overhead: make R1 into
the range 0..2**30-1. iTo do this think of R1 as returnig a single
digit number base 1024; use 3 calls to R1 to make x, 
a 3 digit number  base 1024.  Now
just return x rem 3: same bias, same max overhead as other
method, but 3 times the average overhead.

cheers, Jonathan





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

* Re: Random Number Generation
  1996-10-13  0:00 Random Number Generation parker
  1996-10-13  0:00 ` Robert Dewar
@ 1996-10-14  0:00 ` Robert A Duff
  1 sibling, 0 replies; 57+ messages in thread
From: Robert A Duff @ 1996-10-14  0:00 UTC (permalink / raw)



In article <13OCT96.18283680@enh.nist.gov>,  <parker@enh.nist.gov> wrote:
>
>Geert Bosch wrote:
>
>"I don't say it is not possible to present a correct algorithm
>to convert R1 to R2. Such a correct algorithm just is not guaranteed to
>finish in finite time.
>
>Your algorithm:
>`` x := random;
>   while x > R1'Last - 1024 rem 3 loop
>      x := random;
>   end loop;
>   return x rem 3; ''
>
>You can't give an upper boundary for the number of iterations
>of the while loop if R1 is a truly random generator.

But so-called "random number generators" are *not* really random.
They're really pseudo-random number generators, and they will eventually
produce a value that will cause the above loop to terminate.  R1 will
*not* generate an arbitrarily long series of 1024's, or whatever, even
though a *truly* random sequence might.

The above loop *might* take a long time, but in any case, it *is*
finite, given a pseudo-random number generator.

Of course, in a real-time situation, you want a small upper bound on
that time, which Jonathan addresses:

>An alterative with same error, but constant overhead: make R1 into
>the range 0..2**30-1. iTo do this think of R1 as returnig a single
>digit number base 1024; use 3 calls to R1 to make x, 
>a 3 digit number  base 1024.  Now
>just return x rem 3: same bias, same max overhead as other
>method, but 3 times the average overhead.

- Bob




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

* random number generation
@ 1997-12-19  0:00 Mok-kong Shen
  1998-01-02  0:00 ` Mok-kong Shen
  0 siblings, 1 reply; 57+ messages in thread
From: Mok-kong Shen @ 1997-12-19  0:00 UTC (permalink / raw)



Hello,

If you are interested in random number sequences, I like to invite you
to look at a combined pseudo-random number generator designed by me.
The underlying algorithm, which to my knowledge has not appeared
previously in the literature, is in fact extremely simple:

   j:=0; do output(G(j)); j:=trunc(n*G(j)) od;

where G(j) (0<=j<n) are n pseudo-random number generators (with output
in [0,1)) that can be arbitrarily given by the user, i.e. no particular
requirements of statistical qualities are imposed on them. These n
constituent generators can be of any kind; their parameters can be,
in particular, randomly chosen with the help of one additional pseudo-
random number generator.

The basic idea is the following: Each of the n constituent generators
produces an output stream that is, depending on its quality, more or
less random. If one randomly interleaves these streams, then the
result should be more random. In other words, the auto-correlations
that exist in the n individual output streams get lost through the
mixing process since elements that are at distance d (d>=1) apart
from one another in any particular one of the n output streams are no
longer at any fixed distance, say d', apart on the combined output.
Besides, half of the output of each generator is consumed internally
and does not appear as the output of the combined generator. From
the algorithm it can be seen that auto-correlations of elements at
distance d=1 apart of the n individual output streams are totally
lost on the combined output stream.

I found through experiments that the combined generator thus built
behaves, as expected, indeed very satisfactorily in both the frequency
and the serial test. Its qualities very quickly asymptotically improve
with larger n. Since the computing cost pro each output element of the
combined generator is independent of n, meaning that n can be chosen
to be fairly large without penality, I suppose that this scheme could
be very useful for practical applications.

Please give your comments and critiques. A well-documented Fortran 90 
implementation is available on

http://www.stud.uni-muenchen.de/~mok-kong.shen/

See also the attachment below.

------------------------------------------------------------
The following is a fragment taken from an old unpublished report of
mine. The experiment (referred to as 'a small-scale test run' in my Web
document) was done at a time when the PCs were of 20MHZ, hence the test
sequences were short. Later experiments confirmed the superior
statistical behaviour previously found of my algorithm. (Note that the
generation of the constituent generators in the computer program
provided in the Web document is done somewhat differently from what is
described below.)


   In order to quantitatively verify the performance of our algorithm as
predicted from the theoretical considerations above, an experiment was
done on a set of generators that were each internally based on a LCPRNG
of the mixed type. The coefficients of these LCPRNG's were themselves
generated by a random number generator named RANDOM provided by the UNIX
operating system. In order to obtain large periods of the sequences
generated, we posed the requirement that the modulus of each LCPRNG be a
prime lying between 2**18 and 2**30. Otherwise, all coefficients of the
congruence relations involved were randomly chosen, subject to the
single necessary constraint that no arithmetic overflow should ever
occur on a computer of 32 bit word length. The sequence of integers
obtained from each LCPRNG were divided by the corresponding modulus so
that the output of each generator was real numbers in the range [0,1).
We obtained in this manner 12 generators to serve as constituent
generators of our scheme. Then we applied our algorithm for n=1 to the
first generator obtained. The system output was multiplied by 32 and
then truncated so that a sequence of random integers lying between 0 and
31 was obtained. On this sequence, of length 10000, the serial test
(non-overlapping) was applied, leading to the values of the test
statistic given for n=1 in the table below for three different values of
the distance u. Next we applied our algorithm for n=2 to the set
consisting of the first and the second generator, leading to the values
of the test statistic given for n=2 in the table. The other entries of
the table were obtained in analogous fashion.

   Note that for n=1 and u=1 the value of the test statistic obtained is
very large. In fact, even larger values were obtained with the serial
test applied directly to the output of any of the 12 randomly chosen
random number generators (test done on integer sequences in [0,31] as
above). This is in conformance to the well-known fact that it is
extremely difficult to find coefficients for a LCPRNG such that its
output is satisfactory in respect of statistical correlations. For n>=9
the test statistic of our combined generator has apparently attained
values that cannot be further improved, i.e. values that would also have
been obtained even from truly random sequences.

             n     u=1      u=2      u=3
             1   31251.6   5740.9   1104.2
             2    8641.3   3402.1   1706.0
             3    3158.0   1674.8   1354.6
             4    1917.3   1264.4   1198.1
             5    1610.9   1252.1   1114.1
             6    1489.7   1139.5   1096.0
             7    1461.9   1144.0   1090.7
             8    1362.7   1044.9   1106.3
             9    1185.0   1162.9   1043.2
            10    1155.9    975.2   1022.7
            11    1155.5   1016.6   1001.4
            12    1085.8   1067.0   1070.6

   For comparison purposes, we also ran the serial test (in the same
manner as above) directly on the output of the generator RANDOM of the
UNIX operating system, the generator G05CAF of the NAG library and the
generator RNUNF of the IMSL library. The values of the test statistic
obtained are given below. It can be clearly seen by comparing the two
tables that through combining some 10 fairly bad random number
generators according to our algorithm we have succeeded to obtain output
sequences whose quality is comparable to that of the three well-known
good random number generators examined.

                    u=1      u=2      u=3
          RANDOM   1001.1    978.9    979.7
          G05CAF   1078.5   1033.4   1036.2
          RNUNF    1028.1   1016.2    947.3




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

* Re: random number generation
  1997-12-19  0:00 Mok-kong Shen
@ 1998-01-02  0:00 ` Mok-kong Shen
  1998-01-02  0:00   ` Robert Dewar
  0 siblings, 1 reply; 57+ messages in thread
From: Mok-kong Shen @ 1998-01-02  0:00 UTC (permalink / raw)



Since I received comments and critiques from several readers of my
article, I think it is appropriate to respond to them all in one
follow-up rather than in seperate pieces. Formally it is a response
to Herman Rubin.


Herman Rubin <hrubin@stat.purdue.edu> wrote on 23 Dec 1997:

>In article <349AC478.47988774@stud.uni-muenchen.de> you write:
>>Hello,
>>
>>If you are interested in random number sequences, I like to invite you
>>to look at a combined pseudo-random number generator designed by me.
>>The underlying algorithm, which to my knowledge has not appeared
>>previously in the literature, is in fact extremely simple:
>>
>>   j:=0; do output(G(j)); j:=trunc(n*G(j)) od;
>>
>>where G(j) (0<=j<n) are n pseudo-random number generators (with output
>>in [0,1)) that can be arbitrarily given by the user, i.e. no particular
>>requirements of statistical qualities are imposed on them. These n
>>constituent generators can be of any kind; their parameters can be,
>>in particular, randomly chosen with the help of one additional pseudo-
>>random number generator.

>>The basic idea is the following: Each of the n constituent generators
>>produces an output stream that is, depending on its quality, more or
>>less random. If one randomly interleaves these streams, then the
>>result should be more random. In other words, the auto-correlations
>>that exist in the n individual output streams get lost through the
>>mixing process since elements that are at distance d (d>=1) apart
>>from one another in any particular one of the n output streams are no
>>longer at any fixed distance, say d', apart on the combined output.
>>Besides, half of the output of each generator is consumed internally
>>and does not appear as the output of the combined generator. From
>>the algorithm it can be seen that auto-correlations of elements at
>>distance d=1 apart of the n individual output streams are totally
>>lost on the combined output stream.


>It is not totally clear what you are doing.  Something like this
>is discussed by Knuth, and the results are not that good.


Like the method of MacLaren and Marsaglia, my algorithm effects a
shuffling of the outputs of PRNGs. MacLaren and Marsaglia shuffle the
output of one single PRNG with the help of another PRNG, while I
shuffle the outputs of n PRNGs with the help of these n PRNGs
themselves. The outputs of the n PRNGs are interleaved (mixed up) in a
(pseudo-)random way, because the order of activations of the PRNGs is
not fixed (like e.g. round-robin) but is determined at runtime of the
algorithm by the current outputs of the PRNGs. This can be easily
seen from the algorithm.  (If not, a paper and pencil exercise with,
say, 3 PRNGs should make this interleaving clear.)

Knuth may have found that some existing methods of combinations of
PRNGs or of shuffling are poor (I haven't checked through his book),
but I am quite sure that he didn't give categorical statements to the
effect that such approaches were doomed to be a failure from the
very beginning, for that would have been a non-scientific way of
argumentation. It is well-known that shuffling appears to be not
amenable to rigorous formal mathematical analysis and hence has the
disadvantage of having to be treated on a more or less heuristic
basis. Thus J. Dagpunar writes in his Principles of Random Variate
Generation, Clarendon, Oxford, 1988, on p.35 the following:

     Given the inevitable dependencies that will exist in a 'random'
     sequence, it seems natural that one should try to shuffle the
     output of a sequence, in the hope that this will make it more
     random. Examples of such approaches are MacLaren  and
     Marsaglia (1965) and Bays and Durham (1976).

without giving pointers to any text where rigorous formal mathematical
analysis of the merits of shuffling could be found. The consequence
of this is that such methods need more extensive tests before they
can be accepted for application as compared to those methods that
are easily amenable to mathematical analysis. On the other hand, this
clearly does in no way rule out that certain shuffling methods could
be very successful nevertheless. This can be seen from the following
which is taken from the User's Manual of IMSL STAT/Library, vol. 3,
p.947:

     The user can also select a shuffled version of these generators
     using RNOPT. The shuffled generators use a scheme due to
     Learmonth and Lewis (1973a). ....... This scheme is similar to
     that of Bays and Durham (1976), and their analysis would be
     applicable to this scheme as well.

Since several readers mentioned Knuth, it is interesting to know what
Knuth writes in his book (1969, p.30) about the method of MacLaren
and Marsaglia which is one of the best known existing shuffling methods
(hence not amenable to rigorous mathematical analysis todate):

     A much better method has been suggested by MacLaren and
     Marsaglia, and is eminently suited to computer programming.  ....
     ....... This method can be highly recommended.

Let me now expand my arguments about correlations. Consider the output
of a particular one of the n PRNGs, say, G(k) for a fixed k. Let its
output be (t_i) (i=1,2,.....). Depending on the parameters of G(k),
this sequence has more or less strong auto-correlations. There is
dependency between t_i and t_(i+1) for i=1,2,....., which makes for the
auto-correlation at distance d=1. There is dependency between t_i and
t_(i+2) for i=1,2,....., which makes for the auto-correlation at
distance d=2. Analog for auto-correlations at other values of d. My
algorithm is designed such that t_i and t_(i+1) never both appear as
output of the combined generator. Therefore the auto-correlation at
distance d=1 originally present in the output sequence of G(k) is
completely lost on the output stream of the combined generator. Let
us now investigate what happens to the auto-correlation at distance
d=2 of the sequence output by G(k). Depending on the value of i,
t_i and t_(i+2) either both appear as output of the combined generator
or both do not appear as the output of the combined generator. Of
those pairs t_i and t_(i+2) that do appear as the output of the
combined generator the following happens: While t_i and t_(i+2) are
at a constant distance d=2 apart within the original output sequence
of G(k), they are in general at another distance d' apart (on the
output sequence of the combined generator) which, in consequence of
the (pseudo-)random interleaving of the n output streams of the PRNGS,
is not a constant for all i, in other words, d' takes on a spectrum of
different values. Consequently, the auto-correlation at d=2 originally
present in the output of G(k) becomes 'distributed' into auto-
correlations at a number of distances d' on the output stream of the
combined generator. Analogous arguments apply to auto-correlations at
d=3,4,..... that are present in the output sequence of G(k). Lastly
one should consider possible dependency between any two elements in
the output sequence of the combined generator that are originated
from different constituent PRNGs. This question turns out to be very
simple. The n PRNGs are assumed to have been chosen independent from
one another. Hence there is no dependency between a pair of elements
of the said kind.

There are two aspects of my algorithm particularly worthy of notice.
The first aspect is that n, the number of constituent PRNGs, can be
chosen to be arbitrary large (practically without limit) without
causing penalty in computing cost, which means that one can freely
tune the quality of the output of the combined generator through
the value of n. (As I found through experiments, the results of the
serial test asmyptotically improves with increasing n.) This is not
true, as far as my knowledge goes, for other existing shuffling
methods employing more than one PRNG. As a consequence, they are
limited, for the practical reason of economy, to using very small
values of n.  The second aspect is that only one half of the total
outputs of the n constituent generators appear as the output of the
combined generator, while the other half is consumed internally, thus
rendering the inference of the parameters of the n constituent PRNGs
(n itself has to be inferred) much more difficult. This is of
essential significance to information security applications, though
perhaps of no particular relevance to normal statistical computations.

It may be mentioned that my design originally started from a simpler
one:

      j:=0; do t:=G(j); output(t); j:=trunc(n*t) od;

This has the advantage of having a computing cost factor of 1 instead
of 2 of my final design. However, I prefer the scheme posted in my
article because of (1) the complete elimination of the original
auto-correlation at d=1, which is normally the more significant of
the spectrum of auto-correlations and (2) the much enhanced complexity
of inferring the parameters of the constituent PRNGs as a result of
the suppression of one half of their outputs.

Some readers have pointed to the following two issues of interest:

(a) Consider the PRNG G(0). If it continues to generate numbers close
to 0.0 for a long time, then G(0) will always be selected during that
period by the algorithm and the remaining n-1 PNRGs will not
contribute to the output of the combined generator. This is certainly
undesirable. Analogous argument applies to G(k) for any k. However,
the pathological case for G(0) could only arise if its parameters
are extremely bad. This is rendered impossible through a bit careful
programming of the algorithm. See in this regard the implementation
on my Web page, where the linear congruential relations have 
sufficiently large moduli. Those who still feel uncomfortable may
consider the following variant of the algorithm:

     j:=0; do output(G(j)); j1:=trunc(n*G(j));
              if j=j1 then j:=j+1 mod n else j:=j1 fi od;

(b) The implementation provided on my Web page uses only two input
values, namely n and a seed for the standard PRNG that is used to
generate the paramenters of the n PRNGs. Consequently an inferencer
has only these two numbers to deal with. However, my implementation
is programmed to show simply how my algorithm may be essentially
realized. If one choose n=10000, one could let the parameters of the
10000 constituent PRNGs be input by the user, if one likes. A
practically more useful set of input values can contain m seeds,
with each seed being used for the construction of a subset of the
n PRNGs. One could also use several standard PRNGs instead of a
single one that is employed in my implementation. Finally it is to
be noted that the algorithm does not prescribe the type of the
n constituent PRNGs. These can be, in particular, non-linear PRNGs,
instead of being based on linear congruential relations as in my
implementation.


>One should test for the randomness of bits, rather than numbers.
>Congruential generaters are know to be atrocious for tail bits.
>Also, it is easy to fix up congruential generators to give low
>serial correlations without really giving independence.  Even
>the non-random quasi-random streams have 0 correlation, but
>essentially complete dependence (except for rounding).
>-- 
>This address is for information only.  I do not claim that these views
>are those of the Statistics Department or of Purdue University.
>Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907-1399
>hrubin@stat.purdue.edu         Phone: (765)494-6054   FAX: (765)494-0558


I must admit that I possess little knowledge of the details of the
'non-randomness' of the tail bits of numbers produced by
congruential generators. If I don't err, this concerns directly the
integer-valued numbers that are computed. My algorithm requires
that the constituent PRNGs output real-valued numbers in [0,1).
Now the integer-valued numbers obtained from the congruential
relations have to be divided by the corresponding moduli in order
to produce the real-valued numbers in [0,1). I have a strong feeling
that any 'non-randomness' of the tail bits of the integer-valued
numbers will be much reduced, if not rendered entirely negligible,
when the division process is invoked and when the output streams
of the n constituent PRNGs are (pseudo-)randomly interleaved, in
particular, when n is chosen to be sufficiently large. In any case,
I should appreciate being able to access any concrete materials
on the 'non-randomness' of the tail bits of either the integer-
valued numbers or the mantissa of the real-valued numbers
originated from congruential relations.


To conclude, I think I have provided sufficient (informal) explanation
of why my algorithm should produce output of low auto-correlations
and why the inference of the parameters of the PRNGs is likely to
be very difficult. On the other hand, I have done yet very little
tests. While the serial test is considered in the literature to be
fairly reliable for detecting dependencies, it is only one of a
currently existing huge battery of tests that are recommended. My
personal problem is that I do not have the hardware resources to carry
out even a small portion of these tests, not to mention the more grave
issue that the running and the evaluation of the results of the
software packages involved could demand expertise that is well
beyond my humble knowledge. Thus I hope that my posted article could
attract the attentions of some experts who, being knowledgeable and
possessing sufficient hardware resources, would be kind enough to
critically examine my algorithm by subjecting it to a wide range
of tests which I could not perform, thus refuting or confirming
my subjective opinion on its merits. Lastly I like to mention
that essentials of the above arguments plus some other points may
be found on my Web page and that a tiny reward of US$300 is offered
to the expert who is kind enough to help me.

M. K. Shen

______________________________________________________
------------------------------------------------------
Apology:
On 29-30th Dec 1997 someone, cracking my login password and using 
my e-mail address, has sent a number of faked mails of schizophrenic
(fortunately non-criminal) content. These probably all have at the
bottom the name of a certain Molana, as could be deduced from some
mails that were bounced back because the target addresses happened
to be invalid. I sincerely regret the inconvenience that these faked
mails have caused to their receivers.

------------------------------------------------------
M. K. Shen, Postfach 340238, D-80099 Muenchen, Germany
+49 (89) 831939   (6:00 GMT)
mok-kong.shen@stud.uni-muenchen.de
http://www.stud.uni-muenchen.de/~mok-kong.shen/
(containing 2 mathematical problems with rewards totalling US$500)

----------------------------------------------
Sunshine is the best disinfectant.
(citation of a citation in B. Schneier and D. Banisar, The Electronic
Privacy Papers. John-Wiley, New York, 1997.)

----------------------------------------------
The words of a man's mouth are as deep waters, and the wellspring 
of wisdom as a flowing brook.   (Proverbs 18:4)

A little that a righteous man hath is better than the riches of many
wicked.   (Psalms 37:16)




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

* Re: random number generation
  1998-01-02  0:00 ` Mok-kong Shen
@ 1998-01-02  0:00   ` Robert Dewar
  0 siblings, 0 replies; 57+ messages in thread
From: Robert Dewar @ 1998-01-02  0:00 UTC (permalink / raw)



Mok-kong says

<<Knuth may have found that some existing methods of combinations of
PRNGs or of shuffling are poor (I haven't checked through his book),
>>


Casual conversation on the net is not a substitute for reading the literature.
If you are interested in random number generators, you most certainly need to
be fully aware of the literature. The Knuth reference is just one of many that
should be familiar to you.





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

* random number generation
@ 2003-09-26  7:00 Andrew
  2003-09-26  7:35 ` tmoran
  0 siblings, 1 reply; 57+ messages in thread
From: Andrew @ 2003-09-26  7:00 UTC (permalink / raw)


I need to write a program to randomly grab a integer from 1 - 4,and 
output the result to the screen.  In some languages this would be a 
fairly simple procedure.  Sometimes it is just a simple, single command 
line to get the random number and one more to put the result to the 
screen.

Does this exist in Ada?
      I don't believe it does from what I have been reading.
      But if it does please let me know.




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

* Re: random number generation
@ 2003-09-26  7:14 christoph.grein
  0 siblings, 0 replies; 57+ messages in thread
From: christoph.grein @ 2003-09-26  7:14 UTC (permalink / raw)
  To: comp.lang.ada

> I need to write a program to randomly grab a integer from 1 - 4,and 
> output the result to the screen.  In some languages this would be a 
> fairly simple procedure.  Sometimes it is just a simple, single command 
> line to get the random number and one more to put the result to the 
> screen.
> 
> Does this exist in Ada?
>       I don't believe it does from what I have been reading.
>       But if it does please let me know.

RM A.5.2



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

* Re: random number generation
  2003-09-26  7:00 Andrew
@ 2003-09-26  7:35 ` tmoran
  2003-09-26 17:58   ` Andrew
  2003-09-26 19:25   ` Andrew
  0 siblings, 2 replies; 57+ messages in thread
From: tmoran @ 2003-09-26  7:35 UTC (permalink / raw)


>I need to write a program to randomly grab a integer from 1 - 4,and
>Does this exist in Ada?
  type Options is range 1 .. 4;
  package Generate_Options is new Ada.Numerics.Discrete_Random(Options);
  A_Generator : Generate_Options.Generator;
  ...
  X := Generate_Options.Random(A_Generator);
  Ada.Text_IO.Put_Line("Selected option is" & Options'image(X));
You could of course replace type Options with
  type Suits is (Spades, Hearts, Diamonds, Clubs);
and have several Dealers instead of a single A_Generator, and so forth.

>      I don't believe it does from what I have been reading.
  What have you been reading?  If your book doesn't cover random
number generation, you can go to the authoritative source, section
A.5.2 of the Ada 95 Reference Manual (available online).



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

* Re: random number generation
  2003-09-26  7:35 ` tmoran
@ 2003-09-26 17:58   ` Andrew
  2003-09-26 19:25   ` Andrew
  1 sibling, 0 replies; 57+ messages in thread
From: Andrew @ 2003-09-26 17:58 UTC (permalink / raw)




tmoran@acm.org wrote:
>>I need to write a program to randomly grab a integer from 1 - 4,and
>>Does this exist in Ada?
> 
>   type Options is range 1 .. 4;
>   package Generate_Options is new Ada.Numerics.Discrete_Random(Options);
>   A_Generator : Generate_Options.Generator;
>   ...
>   X := Generate_Options.Random(A_Generator);
>   Ada.Text_IO.Put_Line("Selected option is" & Options'image(X));
> You could of course replace type Options with
>   type Suits is (Spades, Hearts, Diamonds, Clubs);
> and have several Dealers instead of a single A_Generator, and so forth.
> 
> 
>>     I don't believe it does from what I have been reading.
> 
>   What have you been reading?  If your book doesn't cover random
> number generation, you can go to the authoritative source, section
> A.5.2 of the Ada 95 Reference Manual (available online).



thank you to both of you




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

* Re: random number generation
  2003-09-26  7:35 ` tmoran
  2003-09-26 17:58   ` Andrew
@ 2003-09-26 19:25   ` Andrew
  2003-09-26 19:35     ` chris
                       ` (2 more replies)
  1 sibling, 3 replies; 57+ messages in thread
From: Andrew @ 2003-09-26 19:25 UTC (permalink / raw)




tmoran@acm.org wrote:
>>I need to write a program to randomly grab a integer from 1 - 4,and
>>Does this exist in Ada?
> 
>   type Options is range 1 .. 4;
>   package Generate_Options is new Ada.Numerics.Discrete_Random(Options);
>   A_Generator : Generate_Options.Generator;
>   ...
>   X := Generate_Options.Random(A_Generator);
>   Ada.Text_IO.Put_Line("Selected option is" & Options'image(X));
> You could of course replace type Options with
>   type Suits is (Spades, Hearts, Diamonds, Clubs);
> and have several Dealers instead of a single A_Generator, and so forth.
> 
> 
>>     I don't believe it does from what I have been reading.
> 
>   What have you been reading?  If your book doesn't cover random
> number generation, you can go to the authoritative source, section
> A.5.2 of the Ada 95 Reference Manual (available online).


ok in the previous post .. I said thanks for the help.. and I've been 
trying to figure out how to implement the code that you gave me above..

the problem is I get errors such as
mazecreate.adb:18:04: statement not allowed in declarative part

or

mazecreate.adb:26:01: declarations must come before "begin"

depending on exactly how I set the code up.

here is the coding at it's current standing.
========================================
====================================

-- This program is to open file 'Map2', then print a bunch of characters 
'x' in the
-- form of a square.
 

with TEXT_IO;
use TEXT_IO;
procedure Mazecreate is
    spot: CHARACTER:='x';
    spott: CHARACTER:='T';
    sitt: Boolean:=True;
    orig: INTEGER:=5;  -- point of origin for map
    down: Integer:=10;  -- down map
    acros: INTEGER:=11; -- across map
    row: INTEGER:=1;
    col: INTEGER:=1;
    X: INTEGER;
    map_file:FILE_TYPE;

    A_Generator : Generate_Options.Generator;
    X:= Generator_Options.Random(A_Generator);
 

    package Number_IO is new INTEGER_IO(INTEGER);
    use Number_IO;
    package FLOAT1_IO is new FLOAT_IO(FLOAT);
    use FLOAT1_IO;

    type Options is range 1 .. 4;
    package Generate_Options is new
       Ada.Numerics.Discrete_Random(Options);

Begin
 
                         -- **********************
-- ** section to print **
-- **   the randomly   **
-- **  created number  **
-- **********************

   Ada.Text_IO.Put_Line("Selected option is" & Options'image(X));

 

    -- *********************
    -- **   section to    **
    -- **   create the    **
    -- ** square of Stars **
    -- *********************
 
                              Create (map_file, out_FILE, "Map2");
    if IS_OPEN(map_file) then
       for i in 1..down loop
          for j in 1..acros loop
          put (map_file, spot);
          end loop;
        NEW_LINE(map_file);
       end loop;
       Put(map_file, spott);
       CLOSE (map_file);
 

   else
      Put_Line("Map file didn't open .. Killing Program");
      Return;
end if;
 

end Mazecreate;
==============================
===============================================
Now I know I have something wrong on the above code.. but I can't figure 
out what is wrong.. and I've tried moving different sections of your 
code around.. but to no avail.

any help is appreciated.
Andrew




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

* Re: random number generation
  2003-09-26 19:25   ` Andrew
@ 2003-09-26 19:35     ` chris
  2003-09-26 21:44     ` tmoran
  2003-09-27  1:40     ` Robert I. Eachus
  2 siblings, 0 replies; 57+ messages in thread
From: chris @ 2003-09-26 19:35 UTC (permalink / raw)


Move

X := Generator_Options.Random(A_Generator);

into the begin ... end block.

HTH,
Chris




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

* Re: random number generation
  2003-09-26 19:25   ` Andrew
  2003-09-26 19:35     ` chris
@ 2003-09-26 21:44     ` tmoran
  2003-09-27  1:40     ` Robert I. Eachus
  2 siblings, 0 replies; 57+ messages in thread
From: tmoran @ 2003-09-26 21:44 UTC (permalink / raw)


> the problem is I get errors such as
> mazecreate.adb:18:04: statement not allowed in declarative part
    The compiler is trying to help you.
It's telling you that line 18 has a statement, but it's in a
declarative part, ie, a part where there are supposed to be just
declarations.  Looking at line 18, I see
    X:= Generator_Options.Random(A_Generator);
which is an assignment statement, not a declaration.
  It's also the case that Ada programs are normally readable from
top to bottom.  Your's has
    A_Generator : Generate_Options.Generator;
before you've declared what "Generate_Options" is, so you need
to move
    A_Generator : Generate_Options.Generator;
after
    package Generate_Options is new
       Ada.Numerics.Discrete_Random(Options);
Of course you will also need to tell the compiler what
Ada.Numerics.Discrete_Random is, by putting it in a "with" statement
at the beginning of your program.

  What is X?  A general integer, which can legitimately be negative or
very large, and which can be added and multiplied by any other Integer?
Or is X a code, say for card suits, or one of four symbols in maze, where
adding two of them together or multiplying by -3, would make no sense.
If it's a code, then you need
  X : Options;
(after Options has been declared) instead of
  X : Integer;
If X is a general purpose Integer, then type Options should be a subtype
of Integer, not a full-fledged type of its own, ie, it should be:
  subtype Options is Integer range 1 .. 4;
  I notice your program does not actually use X anywhere.  I presume
that's because you just haven't gotten to coding that yet.
  A couple other notes:  The Is_Open test right after Create is not
really necessary.  Either the file is open, or if there was a problem
creating such a file Create would have raised an exception and you
won't be executing the "if Is_Open" code.
  Having variables named "spot" and "spott" means that when you mistype one
as the other the compiler won't be able to warn you, and you'll wonder why
your program doesn't work right.  Better to choose names so a simple typo
will do something detectable by the compiler as an error.



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

* Re: random number generation
  2003-09-26 19:25   ` Andrew
  2003-09-26 19:35     ` chris
  2003-09-26 21:44     ` tmoran
@ 2003-09-27  1:40     ` Robert I. Eachus
  2003-09-27  4:48       ` Andrew
  2 siblings, 1 reply; 57+ messages in thread
From: Robert I. Eachus @ 2003-09-27  1:40 UTC (permalink / raw)


Andrew wrote:

> any help is appreciated.

Another thing.  If you don't call Reset for the random number generator, 
you will get the same sequence of random numbers every time you run the 
program.  This is intentional.  (It makes debugging easier.)

So once you have gotten far enough along, right after the begin put in

Reset(A_Generator); -- or whatever you called your generator.

That will set the generator based on the computer's real-time clock, and 
shouldn't repeat a seed during the next 50 years. (Unless you run your 
program on two different computers.  There are other ways of 
initializing the generator to be used when you have multiple generators, 
each running on its own CPU.)

-- 
                                                     Robert I. Eachus

"Quality is the Buddha. Quality is scientific reality. Quality is the 
goal of Art. It remains to work these concepts into a practical, 
down-to-earth context, and for this there is nothing more practical or 
down-to-earth than what I have been talking about all along...the repair 
of an old motorcycle."  -- from Zen and the Art of Motorcycle 
Maintenance by Robert Pirsig




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

* Re: random number generation
  2003-09-27  1:40     ` Robert I. Eachus
@ 2003-09-27  4:48       ` Andrew
  0 siblings, 0 replies; 57+ messages in thread
From: Andrew @ 2003-09-27  4:48 UTC (permalink / raw)




Robert I. Eachus wrote:
> Andrew wrote:
> 
>> any help is appreciated.
> 
> 
> Another thing.  If you don't call Reset for the random number generator, 
> you will get the same sequence of random numbers every time you run the 
> program.  This is intentional.  (It makes debugging easier.)
> 
> So once you have gotten far enough along, right after the begin put in
> 
> Reset(A_Generator); -- or whatever you called your generator.
> 
> That will set the generator based on the computer's real-time clock, and 
> shouldn't repeat a seed during the next 50 years. (Unless you run your 
> program on two different computers.  There are other ways of 
> initializing the generator to be used when you have multiple generators, 
> each running on its own CPU.)
> 


thank you again for everyones help.

this is one of the reasons why I am a firm believer in newsgroups...a 
person has a question, and they can find an answer.

here is the working code.. just in case anyone is/was curious:
===============================
-- This program is to open file 'Map2', then print a
-- bunch of characters 'x' in the form of a square.
-- It will also randomly grab a number from 1 - 4.


with TEXT_IO, ADA.NUMERICS.DISCRETE_RANDOM;
use TEXT_IO;
procedure Mazecreate is
    spot: CHARACTER:='x';
    spott: CHARACTER:='T';
    sitt: Boolean:=True;
    orig: INTEGER:=5;  -- point of origin for map
    down: Integer:=10;  -- down map
    acros: INTEGER:=11; -- across map
    row: INTEGER:=1;
    col: INTEGER:=1;
    X: INTEGER;
    map_file:FILE_TYPE;

    package Number_IO is new INTEGER_IO(INTEGER);
    use Number_IO;
    package FLOAT1_IO is new FLOAT_IO(FLOAT);
    use FLOAT1_IO;
   subtype Options is INTEGER range 1 .. 4;
    package Generate_Options is new
          Ada.Numerics.Discrete_Random(Options);
    use Generate_Options;
    A_Generator : Generate_Options.Generator;
 

Begin
 

Reset (A_Generator);
    X:=Generate_Options.Random(A_Generator);
   Put_Line("Selected option is" & Options'image(X));
    Create (map_file, out_FILE, "Map2");
 

    -- *********************
    -- **   section to    **
    -- **   create the    **
    -- ** square of Stars **
    -- *********************
 

    if IS_OPEN(map_file) then
       for i in 1..down loop
          for j in 1..acros loop
          put (map_file, spot);
          end loop;
        NEW_LINE(map_file);
       end loop;
       Put(map_file, spott);
       CLOSE (map_file);
 

   else
      Put_Line("Map file didn't open .. Killing Program");
      Return;
   end if;
 

end Mazecreate;
==========================




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

* Random number generation
@ 2010-07-13 12:45 tonyg
  2010-07-13 12:50 ` Jacob Sparre Andersen
                   ` (3 more replies)
  0 siblings, 4 replies; 57+ messages in thread
From: tonyg @ 2010-07-13 12:45 UTC (permalink / raw)


I want to generate a random integer and a random floating point number
between 10 and 30 . I've been looking at previous posts and finding it
a little confusing with many packages, has anyone an already done
example in ada 2005 they can post up?



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

* Re: Random number generation
  2010-07-13 12:45 tonyg
@ 2010-07-13 12:50 ` Jacob Sparre Andersen
  2010-07-13 12:58 ` Dmitry A. Kazakov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 57+ messages in thread
From: Jacob Sparre Andersen @ 2010-07-13 12:50 UTC (permalink / raw)


tonyg <tonythegair@googlemail.com> writes:

> I want to generate a random integer and a random floating point number
> between 10 and 30 . I've been looking at previous posts and finding it
> a little confusing with many packages, has anyone an already done
> example in ada 2005 they can post up?

There is an example in section A.5.2 in the reference manual.

Jacob
-- 
There only exist 10 kinds of people: Those who know binary
numbers and those who don't know binary numbers.



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

* Re: Random number generation
  2010-07-13 12:45 tonyg
  2010-07-13 12:50 ` Jacob Sparre Andersen
@ 2010-07-13 12:58 ` Dmitry A. Kazakov
  2010-07-13 13:17 ` Thomas Løcke
  2010-07-13 16:07 ` Jeffrey R. Carter
  3 siblings, 0 replies; 57+ messages in thread
From: Dmitry A. Kazakov @ 2010-07-13 12:58 UTC (permalink / raw)


On Tue, 13 Jul 2010 05:45:47 -0700 (PDT), tonyg wrote:

> I want to generate a random integer and a random floating point number
> between 10 and 30 . I've been looking at previous posts and finding it
> a little confusing with many packages, has anyone an already done
> example in ada 2005 they can post up?

An example of Gaussian distribution:

   http://rosettacode.org/wiki/Random_numbers#Ada

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Random number generation
  2010-07-13 12:45 tonyg
  2010-07-13 12:50 ` Jacob Sparre Andersen
  2010-07-13 12:58 ` Dmitry A. Kazakov
@ 2010-07-13 13:17 ` Thomas Løcke
  2010-07-13 16:07 ` Jeffrey R. Carter
  3 siblings, 0 replies; 57+ messages in thread
From: Thomas Løcke @ 2010-07-13 13:17 UTC (permalink / raw)


On 2010-07-13 14:45, tonyg wrote:
> I want to generate a random integer and a random floating point number
> between 10 and 30 . I've been looking at previous posts and finding it
> a little confusing with many packages, has anyone an already done
> example in ada 2005 they can post up?


Hey tonyq,

I wrote this little tutorial a while ago:

http://wiki.ada-dk.org/index.php/The_Dice_Roller_Program

As the name suggests, the tutorial centers around a program that rolls 
dice, and as such it needs to generate some random numbers. The part the 
does the random stuff can be found here:

http://wiki.ada-dk.org/index.php/The_Dice_Roller_Program#dice-random.ads_and_dice-random.adb

It's not a very complicated routine, so you should be able to tweak it 
to match your needs.  :o)

-- 
Regards,
Thomas L�cke

Email: tl at ada-dk.org
Web: http:ada-dk.org
IRC nick: ThomasLocke



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

* Re: Random number generation
  2010-07-13 12:45 tonyg
                   ` (2 preceding siblings ...)
  2010-07-13 13:17 ` Thomas Løcke
@ 2010-07-13 16:07 ` Jeffrey R. Carter
  2010-07-13 20:33   ` John B. Matthews
  3 siblings, 1 reply; 57+ messages in thread
From: Jeffrey R. Carter @ 2010-07-13 16:07 UTC (permalink / raw)


On 07/13/2010 05:45 AM, tonyg wrote:
> I want to generate a random integer and a random floating point number
> between 10 and 30 . I've been looking at previous posts and finding it
> a little confusing with many packages, has anyone an already done
> example in ada 2005 they can post up?

The random integer is pretty easy to do with an appropriate [sub]type and 
Ada.Numerics.Discrete_Random. The random floating-point is a bit more difficult, 
and there's always the question of whether 30.0 must be a possible value. You 
can have a look at Random_Range in PragmARC.Universal_Random:

http://pragmada.x10hosting.com/pragmarc.htm

which excludes the maximum value from the returned values.

-- 
Jeff Carter
"When Roman engineers built a bridge, they had to stand under it
while the first legion marched across. If programmers today
worked under similar ground rules, they might well find
themselves getting much more interested in Ada!"
Robert Dewar
62



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

* Re: Random number generation
  2010-07-13 16:07 ` Jeffrey R. Carter
@ 2010-07-13 20:33   ` John B. Matthews
  2010-07-13 23:02     ` Jeffrey R. Carter
  0 siblings, 1 reply; 57+ messages in thread
From: John B. Matthews @ 2010-07-13 20:33 UTC (permalink / raw)


In article <i1i3cc$8ro$1@tornado.tornevall.net>,
 "Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org> wrote:

> On 07/13/2010 05:45 AM, tonyg wrote:
> > I want to generate a random integer and a random floating point 
> > number between 10 and 30 . I've been looking at previous posts and 
> > finding it a little confusing with many packages, has anyone an 
> > already done example in ada 2005 they can post up?

Here's an Ada 95 example that uses Ada.Numerics.Discrete_Random to 
simulate repeated plays of a simple card game:

<http://home.roadrunner.com/~jbmatthews/war.html>

The shuffling algorithm needs work; this might be an alternative:

<http://en.wikipedia.org/wiki/Fisher–Yates_shuffle>

> The random integer is pretty easy to do with an appropriate [sub]type 
> and Ada.Numerics.Discrete_Random. The random floating-point is a bit 
> more difficult, and there's always the question of whether 30.0 must 
> be a possible value. You can have a look at Random_Range in 
> PragmARC.Universal_Random:
> 
> http://pragmada.x10hosting.com/pragmarc.htm

As an aside, Mine Detector V6.0 builds on Mac OS X 10.5.8 with GtkAda 
2.14.1 and GNAT 4.3.4. Wait, I took a picture:

<http://i26.tinypic.com/23qyxxi.png>

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>



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

* Re: Random number generation
  2010-07-13 20:33   ` John B. Matthews
@ 2010-07-13 23:02     ` Jeffrey R. Carter
  2010-07-14  4:42       ` John B. Matthews
  0 siblings, 1 reply; 57+ messages in thread
From: Jeffrey R. Carter @ 2010-07-13 23:02 UTC (permalink / raw)


On 07/13/2010 01:33 PM, John B. Matthews wrote:
>
> The shuffling algorithm needs work; this might be an alternative:
>
> <http://en.wikipedia.org/wiki/Fisher–Yates_shuffle>

The problem with this (for Ada) is the need to instantiate Discrete_Random for a 
different range each time (although you could use 
PragmARC.Universal_Random.Random_Int). If it's for a game with a human, then the 
biased version of using the full range each time is good enough

> As an aside, Mine Detector V6.0 builds on Mac OS X 10.5.8 with GtkAda
> 2.14.1 and GNAT 4.3.4. Wait, I took a picture:
>
> <http://i26.tinypic.com/23qyxxi.png>

Cool. I wouldn't check any boxes with only 100 mines.

-- 
Jeff Carter
"When Roman engineers built a bridge, they had to stand under it
while the first legion marched across. If programmers today
worked under similar ground rules, they might well find
themselves getting much more interested in Ada!"
Robert Dewar
62



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

* Re: Random number generation
  2010-07-13 23:02     ` Jeffrey R. Carter
@ 2010-07-14  4:42       ` John B. Matthews
  2010-07-15 19:01         ` tonyg
  0 siblings, 1 reply; 57+ messages in thread
From: John B. Matthews @ 2010-07-14  4:42 UTC (permalink / raw)


In article <i1irmb$vfe$1@tornado.tornevall.net>,
 "Jeffrey R. Carter" <spam.jrcarter.not@spam.acm.org> wrote:

> On 07/13/2010 01:33 PM, John B. Matthews wrote:
> >
> > The shuffling algorithm needs work; this might be an alternative:
> >
> > <http://en.wikipedia.org/wiki/Fisher–Yates_shuffle>
> 
> The problem with this (for Ada) is the need to instantiate 
> Discrete_Random for a different range each time (although you could 
> use PragmARC.Universal_Random.Random_Int).

Thank you for suggesting this; I see the problem, now. Section 
A.5.2(50), Note 16, mentions the very problem, suggesting Float_Random 
as an alternative:

<http://www.adaic.com/standards/05rm/html/RM-A-5-2.html>

I also found this implementation using Discrete_Random:

<http://rosettacode.org/wiki/Knuth_shuffle#Ada>

> If it's for a game with a human, then the biased version of using the 
> full range each time is good enough.

No, it's a simulation; I don't get off that easy.
 
> > As an aside, Mine Detector V6.0 builds on Mac OS X 10.5.8 with GtkAda
> > 2.14.1 and GNAT 4.3.4. Wait, I took a picture:
> >
> > <http://i26.tinypic.com/23qyxxi.png>
> 
> Cool. I wouldn't check any boxes with only 100 mines.

They were smiling for the camera! :-)

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>



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

* Re: Random number generation
  2010-07-14  4:42       ` John B. Matthews
@ 2010-07-15 19:01         ` tonyg
  0 siblings, 0 replies; 57+ messages in thread
From: tonyg @ 2010-07-15 19:01 UTC (permalink / raw)


On 14 July, 05:42, "John B. Matthews" <nos...@nospam.invalid> wrote:
> In article <i1irmb$vf...@tornado.tornevall.net>,
>  "Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org> wrote:
>
> > On 07/13/2010 01:33 PM, John B. Matthews wrote:
>
> > > The shuffling algorithm needs work; this might be an alternative:
>
> > > <http://en.wikipedia.org/wiki/Fisher–Yates_shuffle>
>
> > The problem with this (for Ada) is the need to instantiate
> > Discrete_Random for a different range each time (although you could
> > use PragmARC.Universal_Random.Random_Int).
>
> Thank you for suggesting this; I see the problem, now. Section
> A.5.2(50), Note 16, mentions the very problem, suggesting Float_Random
> as an alternative:
>
> <http://www.adaic.com/standards/05rm/html/RM-A-5-2.html>
>
> I also found this implementation using Discrete_Random:
>
> <http://rosettacode.org/wiki/Knuth_shuffle#Ada>
>
> > If it's for a game with a human, then the biased version of using the
> > full range each time is good enough.
>
> No, it's a simulation; I don't get off that easy.
>
> > > As an aside, Mine Detector V6.0 builds on Mac OS X 10.5.8 with GtkAda
> > > 2.14.1 and GNAT 4.3.4. Wait, I took a picture:
>
> > > <http://i26.tinypic.com/23qyxxi.png>
>
> > Cool. I wouldn't check any boxes with only 100 mines.
>
> They were smiling for the camera! :-)
>
> --
> John B. Matthews
> trashgod at gmail dot com
> <http://sites.google.com/site/drjohnbmatthews>

Thanks for the help guys



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

* Random number generation
@ 2010-12-30 10:43 Mart van de Wege
  2010-12-30 10:54 ` Thomas Løcke
                   ` (4 more replies)
  0 siblings, 5 replies; 57+ messages in thread
From: Mart van de Wege @ 2010-12-30 10:43 UTC (permalink / raw)


Beginner's question: I'm trying to implement a function that rolls a
number of dice and then adds a modifier. Somehow, it produces the same
number every time. I can't see where I'm going wrong.

Here's the proof of concept code:

with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;

procedure Rolltest is
   function Roll ( Number : in Positive;
		   Size : in Positive;
		   Modifier : in Integer := 0 ) return Integer is 
      subtype Die_Size is Positive range 2..Size;
      package Die is new Ada.Numerics.Discrete_Random( Die_Size );
      G : Die.Generator;
      Result : Integer;
      Temp : Integer;
   begin
      Die.Reset(G);
      Result := 0;
      for I in 1..Number loop
	 Temp := Die.Random(G);
	 Result := Result + Temp;
      end loop;
      Result := Result + Modifier;
      return Result;
   end Roll;
begin
   for I in 1..10 loop
      Put(Roll( Number => 3, Size => 6 ));
   end loop;
end Rolltest;

Anyone care to at least point me to some documentation that explains
what I'm doing wrong? 

Mart

-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Random number generation
  2010-12-30 10:43 Random number generation Mart van de Wege
@ 2010-12-30 10:54 ` Thomas Løcke
  2010-12-30 12:11   ` Mart van de Wege
  2010-12-30 11:34 ` Niklas Holsti
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 57+ messages in thread
From: Thomas Løcke @ 2010-12-30 10:54 UTC (permalink / raw)


On 2010-12-30 11:43, Mart van de Wege wrote:
> Anyone care to at least point me to some documentation that explains
> what I'm doing wrong?


Hey Mart,

We have a dice-roller article at the Ada-DK wiki:

     http://wiki.ada-dk.org/index.php/The_Dice_Roller_Program

If you don't care about the article, you can just grab the code here:

     https://github.com/ThomasLocke/The-Dice-Roller

Also there's a Rosetta Code example:

     http://rosettacode.org/wiki/Random_numbers#Ada

-- 
Regards,
Thomas L�cke

Email: tl at ada-dk.org
Web: http:ada-dk.org
IRC nick: ThomasLocke



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

* Re: Random number generation
  2010-12-30 10:43 Random number generation Mart van de Wege
  2010-12-30 10:54 ` Thomas Løcke
@ 2010-12-30 11:34 ` Niklas Holsti
  2010-12-30 11:53   ` Georg Bauhaus
  2010-12-30 11:51 ` Brian Drummond
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 57+ messages in thread
From: Niklas Holsti @ 2010-12-30 11:34 UTC (permalink / raw)


Mart van de Wege wrote:
> Beginner's question: I'm trying to implement a function that rolls a
> number of dice and then adds a modifier. Somehow, it produces the same
> number every time. I can't see where I'm going wrong.
> 
> Here's the proof of concept code:
> 
> with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO;
> use Ada.Integer_Text_IO;
> 
> procedure Rolltest is
>    function Roll ( Number : in Positive;
> 		   Size : in Positive;
> 		   Modifier : in Integer := 0 ) return Integer is 
>       subtype Die_Size is Positive range 2..Size;
>       package Die is new Ada.Numerics.Discrete_Random( Die_Size );
>       G : Die.Generator;
>       Result : Integer;
>       Temp : Integer;
>    begin
>       Die.Reset(G);

This Reset operation is specified (in RM A.5.2(34)) to set the state of 
the generator G to a "time-dependent" state.

If every call of Roll is returning the same results, perhaps the calls 
happen so rapidly that whatever discrete "time" source Reset uses is the 
same on each call, thus setting G to the same state on each call.

Ordinarily I would suggest to call Reset just once, and then let the 
state of the generator evolve without Resets over all calls of Roll, but 
this cannot be done here because G is a local variable in Roll, and it 
must be so since the generic actual parameter depends on the Size 
parameter of Roll.

Perhaps you should make another random Integer number generator IntGen, 
local to Rolltest but not to Roll, and use the generated Integer numbers 
to initialize Roll.G by a Reset call that has the random Integer as the 
second, state-determining "Initiator" parameter. The IntGen generator 
should be Reset in Rolltest, not in Roll, or left in its default initial 
state.

If you leave a random-number generator with its default initial state 
(no Reset call), you get the same random-number sequence on every execution.

If you use the single-parameter Reset (G) procedure, you get a sequence 
that is different for different executions, providing that the Resets 
are far enough apart in time to make a difference.

>       Result := 0;
>       for I in 1..Number loop
> 	 Temp := Die.Random(G);
> 	 Result := Result + Temp;
>       end loop;
>       Result := Result + Modifier;
>       return Result;
>    end Roll;
> begin
>    for I in 1..10 loop
>       Put(Roll( Number => 3, Size => 6 ));
>    end loop;
> end Rolltest;
> 
> Anyone care to at least point me to some documentation that explains
> what I'm doing wrong? 
> 
> Mart
> 


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Random number generation
  2010-12-30 10:43 Random number generation Mart van de Wege
  2010-12-30 10:54 ` Thomas Løcke
  2010-12-30 11:34 ` Niklas Holsti
@ 2010-12-30 11:51 ` Brian Drummond
  2010-12-30 12:16   ` Mart van de Wege
  2010-12-30 13:04 ` Dmitry A. Kazakov
  2010-12-31  3:14 ` Gene
  4 siblings, 1 reply; 57+ messages in thread
From: Brian Drummond @ 2010-12-30 11:51 UTC (permalink / raw)


On Thu, 30 Dec 2010 11:43:40 +0100, Mart van de Wege <mvdwege@mail.com> wrote:

>Beginner's question: I'm trying to implement a function that rolls a
>number of dice and then adds a modifier. Somehow, it produces the same
>number every time. I can't see where I'm going wrong.
>
>Here's the proof of concept code:
>
>with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO;
>use Ada.Integer_Text_IO;
>
>procedure Rolltest is
>   function Roll ( Number : in Positive;
...
>      package Die is new Ada.Numerics.Discrete_Random( Die_Size );
...
>   begin
>      Die.Reset(G);
...
>   end Roll;
>begin
>   for I in 1..10 loop
>      Put(Roll( Number => 3, Size => 6 ));
>   end loop;
>end Rolltest;
>
>Anyone care to at least point me to some documentation that explains
>what I'm doing wrong? 

Check the documentation for  Ada.Numerics.Discrete_Random or at least its
specification ( .ads file) but I think you'll find you need to reset the Die
exactly once, rather than every call of the Roll function.

As I understand, you are resetting the seed each time, so you get the same
results!

The shortest way to resolve this is to make Die a global variable and reset it
at the start of the main program - in the context of a one-page beginner's
program it's a reasonable thing to do.

We're all taught "Global Variables are BAD" with good reason, so - once you have
resolved the immediate problem - it might be a good time to learn a bit about
packages, to hide the Die and expose only what you need to operate on it.

Essentially, within the package, Die can safely become a "global" variable, but
invisible and inaccessible outside the package, so that it appears more like a
static variable in a C function (holds the current random seed value between
calls).

- Brian



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

* Re: Random number generation
  2010-12-30 11:34 ` Niklas Holsti
@ 2010-12-30 11:53   ` Georg Bauhaus
  2010-12-30 12:25     ` Mart van de Wege
  0 siblings, 1 reply; 57+ messages in thread
From: Georg Bauhaus @ 2010-12-30 11:53 UTC (permalink / raw)


On 30.12.10 12:34, Niklas Holsti wrote:

> If every call of Roll is returning the same results, perhaps the calls happen
> so rapidly that whatever discrete "time" source Reset uses is the same on each
> call, thus setting G to the same state on each call.

If I place a delay before each call of Roll, I get more
different values, confirming this time/speed dependence
of resetting the generator.

> Ordinarily I would suggest to call Reset just once, and then let the state of
> the generator evolve without Resets over all calls of Roll, but this cannot be
> done here because G is a local variable in Roll, and it must be so since the
> generic actual parameter depends on the Size parameter of Roll.

OTOH, the Size parameter is fixed at 6, so subtype Die_Size and
the generator could be placed outside Roll.  Anyway, another
nest will give suitable life times to the objects involved.




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

* Re: Random number generation
  2010-12-30 10:54 ` Thomas Løcke
@ 2010-12-30 12:11   ` Mart van de Wege
  0 siblings, 0 replies; 57+ messages in thread
From: Mart van de Wege @ 2010-12-30 12:11 UTC (permalink / raw)


Thomas Løcke <tl@ada-dk.org> writes:

> On 2010-12-30 11:43, Mart van de Wege wrote:
>> Anyone care to at least point me to some documentation that explains
>> what I'm doing wrong?
>
>
> Hey Mart,
>
> We have a dice-roller article at the Ada-DK wiki:
>
>     http://wiki.ada-dk.org/index.php/The_Dice_Roller_Program
>

Hmm.

If I look at dice-random.adb, it looks like the same algorithm I'm
using.

And yet if I run my test program, I get multiple same values. A
different value at each run, to be sure, so it looks like I'm doing
something wrong so that the generator only gives me one value.

> If you don't care about the article, you can just grab the code here:
>
>     https://github.com/ThomasLocke/The-Dice-Roller
>
> Also there's a Rosetta Code example:
>
>     http://rosettacode.org/wiki/Random_numbers#Ada

I had seen that one before, but it's using Float_Random. Not that I am
opposed to doing it using Float_Random, but I was just trying to get my
head around Discrete_Random, and I thought I had understood it.

Mart

-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Random number generation
  2010-12-30 11:51 ` Brian Drummond
@ 2010-12-30 12:16   ` Mart van de Wege
  0 siblings, 0 replies; 57+ messages in thread
From: Mart van de Wege @ 2010-12-30 12:16 UTC (permalink / raw)


Brian Drummond <brian_drummond@btconnect.com> writes:

> On Thu, 30 Dec 2010 11:43:40 +0100, Mart van de Wege <mvdwege@mail.com> wrote:
>
<snip>

> Check the documentation for  Ada.Numerics.Discrete_Random or at least its
> specification ( .ads file) but I think you'll find you need to reset the Die
> exactly once, rather than every call of the Roll function.
>
> As I understand, you are resetting the seed each time, so you get the same
> results!
>
> The shortest way to resolve this is to make Die a global variable and reset it
> at the start of the main program - in the context of a one-page beginner's
> program it's a reasonable thing to do.
>
> We're all taught "Global Variables are BAD" with good reason, so - once you have
> resolved the immediate problem - it might be a good time to learn a bit about
> packages, to hide the Die and expose only what you need to operate on it.
>
Heh.

This function *was* living in a package. I abstracted it out into a
test program to isolate it and make it short enough to copy/paste here.

But thanks. The problem is with my re-initialising the generator every time,
and like others pointed out, the code is running fast enough that the
generator gets the same seed every time; that is, if I understand
everything correctly now.

Mart
-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Random number generation
  2010-12-30 11:53   ` Georg Bauhaus
@ 2010-12-30 12:25     ` Mart van de Wege
  2010-12-30 15:29       ` Georg Bauhaus
  0 siblings, 1 reply; 57+ messages in thread
From: Mart van de Wege @ 2010-12-30 12:25 UTC (permalink / raw)


Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
>
> OTOH, the Size parameter is fixed at 6, so subtype Die_Size and
> the generator could be placed outside Roll.  Anyway, another
> nest will give suitable life times to the objects involved.
>
How does that work?

Because if I move out the declaration of the Die_Size subtype out of the
function, I cannot instantiate Discrete_Random with a run-time dependent
range, right? 

And I'd need to instantiate Discrete_Random outside the function,
because otherwise I can't call Generator, or can I?

Mart

-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Random number generation
  2010-12-30 10:43 Random number generation Mart van de Wege
                   ` (2 preceding siblings ...)
  2010-12-30 11:51 ` Brian Drummond
@ 2010-12-30 13:04 ` Dmitry A. Kazakov
  2010-12-30 13:22   ` Niklas Holsti
  2010-12-30 13:30   ` Mart van de Wege
  2010-12-31  3:14 ` Gene
  4 siblings, 2 replies; 57+ messages in thread
From: Dmitry A. Kazakov @ 2010-12-30 13:04 UTC (permalink / raw)


On Thu, 30 Dec 2010 11:43:40 +0100, Mart van de Wege wrote:

> Anyone care to at least point me to some documentation that explains
> what I'm doing wrong? 

Random generator is a stateful object, thus it cannot be local.

I suggest this is what you want:
--------------------------------------------------------------------------
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

with Ada.Numerics.Discrete_Random;

procedure Rolltest is
   package Uniform is new Ada.Numerics.Discrete_Random (Natural);
   use Uniform;

   function Roll
            (  Dice     : Generator;
               Number   : in Positive;
		   Size     : in Positive;
		   Modifier : in Integer := 0
            )  return Integer is 
      Result : Integer := 0;
   begin
      for I in 1..Number loop
	   Result := Result + Random (Dice) mod Size;
      end loop;
      Result := Result + Modifier + Number;
      return Result;
   end Roll;

   Dice : Generator;
begin
   Reset (Dice);
   for I in 1..10 loop
      Put (Roll (Dice => Dice, Number => 3, Size => 6));
   end loop;
end Rolltest;
-------------------------------------------------------------------------
I added Number to the accumulated result because you did so in your example
by choosing the range 2..Size.

BTW, a sum of n realizations of a uniformly distributed random number is
distributed uniformly with the factor n. So you need not to run a cycle
within Roll:

   function Roll
            (  Dice     : Generator;
               Number   : in Positive;
		   Size     : in Positive;
		   Modifier : in Integer := 0
            )  return Integer is 
   begin
      return Number * ((Random (Dice) mod Size) + 1) + Modifier;
   end Roll;
 
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Random number generation
  2010-12-30 13:04 ` Dmitry A. Kazakov
@ 2010-12-30 13:22   ` Niklas Holsti
  2010-12-30 13:39     ` Dmitry A. Kazakov
  2010-12-30 13:30   ` Mart van de Wege
  1 sibling, 1 reply; 57+ messages in thread
From: Niklas Holsti @ 2010-12-30 13:22 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> BTW, a sum of n realizations of a uniformly distributed random number is
> distributed uniformly with the factor n. So you need not to run a cycle
> within Roll:
> 
>    function Roll
>             (  Dice     : Generator;
>                Number   : in Positive;
> 		   Size     : in Positive;
> 		   Modifier : in Integer := 0
>             )  return Integer is 
>    begin
>       return Number * ((Random (Dice) mod Size) + 1) + Modifier;
>    end Roll;

I don't think that gives uniformly distributed numbers, since it only 
produces results that are some multiple of Number, plus the Modifier. 
The OP's implementation gives a more uniform result.

The multiplication formula might work for floating-point values, 
depending on how fine-scaled uniformity is needed.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Random number generation
  2010-12-30 13:04 ` Dmitry A. Kazakov
  2010-12-30 13:22   ` Niklas Holsti
@ 2010-12-30 13:30   ` Mart van de Wege
  1 sibling, 0 replies; 57+ messages in thread
From: Mart van de Wege @ 2010-12-30 13:30 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

>
> BTW, a sum of n realizations of a uniformly distributed random number is
> distributed uniformly with the factor n. So you need not to run a cycle
> within Roll:
>
>    function Roll
>             (  Dice     : Generator;
>                Number   : in Positive;
> 		   Size     : in Positive;
> 		   Modifier : in Integer := 0
>             )  return Integer is 
>    begin
>       return Number * ((Random (Dice) mod Size) + 1) + Modifier;
>    end Roll;

This accomplishes not quite what I want. The idea is to add multiple
random results together, which will result in a standard distribution.

I don't think simply multiplying one random result gives the same
distribution.

Mart

-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Random number generation
  2010-12-30 13:22   ` Niklas Holsti
@ 2010-12-30 13:39     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 57+ messages in thread
From: Dmitry A. Kazakov @ 2010-12-30 13:39 UTC (permalink / raw)


On Thu, 30 Dec 2010 15:22:00 +0200, Niklas Holsti wrote:

> I don't think that gives uniformly distributed numbers, since it only 
> produces results that are some multiple of Number, plus the Modifier.

Yes, you are right, I forgot that the range is bound.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Random number generation
  2010-12-30 12:25     ` Mart van de Wege
@ 2010-12-30 15:29       ` Georg Bauhaus
  2010-12-30 15:37         ` Mart van de Wege
  0 siblings, 1 reply; 57+ messages in thread
From: Georg Bauhaus @ 2010-12-30 15:29 UTC (permalink / raw)


On 30.12.10 13:25, Mart van de Wege wrote:
> Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
>>
>> OTOH, the Size parameter is fixed at 6, so subtype Die_Size and
>> the generator could be placed outside Roll.  Anyway, another
>> nest will give suitable life times to the objects involved.
>>
> How does that work?

Using another level of nesting to control life time
and parameterization:

procedure Rolltest is

    procedure Setup_And_Roll (Size: Positive) is

        subtype Die_Size is Positive range 2..Size;
        package Die is new Ada.Numerics.Discrete_Random( Die_Size );
        G : Die.Generator;

        function Roll ( Number : in Positive;
                        Modifier : in Integer := 0 ) return Integer is
            Result : Integer;
            Temp : Integer;
        begin
            Result := 0;
            for I in 1..Number loop
                Temp := Die.Random(G);
                Result := Result + Temp;
            end loop;
            Result := Result + Modifier;
            return Result;
        end Roll;

    begin
        Die.Reset(G);
        for I in 1..10 loop
            Put(Roll( Number => 3 ));
        end loop;
    end Setup_And_Roll;

begin
    Setup_And_Roll (Size => 6);
end Rolltest;




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

* Re: Random number generation
  2010-12-30 15:29       ` Georg Bauhaus
@ 2010-12-30 15:37         ` Mart van de Wege
  0 siblings, 0 replies; 57+ messages in thread
From: Mart van de Wege @ 2010-12-30 15:37 UTC (permalink / raw)


Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:

> On 30.12.10 13:25, Mart van de Wege wrote:
>> Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
>>>
>>> OTOH, the Size parameter is fixed at 6, so subtype Die_Size and
>>> the generator could be placed outside Roll.  Anyway, another
>>> nest will give suitable life times to the objects involved.
>>>
>> How does that work?
>
> Using another level of nesting to control life time
> and parameterization:

<snip good example>

Yeah, after some time pondering on it, I was going for a similar
solution; I was thinking of doing it the traditional OO way, using a
constructor method to return a Dice_Pool object with the Generator intialized,
and a Roll method to generate a result. 

Hadn't thought of the exact way to implement this, but it would not have
looked a lot different from your example.

Thanks,

Mart

-- 
"We will need a longer wall when the revolution comes."
    --- AJS, quoting an uncertain source.



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

* Re: Random number generation
  2010-12-30 10:43 Random number generation Mart van de Wege
                   ` (3 preceding siblings ...)
  2010-12-30 13:04 ` Dmitry A. Kazakov
@ 2010-12-31  3:14 ` Gene
  4 siblings, 0 replies; 57+ messages in thread
From: Gene @ 2010-12-31  3:14 UTC (permalink / raw)


I've been bitten by this before.  As others have said, Reset, as imlemented in GNAT, initializes the Generator using the system time to derive a seed value.  When I last looked at the GNAT library sources for Windows, it used 1-second resolution for this purpose.  So if you called it twice in the same clock second, you'd get the same results from Random afterward. 

This version of Reset is clearly meant to be called only once per Generator per program run to establish the streams.



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

end of thread, other threads:[~2010-12-31  3:14 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-30 10:43 Random number generation Mart van de Wege
2010-12-30 10:54 ` Thomas Løcke
2010-12-30 12:11   ` Mart van de Wege
2010-12-30 11:34 ` Niklas Holsti
2010-12-30 11:53   ` Georg Bauhaus
2010-12-30 12:25     ` Mart van de Wege
2010-12-30 15:29       ` Georg Bauhaus
2010-12-30 15:37         ` Mart van de Wege
2010-12-30 11:51 ` Brian Drummond
2010-12-30 12:16   ` Mart van de Wege
2010-12-30 13:04 ` Dmitry A. Kazakov
2010-12-30 13:22   ` Niklas Holsti
2010-12-30 13:39     ` Dmitry A. Kazakov
2010-12-30 13:30   ` Mart van de Wege
2010-12-31  3:14 ` Gene
  -- strict thread matches above, loose matches on Subject: below --
2010-07-13 12:45 tonyg
2010-07-13 12:50 ` Jacob Sparre Andersen
2010-07-13 12:58 ` Dmitry A. Kazakov
2010-07-13 13:17 ` Thomas Løcke
2010-07-13 16:07 ` Jeffrey R. Carter
2010-07-13 20:33   ` John B. Matthews
2010-07-13 23:02     ` Jeffrey R. Carter
2010-07-14  4:42       ` John B. Matthews
2010-07-15 19:01         ` tonyg
2003-09-26  7:14 random " christoph.grein
2003-09-26  7:00 Andrew
2003-09-26  7:35 ` tmoran
2003-09-26 17:58   ` Andrew
2003-09-26 19:25   ` Andrew
2003-09-26 19:35     ` chris
2003-09-26 21:44     ` tmoran
2003-09-27  1:40     ` Robert I. Eachus
2003-09-27  4:48       ` Andrew
1997-12-19  0:00 Mok-kong Shen
1998-01-02  0:00 ` Mok-kong Shen
1998-01-02  0:00   ` Robert Dewar
1996-10-13  0:00 Random Number Generation parker
1996-10-13  0:00 ` Robert Dewar
1996-10-14  0:00 ` Robert A Duff
1996-10-10  0:00  Dr J Parker
1996-10-12  0:00 ` Keith Thompson
1996-10-12  0:00 ` Geert Bosch
1996-10-10  0:00  Dr J Parker
1996-10-02  0:00  Dr J Parker
1996-10-03  0:00 ` Mats Weber
1996-10-07  0:00 ` Geert Bosch
1996-09-23  0:00 Nigel J. Tracey
1996-09-23  0:00 ` Tucker Taft
1996-10-02  0:00   ` Nigel J. Tracey
1996-10-02  0:00   ` Robert I. Eachus
1996-10-03  0:00   ` Nigel J. Tracey
1996-09-25  0:00 ` James_Rogers
1996-09-26  0:00   ` Dale Stanbrough
1996-10-01  0:00   ` Robert I. Eachus
1996-09-30  0:00 `  Dr J Parker
1996-10-01  0:00   ` Tucker Taft
1996-10-01  0:00     ` Keith Thompson

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