<html>
<head>
  <title>Comments about Issues with Random Number Generators (N1535)</title>
  <meta Author="Jens Maurer" content="proposal">
</head>

<body bgcolor="#FFFFFF" text="#000000">

<font size=-1>
Jens Maurer &lt;Jens.Maurer@gmx.net&gt;
<br>
2003-10-30
<br>
Document N1544=03-0127
<p>
<code>$Id: issues.html,v 1.11 2003/10/30 21:28:42 jmaurer Exp $</code>
</font>

<h1>Comments about Issues with Random Number Generators</h1>

Numeric issue numbers refer to N1535, Jxx issue numbers are new issues
described in this paper.

<h2>Minor typo fixes</h2>

<h3>Issue 21: linear_congruential::linear_congruential(In&, In)
  -- Garbled Requires Clause</h3>

Subsumed by proposed resolution for issue 19 (see below).


<h3>Issue J1: More garbled pieces</h3>

There are some places where the TR draft contains garbled characters.
This issue points out the places where editorial changes to rectify
this need to be performed.

<ul>
<li>5.1.4.3 [tr.rand.eng.sub], first paragraph
<li>5.1.4.4 [tr.rand.eng.sub1], first paragraph
<li>5.1.4.5 [tr.rand.eng.disc], after the class definition
<li>5.1.4.5 [tr.rand.eng.disc], effects clause of operator()
</ul>


<h3>Issue J2: class vs. type</h3>

<b>Proposed resolution:</b>
<p>
Replace in section 5.1.1 [tr.rand.req], last paragraph

<blockquote>
In the following subclauses, a template parameter named
UniformRandomNumberGenerator shall denote a <strike>class</strike>
<b>type</b> that satisfies all the requirements of a uniform random
number generator.
</blockquote>

[This aligns the wording with the subsequent sentences in the same
paragraph.]


<h3>Issue J3: Fix section reference</h3>

<b>Proposed resolution:</b>
<p>
Replace in section 5.1.4 [tr.rand.eng], second paragraph
<blockquote>
The class templates specified in this section satisfy all the
requirements of a pseudo-random number engine (given in tables in
section <strike>x.x</strike> <b>5.1.1 [tr.rand.req]</b>), except where
specified otherwise. Descriptions are provided here only for
operations on the engines that are not described in one of these
tables or for operations where there is additional semantic
information.
</blockquote>

<h3>Issue J4: Avoid confusion for "ell" and "one"</h3>

[See issue 19 for another issue that touches these words.]
<p>

<b>Proposed resolution:</b>
<p>
Replace in 5.4.1.2 [tr.rand.eng.mers]
<blockquote>
Effects: With a linear congruential generator l(i) having parameters
m<sub>l</sub> = 2<sup>32</sup>, a<sub>l</sub> = 69069, c<sub>l</sub> = 0, and
l(0) = value, sets x(-n) ... x(-1) to l(1) ... l(n), respectively.
</blockquote>

by

<blockquote>
Effects: With a linear congruential generator lcg(i) having parameters
m<sub>lcg</sub> = 2<sup>32</sup>, a<sub>lcg</sub> = 69069, c<sub>lcg</sub> = 0,
and lcg(0) = value, sets x(-n) ... x(-1) to lcg(1) ... lcg(n),
respectively.
</blockquote>

Replace in 5.4.1.3 [tr.rand.eng.sub]

<blockquote>
<strong>Effects:</strong> With a linear congruential generator l(i)
having parameters m<sub>l</sub> = 2147483563, a<sub>l</sub> = 40014,
c<sub>l</sub> = 0, and l(0) = <code>value</code>, sets x(-r) ... x(-1)
to l(1) mod m ... l(r) mod m, respectively.  If x(-1) == 0, sets
carry(-1) = 1, else sets carry(-1) = 0.
</blockquote>

by

