March 22, 2014
Latest patches rename randomSample => sample, again offering a documented alias to assist migration.

It would be nice to complete the set and eliminate randomCover, but in this case "cover" seems too vague a name to use.  Any suggestions for alternatives?  I wasn't able to readily find an equivalent in other random number libraries.

"permutation" seems good to me (or "permute"?), but perhaps others have suggestions or can point to a typical naming practice from other languages?
March 22, 2014
Joseph Rushton Wakeling:

> Latest patches rename randomSample => sample, again offering a documented alias to assist migration.

Perhaps it's better to not document this alias.


> "permutation" seems good to me (or "permute"?), but perhaps others have suggestions or can point to a typical naming practice from other languages?

I'd like a permutations() range in std.range or std.combinatorics.  permutation() sounds a bit too much close, despite it is inside another module.

Bye,
bearophile
March 22, 2014
On Saturday, 22 March 2014 at 20:09:00 UTC, bearophile wrote:
> Perhaps it's better to not document this alias.

For now it will be documented, for clarity if nothing else.  Whether that documentation makes it into a Phobos submission, I think should depend on formal review.

> I'd like a permutations() range in std.range or std.combinatorics.  permutation() sounds a bit too much close, despite it is inside another module.

How does your desired concept relate to the existing std.algorithm.nextPermutation ... ?
March 22, 2014
Joseph Rushton Wakeling:

> How does your desired concept relate to the existing std.algorithm.nextPermutation ... ?

The API of the lazy permutations/combinations ranges is similar to the one I have written here:
http://rosettacode.org/wiki/Permutations#Fast_Lazy_Version

That is also very similar to the permutations/combinations here (with the "r" optional argument):
http://docs.python.org/2/library/itertools.html


To the one in Phobos is used like:

auto items = [1, 2, 3];
do
    writeln(items);
while (items.nextPermutation());


The permutations/combinations range is used like (the boolean template argument is to specify if it has to copy the buffer or not):

[1, 2, 3].permutations!false.writeln;

Bye,
bearophile
March 22, 2014
Latest patches just pushed to repo make the randomSample => sample change and introduce a fast uniform01 and uniform01Distribution :-)
March 22, 2014
Joseph Rushton Wakeling:

> Latest patches just pushed to repo make the randomSample => sample change and introduce a fast uniform01 and uniform01Distribution :-)

They seem good.

More ideas:

"Three suggestions for std.random":
https://d.puremagic.com/issues/show_bug.cgi?id=4851

"Strongly pure random generator":
https://d.puremagic.com/issues/show_bug.cgi?id=5249

I hope a gaussian (normal distribution) generator is planned or present.

Bye,
bearophile
March 23, 2014
On Saturday, 22 March 2014 at 23:56:35 UTC, bearophile wrote:
> They seem good.

Excellent!

There may need to be some attention to the internals of uniform01.  Its correctness depends on whether one can always trust a float-based RNG to return values in [min, max) or whether [min, max] is also going to be supplied by some.

> More ideas:
>
> "Three suggestions for std.random":
> https://d.puremagic.com/issues/show_bug.cgi?id=4851

I think all std.random functions now support a default RNG.  There were some bugs related to that (e.g. the "can't use Xorshift" one) that I fixed last year.

The problem you identify with,

    int r = randomCover(data, rndGen).front;

always returning the same value, is down to the fact that rndGen is being copied inside the RandomCover struct by value, so of course the original rndGen is never updated and each of these calls will produce the same result.  The new std.random2 fixes that, because the RNGs are reference types.

However, I'd have thought that

    int r = data.sample(1, rndGen).front;

would have been a more efficient way to implement "choice", as it can operate on any input range, as long as it has the .length property; and it ought to be _much_ faster than even a single call to randomCover.

One could always use this as a default option, with a specialization where data is a RandomAccessRange to use the more efficient

    int r = data[uniform!"[)"(0, data.length)];

> "Strongly pure random generator":
> https://d.puremagic.com/issues/show_bug.cgi?id=5249

.front and .popFront at least are pure for _all_ the RNGs currently implemented in std.random2.generator.  See e.g.:
https://github.com/WebDrake/std.random2/blob/master/std/random2/generator.d#L266-L272
https://github.com/WebDrake/std.random2/blob/master/std/random2/generator.d#L506-L517
https://github.com/WebDrake/std.random2/blob/master/std/random2/generator.d#L821-L834

Of course this is not strongly pure in line with your request, but it should enable use of these RNGs in many other scenarios where purity is important.

> I hope a gaussian (normal distribution) generator is planned or present.

https://github.com/WebDrake/std.random2/blob/master/std/random2/distribution.d#L326

This is a range implementation; there will also be a function implementation, which will probably follow the inefficient Box-Muller variant that uses 2 uniform random variates to generate a single normal variate (as per the example you posted in your feature request).
March 23, 2014
Joseph Rushton Wakeling:

> I think all std.random functions now support a default RNG.

Is the issue is already fixed in std.random you can close it :-)


> However, I'd have thought that
>
>     int r = data.sample(1, rndGen).front;
>
> would have been a more efficient way to implement "choice", as it can operate on any input range, as long as it has the .length property; and it ought to be _much_ faster than even a single call to randomCover.
>
> One could always use this as a default option, with a specialization where data is a RandomAccessRange to use the more efficient
>
>     int r = data[uniform!"[)"(0, data.length)];

The best thing is to add an efficient choice() function, so no efficiency mistake happens :-)


>> "Strongly pure random generator":
>> https://d.puremagic.com/issues/show_bug.cgi?id=5249
>
> .front and .popFront at least are pure for _all_ the RNGs currently implemented in std.random2.generator.  See e.g.:
> https://github.com/WebDrake/std.random2/blob/master/std/random2/generator.d#L266-L272
> https://github.com/WebDrake/std.random2/blob/master/std/random2/generator.d#L506-L517
> https://github.com/WebDrake/std.random2/blob/master/std/random2/generator.d#L821-L834
>
> Of course this is not strongly pure in line with your request, but it should enable use of these RNGs in many other scenarios where purity is important.

So you are saying that those RNGs are already weakly pure and they can't become strongly pure because they take the engine as mutable class reference. And even if you design a very small random engine that can be created every time you call a random generator, the API of all the random functions is not compatible with it. So it's not a simple problem...


> This is a range implementation; there will also be a function implementation, which will probably follow the inefficient Box-Muller variant that uses 2 uniform random variates to generate a single normal variate (as per the example you posted in your feature request).

A possibility is to also add a less precise (more approximate) but faster function implementation.


Are the ddocs produced by std.random2 online somewhere?

Bye,
bearophile
March 23, 2014
> Joseph Rushton Wakeling:
>>    int r = data[uniform!"[)"(0, data.length)];

D also accepts:

immutable r = data[uniform!"[)"(0, $)];

Bye,
bearophile
March 23, 2014
On Sun, Mar 23, 2014 at 11:17 AM, bearophile <bearophileHUGS@lycos.com> wrote:
>> Joseph Rushton Wakeling:
>>
>>>    int r = data[uniform!"[)"(0, data.length)];
>
>
> D also accepts:
>
> immutable r = data[uniform!"[)"(0, $)];

Really? The '$' part works?