Mir Random and Dlang Ranges [Example]
Joseph Rushton Wakeling via Digitalmars-d
digitalmars-d at puremagic.com
Fri Nov 25 07:09:46 PST 2016
On Friday, 25 November 2016 at 14:27:13 UTC, Ilya Yaroshenko
wrote:
> The discussion [2] about Mir Random [1] and Range API become a
> holy war [2]. I am putting the following example here. It also
> can be found at GitHub[1].
It's not a holy war, but your code example doesn't really address
the key issues to do with the interaction of random number
generation and ranges, which are not really much about how you
create a reference-type range for RNGs themselves. (Your
solution is one of several.)
What would convince me of the merits of your approach is an
implementation of `RandomSample` (as in, the range that extracts
a subset of n elements out of the first N elements of an input
range, with equal probability of selecting any particular
element) that deals with the following challenges:
* its own internal state (or at least, those parts of it that
correspond to state underlying the pseudo-random process, which
is NOT limited to the RNG state) is not at risk of being copied
by value;
* it's possible to generate multiple `RandomSample` instances
deep in the inner loop of a program, without creating slow-down
related to memory allocation (this was the reason I abandoned a
class-based approach);
* it's easy to fit the `RandomSample` implementation into a range
chain.
The last point doesn't have to be quite as simple as the sort of
thing you can do currently, such as:
iota(100).randomSample(10, rng).filter!(a => a > 50).writeln;
Ideally it would be possible to create a function that creates
that kind of range chain and returns it, as in:
auto myMagicRange(RNG)(size_t n, size_t m, ref RNG rng)
{
assert(n < m);
return iota(m).randomSample(n, rng).filter!(a => a > n/2);
}
// Now output 10,000 unique filtered samples ...
foreach (_; 0 .. 10_000)
{
myMagicRange(10, 100, rng).writeln;
}
More information about the Digitalmars-d
mailing list