<blockquote>
<strong>Effects:</strong> With a linear congruential generator lcg(i)
having parameters m<sub>lcg</sub> = 2147483563, a<sub>lcg</sub> = 40014,
c<sub>lcg</sub> = 0, and lcg(0) = <code>value</code>, sets x(-r) ... x(-1)
to lcg(1) mod m ... lcg(r) mod m, respectively.  If x(-1) == 0, sets
carry(-1) = 1, else sets carry(-1) = 0.
</blockquote>

Replace in 5.4.1.4 [tr.rand.eng.sub1]

<blockquote>
<strong>Effects:</strong> With a linear congruential generator l(i)
having parameters m = 2147483563, a = 40014, c = 0, and l(0) =
<code>value</code>, sets x(-r) ... x(-1) to (l(1)*2<sup>-w</sup>) mod 1
... (l(r)*2<sup>-w</sup>) mod 1, respectively.  If x(-1) == 0, sets
carry(-1) = 2<sup>-w</sup>, else sets carry(-1) = 0.
<br>
</blockquote>

by

<blockquote>
<strong>Effects:</strong> With a linear congruential generator lcg(i)
having parameters m<sub>lcg</sub> = 2147483563, a<sub>lcg</sub> =
40014, c<sub>lcg</sub> = 0, and lcg(0) = <code>value</code>, sets
x(-r) ... x(-1) to (lcg(1)*2<sup>-w</sup>) mod 1
... (lcg(r)*2<sup>-w</sup>) mod 1, respectively.  If x(-1) == 0, sets
carry(-1) = 2<sup>-w</sup>, else sets carry(-1) = 0.
</blockquote>



<h3>Issue J5: xor_combine: fix typo</h3>

<b>Proposed resolution:</b>
<p>
Replace in 5.1.4.6 [tr.rand.eng.xor]
<blockquote>
The template parameters UniformRandomNumberGenerator1 and
UniformRandomNumberGenerator<strike>1</strike> <b>2</b> shall denote
classes that satisfy all the requirements of a uniform random number
generator, ...
</blockquote>

[Replace "1" by "2" once.]


<h2>Requirements Definitions</h2>

<h3>Issue 1: Confusing Text in Description of
<CODE>v.min()</CODE></h3>

<P><B>Proposed Resolution:</B></P>

<P>Change the first sentence of the description
of <CODE>v.min()</CODE> in 5.1.1 [tr.rand.req], Table 5.2
(Uniform random number generator requirements) from:</P>

<BLOCKQUOTE>Returns some <CODE>l</CODE> where <CODE>l</CODE> is less than
or equal to all values potentially returned by <CODE>operator()</CODE>.</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>Returns a value that is less than or equal to all values
potentially returned by <CODE>operator()</CODE>.</BLOCKQUOTE>


<h3>Issue 2: Confusing and Incorrect Text in Description of
<CODE>v.max()</CODE></h3>

<P><B>Proposed Resolution:</B></P>

<P>Change the first sentence of the description
of <CODE>v.max()</CODE> in 5.1.1 [tr.rand.req], Table 5.2
(Uniform random number generator requirements) from:</P>

<BLOCKQUOTE>If <CODE>std::numeric_limits&lt;T&gt;::is_integer</CODE>,
returns <CODE>l</CODE> where <CODE>l</CODE> is less than or equal to
all values potentially returned by <CODE>operator()</CODE>, otherwise,
returns <CODE>l</CODE> where <CODE>l</CODE> is strictly less than
all values potentially returned by <CODE>operator()</CODE>.</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>If <CODE>std::numeric_limits&lt;T&gt;::is_integer</CODE>,
returns a value that is greater than or equal to
all values potentially returned by <CODE>operator()</CODE>, otherwise,
returns a value that is strictly greater than
all values potentially returned by <CODE>operator()</CODE>.</BLOCKQUOTE>


<h3>Issue 3: Table &quot;Number Generator Requirements&quot;
Unnecessary</h3>

<P><B>Proposed Resolution:</B></P>

