On 06/18/2013 03:38 PM, H. S. Teoh wrote:
> W.r.t. (P)RNGs, the places where .save is used are where random ranges
> wouldn't really make sense anyway -- if I *really* wanted to search a
> range for a random needle, I'd make an array out of prng.take(n) first,
> and then pass that to find(); it'd be more efficient, if nothing else.
> And I can't think of any useful application of taking a cartesian
> product of a random range.

I'll have a look through these things and see if there are any ways in which
they might reasonably offer a way to come unstuck statistics-wise.

I've attached a little example.  Here we call:

    auto gen = new MtClass19937(unpredictableSeed);
    auto r = simpleRandomRange(0.0L, 1.0L, gen);
    auto t1 = r.take(5);
    auto s = r.save;
    auto t2 = s.take(5);
    writeln(t1);
    writeln(t2);

    auto t3 = r.take(5);
    auto t4 = s.take(5);
    writeln(t3);
    writeln(t4);

Note that the first pair and last pair produce the same output, but the
successive takes from r (t1 and t3) are different from each other, as are the
successive takes from the save s (t2 and t4).  This is what you'd expect, but an
algorithm might assume that repeatedly consuming r.save would result in the same
output again and again and again.
import std.array, std.range, std.random, std.stdio, std.traits;
import mtclass;

struct SimpleRandomRange(RNG = void)
    if(isUniformRNG!RNG || is(RNG == void))
{
    private real _min, _max, _u;
    static if(!is(RNG == void))
    {
        private RNG _gen;

        this(real min, real max, RNG gen)
        {
            _min = min;
            _max = max;
            _gen = gen;
            _u = uniform(_min, _max, _gen);
        }

        typeof(this) save() @property
        {
            auto ret = typeof(this)(this);
            ret._gen = this._gen.save;
            return ret;
        }
    }
    else
    {
        this(real min, real max)
        {
            _min = min;
            _max = max;
            _u = uniform(_min, _max);
        }
    }

    this(typeof(this) source)
    {
        _min = source._min;
        _max = source._max;
        _u = source._u;
        static if (!is(RNG == void))
            _gen = source._gen;
    }

    immutable bool empty = false;

    real front() @property pure nothrow const
    {
        return _u;
    }

    void popFront()
    {
        static if(is(RNG == void))
            _u = uniform(_min, _max);
        else
            _u = uniform(_min, _max, _gen);
    }
}

auto simpleRandomRange()(real min, real max)
{
    return SimpleRandomRange!void(min, max);
}

auto simpleRandomRange(RNG)(real min, real max, RNG gen)
    if(isUniformRNG!RNG)
{
    return SimpleRandomRange!RNG(min, max, gen);
}


void main()
{
    auto gen = new MtClass19937(unpredictableSeed);
    auto r = simpleRandomRange(0.0L, 1.0L, gen);
    auto t1 = r.take(5);
    auto s = r.save;
    auto t2 = s.take(5);
    writeln(t1);
    writeln(t2);

    auto t3 = r.take(5);
    auto t4 = s.take(5);
    writeln(t3);
    writeln(t4);
}

Reply via email to