This patch fixes the problem that partialShuffle was in fact invariably
shuffling the whole of the input, undetected because there were unittests
only for randomShuffle.
As well as the fix I've added some unittests specifically for partialShuffle
to ensure that it works properly, and I've taken the opportunity to tweak a
couple of bits of Ddoc and tidy up the randomShuffle unittests.
A special case was checked that only occurs when calling uniform with a range of only one element. This was not necessary to keep the math correct and represented a slight slowdown in the common case for no apparent benefit.
These changes retain the uniform quality of this function while, in the
common case, cutting the number of division operations in half.
Additionally, extra unittests were added to assure that all of the
bounds were tested properly.
This patch fixes a problem where the public methods .index()
or .popFront() might be called without the first value of the
sample having been determined, which would then cause spurious
results. The runtime initialization check currently performed
in .front has been extended to those methods.
The private boolean checks in the previous implementation have
been replaced with an enum indicating the algorithm to be used
(A, D or None) with None indicating that the sample has not
been initialized.
Step D1 of Algorithm D has been moved to the skip() function,
which results in a significant performance boost.
Unittests have been introduced to cover the cases where .index
or .popFront() are called before .front.
Finally, the .index method has been made a @property, which I
take to be an oversight of the original code.
RandomCover and RandomSample should only be save'able if:
* the input is a forward range
* the thread-global RNG rndGen is not being used
* the RNG being used is a forward range.
In line with changes to RandomCover, this patch tweaks
the choice of template parameter and variable names in
order to bring clarity and uniformity to the module.
The existing RandomCover design is fatally flawed because it
requires a RNG as input, which it then copies internally by
value. So, unless the user is smart enough to pass something
like e.g. SomeRNG(unpredictableSeed), there will be unintended
correlations in random behaviour.
This partial fix follows the design of RandomSample in allowing
RandomCover to use the thread-global default RNG rndGen. It
also improves the choice of template parameter and variable
names in line with Issue 10434.
The original typo derives directly from George Marsaglia's paper
introducing the Xorshift RNGs. The original checking values, derived
from that code, thus also reflect the typo.
A corrected version of the reference code is available from
https://github.com/WebDrake/xorshift/ and has been used to
generate the updated checking values.
The original typo derives directly from George Marsaglia's paper
introducing the Xorshift RNGs. The original checking values, derived
from that code, thus also reflect the typo.
A corrected version of the reference code is available from
https://github.com/WebDrake/xorshift/ and has been used to
generate the updated checking values.
don't work with Xorshift.
This is an instance of Issue 2803, a clash between a template
parameter and a default argument. I've used the workaround
proposed in that issue thread:
http://d.puremagic.com/issues/show_bug.cgi?id=2803#c1
Tests have been included to ensure that these functions work
with all possible RNG types.
Unittests for LinearCongruentialEngine were previously missing the
constructor and the .save and .opEquals() methods.
Code coverage analysis still fails to pick up on the static methods
and the contents of a static if scope in lines 374-382 of .popFront().
The old unittests were missing coverage of large sections of
RandomSample.skip() because the ratios of sample size to source size
were such that Algorithm A was always being chosen over Algorithm D.
The new unittests fix this and also extend coverage to a number of
other areas previously not addressed. There are also currently-failing
tests commented out with version(none) that can be used to verify
future bugfixes and improvements.
A few lines in skip() remain uncovered simply because they depend on
runtime conditions that are extremely rare.
This small tweak has been accompanied by a couple of extra checks
to ensure that users do not request more sample points than are
available in the input, which could otherwise be the source of
exceptions.
There exists one remaining case where RandomSample may fail: if it
is given an InputRange without the .length property, and the user
indicates that the total number of items available is greater
than what the InputRange actually contains. In this case an
exception is thrown from std.array.popFront() line 450,
"Attempting to popFront() past the end of an array", or from
std.array.front() line 624, "Attempting to fetch the front of an
empty array."