<P>Copy the description of <CODE>X::result_type</CODE> from 5.1.1
[tr.rand.req], Table 5.1 (Number generator requirements) to 5.1.1
[tr.rand.req], Table 5.2 (Uniform random number generator
requirements) and to 5.1.1 [tr.rand.req], Table 5.4 (Random
distribution requirements) and remove 5.1.1 [tr.rand.req], Table 5.1
(Number generator requirements).</P>


<h3>Issue J6: Require additional properties for Engine result_type</h3>

Currently, there are no restrictions on
<code>UniformRandomNumberGenerator::result_type</code>, although
<code>variate_generator</code> is supposed to possibly convert between
integer and floating-point types.
<p>
<b>Proposed resolution:</b>
<p>
In 5.1.1 [tr.rand.req], replace the pre/post-condition for
<code>result_type</code> (fold with resolution for issue 3):
<blockquote>
<code>std::numeric_limits&lt;T&gt;::is_specialized</code> is
<code>true</code>
</blockquote>

by

<blockquote>
<code>T</code> is an arithmetic type [basic.fundamental]
</blockquote>


<h3>Issue J12: No complexity specification for copy construction and
copy assignment</h3>

In 5.1.1 [tr.rand.req], add a new paragraph after table 5.3
(pseudo-random number generator):
<blockquote>
Additional requirements: The complexity of both copy construction and
assignment is O(size of state).
</blockquote>


<h2>General</h2>

<h3>Issue 8: Should the Template Arguments Be Restricted to Built-in Types?</h3>

Because of the difficulty of good specification and in alignment with
complex, I agree to restrict the types to built-in types, with the
option to later expand it to user-defined types.  The choice of
required special functions for the user-defined type might restrict
the choice of algorithms for the distribution.
<p>

<b>Proposed resolution:</b>
<p>
Replace in 5.1.1 [tr.rand.req], last paragraph
<blockquote>
Furthermore, a template parameter named RealType shall denote a type
that holds an approximation to a real number. This type shall meet the
requirements for a numeric type (26.1 [lib.numeric.requirements]), the
binary operators +, -, *, / shall be applicable to it, a conversion
from double shall exist, and function signatures corresponding to
those for type double in subclause 26.5 [lib.c.math] shall be
available by argument-dependent lookup (3.4.2
[basic.lookup.koenig]). [Note: The built-in floating-point types float
and double meet these requirements.]
</blockquote>

by

<blockquote>
Furthermore, the effect of instantiating a template that has a
template type parameter named <code>RealType</code> is undefined unless
that type is one of <code>float</code>, <code>double</code>, or
<code>long double</code>.
</blockquote>

Delete from 5.1.7 [tr.rand.dist]
<blockquote>
A template parameter named IntType shall denote a type that represents
an integer number. This type shall meet the requirements for a numeric
type (26.1 [lib.numeric.requirements]), the binary operators +, -, *,
/, % shall be applicable to it, and a conversion from int shall
exist. [Footnote: The built-in types int and long meet these
requirements.]
<p>
[...]
<p>
No function described in this section throws an exception, unless an
operation on values of IntType or RealType throws an exception. [Note:
Then, the effects are undefined, see [lib.numeric.requirements]. ] 
</blockquote>



Add after 5.1.1 [tr.rand.req], last paragraph

<blockquote>
The effect of instantiating a template that has a template type
parameter named <code>IntType</code> is undefined unless that type
is one of <code>short</code>, <code>int</code>, <code>long</code>, or
their unsigned variants.
<p>
The effect of instantiating a template that has a template type
parameter named <code>UIntType</code> is undefined unless that type
is one of <code>unsigned short</code>, <code>unsigned int</code>, or
<code>unsigned long</code>.
</blockquote>

<p>
[This last change also prevents questions that random number engines /
distributions have to be usable with IntType = bool and other
atrocities.]


<h2>variate_generator</h2>

<h3>Issue 4: Should a <CODE>variate_generator</CODE> Holding a
Reference Be Assignable?</h3>

