September 01, 2013
Joseph Rushton Wakeling:

>     auto uniDist = uniformDistribution(0.0, 1.0);
>     auto biasedDice = diceDistribution(10, 5, 7);
>     foreach(u, d; lockstep(uniDist, biasedDice).take(10))
>     {
>         writeln(u);
>         writeln(d);
>     }
>
> (I'm sure you can find something to improve in how I've written the second example, but you get the idea of how the distributions could behave:-)

Perhaps it's better for it to only accept a range (despite this causes a memory allocation):

diceDistribution([10, 5, 7])

It's usable like this:

[0.3, 0.5, 0.1, 0.1].diceDistribution.map!(i => "ACGT"[i]).take(10).writeln;

diceDistribution() is much more efficient than calling dice() many times in map.

In the enhancement request I have also suggested to support an optional list of items, so the code becomes:

[0.3, 0.5, 0.1, 0.1].diceDistribution("ACGT").take(10).writeln;

The name "diceDistribution" is rather long, but at the moment I don't know of better names. "diceDist" is shorter, but less clear.

I usually don't have a continuous distribution to sample (beside the most common ones, like the gaussian), so for me a diceDistribution is enough for now.

Bye,
bearophile
September 02, 2013
On 02/09/13 00:54, bearophile wrote:
> diceDistribution() is much more efficient than calling dice() many times in map.

Surely, but you should have both available in any case.  I think there's a good argument that for all random number distributions, there should be a function _and_ a range implementation, so depending on your needs do either:

    auto dist = someDistribution(/* ... parameters ... */, rng);
    foreach (x; dist.take(10))
    {
        writeln(x);
    }

... or:

    foreach(_; 0 .. 10)
    {
        auto x = some(/* ... parameters ... */, rng);
        writeln(x);
    }

Of course in practice sometimes the range might just wrap the function, or the function might contain within a static instance of the range.
1 2
Next ›   Last »