November 23, 2016
On Wednesday, 23 November 2016 at 16:01:14 UTC, Ryan wrote:
> On Wednesday, 23 November 2016 at 15:44:10 UTC, Joseph Rushton Wakeling wrote:
>>
>> auto m = (&r).map!(a=>1);
>>
>> ...?  (Untested, but I think it should work.)
>
> Tested, works with 2.071.1

r.randomRangeAdaptor.map!(a=>1);
November 23, 2016
On Wednesday, 23 November 2016 at 14:30:53 UTC, Andrei Alexandrescu wrote:
> That seems to be a minor matter. Of course at best some measurements would be in order.
>> Yes, it's just Joseph worries about microoptimizations.

Though we saw that the compiler can't optimize some simple operations like division by 2.
November 23, 2016
On 11/23/2016 10:52 AM, Ilya Yaroshenko wrote:
> I started with Engines as basis. The library will be very different
> comparing with Phobos and _any_ other RNG libraries in terms of floating
> point generation quality. All FP generation I have seen are not
> saturated (amount of possible unique FP values are very small comparing
> with ideal situation because of IEEE arithmetic). I have not found the
> idea described by others, so it may be an article in the future.

Is this a design matter, or an implementation matter? Could you implement the superior FP generation on the existing std.random API? To not be able to vs. to not want to is a different matter; I have an appreciation for each, but we need to clarify. -- Andrei
November 23, 2016
On Wednesday, 23 November 2016 at 01:28:11 UTC, Andrei Alexandrescu wrote:
> Interesting. Could you please add a couple of links about that? -- Andrei

http://xoroshiro.di.unimi.it/
November 23, 2016
On Wednesday, 23 November 2016 at 16:54:44 UTC, Andrei Alexandrescu wrote:
> On 11/23/2016 10:52 AM, Ilya Yaroshenko wrote:
>> I started with Engines as basis. The library will be very different
>> comparing with Phobos and _any_ other RNG libraries in terms of floating
>> point generation quality. All FP generation I have seen are not
>> saturated (amount of possible unique FP values are very small comparing
>> with ideal situation because of IEEE arithmetic). I have not found the
>> idea described by others, so it may be an article in the future.
>
> Is this a design matter, or an implementation matter? Could you implement the superior FP generation on the existing std.random API? To not be able to vs. to not want to is a different matter; I have an appreciation for each, but we need to clarify. -- Andrei

Floating point generation are implementation matter. Distributions and algorithms are design matter.

Assume your are building a modification Mod_X ~ 1 / X + X for a distribution. This is how it will look in Mir Random:

-------------------------

struct Mod(D)
  if(isRandomVariable!D && isFloatingPoint!(ReturnType!D))
{
    D irv;
    alias irv this;
    ReturnType!D opCall(G)(ref G gen)
        if(isSURBG!D)
    {
        ReturnType!D x1 = void;
        do x1 = irv(gen);
        while(x1 == 0);
        ReturnType!D x2 = irv(gen);
        /////////////////////////////////////////////////////////////////////////
        /////////////////   X1 and X2 are independent! ///////////////
        ////////////////////////////////////////////////////////////////////////
        return 1 / x1 + x2;
    }
}

unittest
{
    auto gen = Xorshift(1);
    auto rv = Mod!GammaRandomVariable(...);
    auto x = rv(gen); /// generator is never copied by value.
}

-------------------------

How it can be done with Range interface instead of opCall?
Please note that users would use Distributions, not Engines.

So, Range API requirements are:

1. Engine must not have implicit copy semantic: it is not correct for RNGs and has performance issues. They also should not be copied explicitly in this example.

2. Do not use Engine's pointers in RandomVariable, because RandomVariables can be passed easily outside of function: they are just a small tuples of params.

3. Do not use classes because of BetterC and performance issues.

4. Engines must have Range interface

5. RandomVariables (both Mod and an underlaying) must have Range interface.

I don't think Range API for random variables can be done easily and without performance or security issues.

Thanks,
Ilya
November 23, 2016
On Wednesday, 23 November 2016 at 18:13:52 UTC, Ilya Yaroshenko wrote:
>
> Assume your are building a modification Mod_X ~ 1 / X + X for a distribution. This is how it will look in Mir Random:

EDIT: Mod_X ~ Y + X, Y ~ X. (X & Y are independent)
November 23, 2016
On 11/23/2016 01:13 PM, Ilya Yaroshenko wrote:
> 1. Engine must not have implicit copy semantic: it is not correct for
> RNGs and has performance issues. They also should not be copied
> explicitly in this example.

OK, so (lack of) copyability is a good argument. I'm ready to live with random generators that are noncopyable values and use opCall; then use a range adaptor on top of a pointer to that. It seems providing the range primitives for a noncopyable object is not useful and is liable to create more confusion and frustration than a distinct API.

A tip for the range adaptor: have it allocate and own the generator internally. That way it's easy to make it reference counted economically.


Andrei
November 23, 2016
On Wednesday, 23 November 2016 at 19:16:29 UTC, Andrei Alexandrescu wrote:
>
> A tip for the range adaptor: have it allocate and own the generator internally. That way it's easy to make it reference counted economically.

Current adaptor should be used in a function scope. (Would be great to have a DIP for that kind of semantic check). An RC adaptor can be added too. First we need to find a real world use case where we need to store a random range outside of a function. -- Ilya
November 23, 2016
On 11/23/16 2:40 PM, Ilya Yaroshenko wrote:
> On Wednesday, 23 November 2016 at 19:16:29 UTC, Andrei Alexandrescu wrote:
>>
>> A tip for the range adaptor: have it allocate and own the generator
>> internally. That way it's easy to make it reference counted economically.
>
> Current adaptor should be used in a function scope. (Would be great to
> have a DIP for that kind of semantic check). An RC adaptor can be added
> too. First we need to find a real world use case where we need to store
> a random range outside of a function. -- Ilya

Yah, problem here is we can't make that @safe. -- Andrei
November 23, 2016
On Wednesday, 23 November 2016 at 19:51:50 UTC, Andrei Alexandrescu wrote:
> On 11/23/16 2:40 PM, Ilya Yaroshenko wrote:
>> On Wednesday, 23 November 2016 at 19:16:29 UTC, Andrei Alexandrescu wrote:
>>>
>>> A tip for the range adaptor: have it allocate and own the generator
>>> internally. That way it's easy to make it reference counted economically.
>>
>> Current adaptor should be used in a function scope. (Would be great to
>> have a DIP for that kind of semantic check). An RC adaptor can be added
>> too. First we need to find a real world use case where we need to store
>> a random range outside of a function. -- Ilya
>
> Yah, problem here is we can't make that @safe. -- Andrei

Can we improve D to make it safe?