<P><B>Proposed Resolution:</B></P>

<P>Change the first two sentences of the third paragraph of 5.1.3 [tr.rand.var] from:</P>

<BLOCKQUOTE>Specializations of <CODE>variate_generator</CODE> satisfy the
requirements of CopyConstructible. They also satisfy the requirements of
Assignable unless the template parameter <CODE>Engine</CODE> is of
the form <CODE>U&amp;</CODE>.</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>Specializations of <CODE>variate_generator</CODE> satisfy the
requirements of CopyConstructible and Assignable.</BLOCKQUOTE>


<h3>Issue 10: Unclear Complexity Requirements for variate_generator</h3>

<b>Proposed resolution:</b>
<p>
Replace in 5.1.3 [tr.rand.var]
<blockquote>
The complexity of all functions specified in this section is constant.
</blockquote>

by

<blockquote>
Except where specified otherwise, the complexity of all functions
specified in this section is constant.
</blockquote>

Add for <code>variate_generator(engine_type e, distribution_type
d)</code>

<blockquote>
<b>Complexity:</b> Sum of the complexities of the copy construtors of
<code>engine_type</code> and <code>distribution_type</code>.
</blockquote>

Add for <code>result_type operator()()</code>
<blockquote>
<b>Complexity:</b> Amortized constant.
</blockquote>

Add for <code>result_type operator()(T value)</code>
<blockquote>
<b>Complexity:</b> Amortized constant.
</blockquote>


<h3>Issue J7: Garbled precondition for min()</h3>

<b>Proposed resolution:</b>
<p>
In 5.1.3 [tr.rand.var], add the highlighted text for
<code>min()</code>:

<blockquote>
Precondition: distribution().min() is <b>well-formed</b>
</blockquote>



<h2>Engines</h2>

<h3>Issue J8: xor_combine: Require additional properties for base*_type::result_type</h3>

There are no restrictions on UniformRandomNumberGenerator1::result_type
and UniformRandomNumberGenerator2::result_type that would ensure that &lt;&lt; and ^ are available on them.  That's well defined for unsigned integral types.

<p>
<b>Proposed resolution:</b>
<p>
Add in 5.1.4.6 [tr.rand.eng.xor] in the paragraph after the class
definition
<blockquote>
<b>Both <code>UniformRandomNumberGenerator1::result_type</code> and 
<code>UniformRandomNumberGenerator2::result_type</code> shall denote
(possibly different) unsigned integral types.</b>  The size of the state ...
</blockquote>


<h3>Issue 12: xor_combine::result_type incorrectly specified</h2>

<b>Proposed resolution:</b>
<p>
In 5.1.4.6 [tr.rand.eng.xor] replace
<blockquote>
typedef typename base_type::result_type result_type;
</blockquote>

by

<blockquote>
typedef /* see below */ result_type;
</blockquote>

and add at the end of the paragraph below the class definition

<blockquote>
The member <code>result_type</code> is defined to that type of
<code>UniformRandomNumberGenerator1::result_type</code> and
<code>UniformRandomNumberGenerator2::result_type</code> that provides
the most storage [basic.fundamental].
</blockquote>


<h3>Issue J14: Insufficient preconditions on xor_combine</h3>

xor_combine does not have any requirements for s1 and s2 template
parameters.

<p>
<b>Proposed resolution:</b>
<p>
Add in 5.1.4.6 [tr.rand.eng.xor], paragraph after the class
definition, before "The size of the state ..."
<blockquote>
The following relation shall hold: 0 <= s1 and 0 <= s2.
</blockquote>

<h3>Issue J9: Be precise about the size of the state of
xor_combine</h3>

It is unclear what the "size of b1" and the "size of b2" mean, we
only talk about the "size of the state".

<p>
<b>Proposed resolution:</b>
<p>

Add in 5.1.4.6 [tr.rand.eng.xor] in the paragraph after the class
definition:

