For some reason this got lost in the ether, so I'm resending.

Related to my earlier question on passing a function -- I was wondering if there's a trivial way of generating a lazily-evaluated range of random numbers according to a given distribution and parameters.

I wrote up the code below to generate a range of uniformly-distributed
numbers, but am not sure how to generalize it for arbitrary distribution and/or
parameters, and I'm also not sure that I'm overcomplicating what might be more
easily achieved with existing D functionality.

The larger goal here is that I want some way to pass an _arbitrary_ number source (may be deterministic, may be stochastic) to a function. A range seemed a good way to do that (after all, in the deterministic case I can just pass an array, no?).

... but I couldn't work out how to generalize the stochastic case beyond what's shown here.

///////////////////////////////////////////////////////////////////////////////
import std.array, std.random, std.range, std.stdio;

struct UniformRange(T1, T2)
{
        T1 _lower;
        T2 _upper;
        
        @property enum bool empty = false;
        
        this(T1 a, T2 b)
        {
                _lower = a;
                _upper = b;
        }

        @property auto ref front()
        {
                assert(!empty);
                return uniform(_lower, _upper);
        }

        void popFront()
        {
        }
}

auto uniformRange(T1, T2)(T1 a, T2 b)
{
        return UniformRange!(T1, T2)(a, b);
}

auto uniformRange(T1, T2)(size_t n, T1 a, T2 b)
{
        return take(UniformRange!(T1, T2)(a, b), n);
}

void main()
{
        auto ur = uniformRange!(double, double)(5, 10.0, 20.0);
        double[] x = array( take(uniformRange(1.0, 2.0), 5) );
        double[] y = array(x);
        
        foreach(r; ur)
                writeln(r);
        writeln;

        foreach(r; ur)
                writeln(r);
        writeln;

        foreach(r; x)
                writeln(r);
        writeln;

        foreach(r; y)
                writeln(r);
        writeln;
}

Reply via email to