<blockquote>
The size of the state is the size <b>of the state</b> of b1 plus the
size <b>of the state</b> of b2.
</blockquote>


<h3>Issue 13: subtract_with_carry's IntType overspecified</h3>

<b>Proposed resolution:</b>
<p>
In 5.1.4.3 [tr.rand.eng.sub], replace
<blockquote>
The template parameter <code>IntType</code> shall denote a signed
integral type large enough to store values up to <code>m</code>-1.
</blockquote>
by
<blockquote>
The template parameter <code>IntType</code> shall denote an
integral type large enough to store values up to <code>m</code>.
</blockquote>


<h3>Issue 14: subtract_with_carry_01::seed(unsigned) Missing Constraint</h3>

Subsumed by proposed resolution to issue 19.

<h3>Issue 15: subtract_with_carry_01::seed(unsigned) Produces Bad
Values</h3>

<b>Proposed resolution:</b>
<p>
Replace in 5.1.4.4 [tr.rand.eng.sub1] [signature was changed in issue
16, "l" was changed to "lcg" in issue J4, this contains the
consolidated edits as far as overlaps are concerned]
<blockquote>
<pre>    void seed(unsigned int value = 19780503)</pre>
<strong>Effects:</strong> With a linear congruential generator l(i)
having parameters m = 2147483563, a = 40014, c = 0, and l(0) =
<code>value</code>, sets x(-r) ... x(-1) to (l(1)*2<sup>-w</sup>) mod 1
... (l(r)*2<sup>-w</sup>) mod 1, respectively.  If x(-1) == 0, sets
carry(-1) = 2<sup>-w</sup>, else sets carry(-1) = 0.
<br>
<strong>Complexity:</strong> O(r)
</blockquote>

by

<blockquote>
<pre> void seed(unsigned long value = 19780503ul)</pre>
<strong>Effects:</strong> With n=(w+31)/32 (rounded downward) and
given an iterator range <code>[first, last)</code> that refers to the
sequence of values lcg(1) ... lcg(n*r) obtained from a
linear congruential generator lcg(i) having parameters m<sub>lcg</sub>
= 2147483563, a<sub>lcg</sub> = 40014, c<sub>lcg</sub> = 0, and lcg(0)
= <code>value</code>, invoke <code>seed(first,last)</code> .
<br>
<strong>Complexity:</strong> O(r*n)
</blockquote>

<h3>Issue 16: subtract_with_carry_01::seed(unsigned) Argument Type Too
Small</h3>

All of mersenne_twister, subtract_with_carry, and
subtract_with_carry_01 need to be changed (the value supplied for the
linear congruential engine-helper for initialization has nothing to
do with the final result type of the engine), here are the
consolidated changes:
<p>
<b>Proposed resolution:</b>
<p>

In 5.1.4.2 [tr.rand.eng.mers], change the signature of a constructor
and a seed function from

<blockquote>
<pre>    explicit mersenne_twister(result_type value);
    void seed(result_type value);
</pre>
</blockquote>

to

<blockquote>
<pre>    explicit mersenne_twister(unsigned long value);
    void seed(unsigned long value);
</pre>
</blockquote>


In 5.1.4.3 [tr.rand.eng.sub], change the signature of a constructor
and a seed function from
<blockquote>
<pre>    explicit subtract_with_carry(IntType value);
    void seed(IntType value = 19780503);
</pre>
</blockquote>

to

<blockquote>
<pre>    explicit subtract_with_carry(unsigned long value);
    void seed(unsigned long value = 19780503ul);
</pre>
</blockquote>

In 5.1.4.4 [tr.rand.eng.sub1], change the signature of a constructor
and a seed function from
<blockquote>
<PRE>    subtract_with_carry_01(unsigned int value);
    void seed(unsigned int value = 19780503);</PRE>
</blockquote>

to:

<blockquote>
<PRE>    subtract_with_carry_01(unsigned long value);
    void seed(unsigned long value = 19780503ul);</PRE>
</blockquote>

<h3>Issue 17: <CODE>subtract_with_carry::seed(In&amp;, In)</CODE>
Required Sequence Length Too Long</h3>

<P><B>Proposed Resolution:</B></P>

<P>Change</P>

<BLOCKQUOTE>With <CODE>n=w/32+1</CODE> (rounded downward) and given the
values <CODE>z0 ... zn*r-1</CODE></BLOCKQUOTE>

<P>to</P>

<BLOCKQUOTE>With <CODE>n=(w+31)/32</CODE> (rounded downward) and given the
values <CODE>z0 ... zn*r-1</CODE></BLOCKQUOTE>

<P>in the description of <CODE>subtract_with_carry::seed(In& first, In
last)</CODE> in 5.1.4.3 [tr.rand.eng.sub] and in the description of
<CODE>subtract_with_carry_01::seed(In& first, In last)</CODE> in
5.1.4.4 [tr.rand.eng.sub1].</P>


<h3>Issue 18: linear_congruential -- Giving Meaning to a Modulus of 0</h3>

<b>Proposed resolution:</b>
<p>
Replace in 5.1.4.1 [tr.rand.eng.lcong], in the paragraph after the
class definition
<blockquote>
If the template parameter m is 0, the behaviour is implementation-defined.
</blockquote>

by

<blockquote>
If the template parameter m is 0, the modulus m used throughout this
section is <code>std::numeric_limits&lt;IntType&gt;::max()</code> plus
1.  [Note: The result is not representable as a value of type
<code>IntType</code>.]
</blockquote>


<h3>Issue 19: linear_congruential::seed(IntType) -- Modify Seed Value When c == 0?</h3>

<b>Proposed resolution:</b>
<p>
Replace in 5.1.4.1 [tr.rand.eng.lcong]

<blockquote>
<pre>    explicit linear_congruential(IntType x0 = 1)
</pre>

<b>Requires:</b> c > 0 || (x0 % m) > 0<br>
<b>Effects:</b> Constructs a linear_congruential engine with state x(0) := x0 mod m.

<pre>    void seed(IntType x0 = 1)
</pre>

<b>Requires:</b> c > 0 || (x0 % m) > 0<br>
<b>Effects:</b> Sets the state x(i) of the engine to x0 mod m.

<pre>    template<class In> linear_congruential(In& first, In last)
</pre>

<b>Requires:</b> c > 0 || *first > 0<br>
<b>Effects:</b> Sets the state x(i) of the engine to *first mod m.<br>
<b>Complexity:</b> Exactly one dereference of *first.
</blockquote>

by

<blockquote>
<pre>    explicit linear_congruential(IntType x0 = 1)
</pre>

<b>Effects:</b> Constructs a <code>linear_congruential</code> engine
and invokes <code>seed(x0)</code>.

<pre>    void seed(IntType x0 = 1)
</pre>

<b>Effects:</b> If <code>c</code> mod <code>m</code> = 0 and
<code>x0</code> mod <code>m</code> = 0, sets the state x(i) of the
engine to 1 mod <code>m</code>, else sets the state x(i) of the engine
to <code>x0</code> mod <code>m</code>.

<pre>    template<class In> linear_congruential(In& first, In last)
</pre>

<b>Effects:</b> If <code>c</code> mod <code>m</code> = 0 and
<code>*first</code> mod <code>m</code> = 0, sets the state x(i) of the
engine to 1 mod <code>m</code>, else sets the state x(i) of the engine
to <code>*first</code> mod <code>m</code>.<br>
<b>Complexity:</b> Exactly one dereference of <code>*first</code>.
</blockquote>


Replace in 5.1.4.2 [tr.rand.eng.mers]  [see issue J4 for the change to "lcg"]

<blockquote>
<pre>    void seed()
</pre>
Effects: Invokes seed(4357).
<pre>    void seed(result_type value)
</pre>
<b>Requires:</b> value > 0<br>
<b>Effects:</b> With a linear congruential generator l(i) having
parameters m<sub>l</sub> = 232, a<sub>l</sub> = 69069, c<sub>l</sub> =
0, and l(0) = value, sets x(-n) ... x(-1) to l(1) ... l(n),
respectively.<br>
<b>Complexity:</b> O(n)
</blockquote>

by

<blockquote>
<pre>    void seed()
</pre>
Effects: Invokes <b>seed(0)</b>.
<pre>    void seed(result_type value)
</pre>
<b>Effects:</b> <b>If <code>value</code> == 0, sets <code>value</code> to 4357.
In any case, </b>with a linear congruential generator
lcg(i) having parameters m<sub>lcg</sub> = 2<sup>32</sup>,
a<sub>lcg</sub> = 69069, c<sub>lcg</sub> = 0, and lcg(0) =
<code>value</code>, sets x(-n) ... x(-1) to lcg(1) ... lcg(n),
respectively.<br>
<b>Complexity:</b> O(n)
</blockquote>



Replace in 5.4.1.3 [tr.rand.eng.sub] [see issue J4 for the change to
"lcg"] [see issue 16 for the change to "unsigned long"]

<blockquote>
<pre>    void seed(unsigned int value = 19780503)</pre>
<strong>Requires:</strong> <code>value &gt; 0</code>
<br>
<strong>Effects:</strong> With a linear congruential generator l(i)
having parameters m<sub>l</sub> = 2147483563, a<sub>l</sub> = 40014,
c<sub>l</sub> = 0, and l(0) = <code>value</code>, sets x(-r) ... x(-1)
to l(1) mod m ... l(r) mod m, respectively.  If x(-1) == 0, sets
carry(-1) = 1, else sets carry(-1) = 0.
<br>
<strong>Complexity:</strong> O(r)
</blockquote>

by

<blockquote>
<pre> void seed(unsigned long value = 19780503ul)</pre>
<strong>Effects:</strong> <b>If <code>value</code> == 0, sets
<code>value</code> to 19780503.  In any case, </b>with a linear congruential
generator lcg(i) having parameters m<sub>lcg</sub> = 2147483563,
a<sub>lcg</sub> = 40014, c<sub>lcg</sub> = 0, and lcg(0) =
<code>value</code>, sets x(-r) ... x(-1) to lcg(1) mod m ... lcg(r)
mod m, respectively.  If x(-1) == 0, sets carry(-1) = 1, else sets
carry(-1) = 0.
<br>
<strong>Complexity:</strong> O(r)
</blockquote>

Replace in 5.4.1.4 [tr.rand.eng.sub1] [see issue J4 for the change to
"lcg"] [see issue 16 for the change to "unsigned long"]

<blockquote>
<pre> void seed(unsigned int value = 19780503)</pre>
<strong>Effects:</strong> With a linear congruential generator l(i)
having parameters m = 2147483563, a = 40014, c = 0, and l(0) =
<code>value</code>, sets x(-r) ... x(-1) to (l(1)*2<sup>-w</sup>) mod 1
... (l(r)*2<sup>-w</sup>) mod 1, respectively.  If x(-1) == 0, sets
carry(-1) = 2<sup>-w</sup>, else sets carry(-1) = 0.
<br>
<strong>Complexity:</strong> O(r)
</blockquote>

by

<blockquote>
<pre> void seed(unsigned long value = 19780503ul)</pre>
<strong>Effects:</strong> <b>If <code>value</code> == 0, sets
<code>value</code> to 19780503.  In any case, </b>with a linear congruential
generator lcg(i) having parameters m<sub>lcg</sub> = 2147483563,
a<sub>lcg</sub> = 40014, c<sub>lcg</sub> = 0, and lcg(0) =
<code>value</code>, sets x(-r) ... x(-1) to lcg(1) mod m ... lcg(r)
mod m, respectively.  If x(-1) == 0, sets
<br>
<strong>Complexity:</strong> O(r)
</blockquote>

<h3>Issue 20: <CODE>linear_congruential</CODE> -- Should the Template Arguments Be Unsigned?</h3>

<P><B>Proposed Resolution:</B></P>

<P>In clause 5.1.4.1 [tr.rand.eng.lcong] replace every occurrence of <CODE>IntType</CODE>
with <CODE>UIntType</CODE> and change the first sentence after the definition of the template
from:</P>

<BLOCKQUOTE>The template parameter <CODE>IntType</CODE> shall denote
an integral type large enough to store values up to
<CODE>(m-1)</CODE>.</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>The template parameter <CODE>UIntType</CODE> shall denote
an unsigned integral type large enough to store values up to
<CODE>(m-1)</CODE>.</BLOCKQUOTE>


<h3>J13: Insufficient preconditions on discard_block</h3>

discard_block does not have sufficient requirements on the r and p
template parameters.
<p>
<b>Proposed resolution:</b>
<p>

Replace in 5.1.4.5 [tr.rand.eng.disc]
<blockquote>
r <= q
</blockquote>

by

<blockquote>
The following relation shall hold: 0 <= r <= p.
</blockquote>




<h2>Distributions</h2>

<h3>Issue 22: bernoulli_distribution Isn't Really a Template</h3>

<p>
<b>Proposed resolution:</b>
<p>

<P>In 5.1.7.2 [tr.rand.dist.bern], 
change the section heading to "Class bernoulli_distribution",
remove <CODE>template &lt;class RealType = double&gt;</CODE>
from the declaration of <CODE>bernoulli_distribtion</CODE>, change the declaration of the
constructor from:</P>

<PRE>    explicit bernoulli_distribution(const RealType&amp; p = RealType(0.5));</PRE>

<P>to:</P>

<PRE>    explicit bernoulli_distribution(double p = 0.5);</PRE>

<P>and change the header for the subclause describing the constructor from:</P>

<PRE>    bernoulli_distribution(const RealType&amp; p = RealType(0.5))</PRE>

<P>to:</P>

<PRE>    bernoulli_distribution(double p = 0.5)</PRE>


<h3>Issue J11: uniform_real should return open interval?</h3>

uniform_real was specified with a closed interval [min, max] range,
but it should have a half-open interval [min, max) range to avoid lots
of special cases in more complex distributions.  (The boost
implementation and documentation does this since ever.)

<p>
<b>Proposed resolution:</b>
<p>
In 5.1.7.6 [tr.rand.dist.runif], replace
<blockquote>
min &lt;= x &lt;= max
</blockquote>

by

<blockquote>
min &lt;= x &lt; max
</blockquote>
[The half-open interval should be used to avoid various special cases
in derived distributions, this is (and always was) correct in the
boost documentation.]


<h3>Issue 5: Normal Distribution Incorrectly Specified</h3>

<P><B>Proposed Resolution:</B></P>

<P>Change the first paragraph of 5.1.7.8 [tr.rand.dist.norm] from:</P>

<BLOCKQUOTE>A <CODE>normal_distribution</CODE> random distribution
produces random numbers <CODE>x</CODE> distributed with probability
density function
<CODE>(1/sqrt(2*pi*sigma))e<SUP>-(x-mean)<sup>2</sup>/(2*sigma<SUP>2</SUP>)</SUP></CODE>,
where <CODE>mean</CODE> and <CODE>sigma</CODE> are the parameters of
the distribution.</BLOCKQUOTE>

<P>to:</P>

<BLOCKQUOTE>A <CODE>normal_distribution</CODE> random distribution
produces random numbers <CODE>x</CODE> distributed with probability
density function
<CODE>(1/(sqrt(2*pi)*sigma))e<SUP>-(x-mean)<sup>2</sup>/(2*sigma<SUP>2</SUP>)</SUP></CODE>,
where <CODE>mean</CODE> and <CODE>sigma</CODE> are the parameters of
the distribution.</BLOCKQUOTE>


</body>
</html>