Making mir.random.ndvariable.multivariateNormalVar create bigger data sets than 2

Nathan S. no.public.email at example.com
Tue Feb 27 21:54:34 UTC 2018


Cross-posting from the github issue 
(https://github.com/libmir/mir-random/issues/77) with a 
workaround (execute it at https://run.dlang.io/is/Swr1xU):
----

I am not sure what the correct interface should be for this in 
the long run, but for now you can use a wrapper function to 
convert an ndvariable to a variable:

```d
/++
Converts an N-dimensional variable to a fixed-dimensional 
variable.
+/
auto specifyDimension(ReturnType, NDVariable)(NDVariable vr)
     if (__traits(isStaticArray, ReturnType) && __traits(compiles, 
{static assert(NDVariable.isRandomVariable);}))
{
     import mir.random : isSaturatedRandomEngine;
     import mir.random.variable : isRandomVariable;
     static struct V
     {
         enum bool isRandomVariable = true;
         NDVariable vr;
         ReturnType opCall(G)(scope ref G gen) if 
(isSaturatedRandomEngine!G)
         {
             ReturnType ret;
             vr(gen, ret[]);
             return ret;
         }

         ReturnType opCall(G)(scope G* gen) if 
(isSaturatedRandomEngine!G)
         {
             return opCall!(G)(*gen);
         }
     }
     static assert(isRandomVariable!V);
     V v = { vr };
     return v;
}
```

So `main` from your above example becomes:

```d
void main()
{
     import std.stdio;
     import mir.random : Random, threadLocalPtr;
     import mir.random.ndvariable : multivariateNormalVar;
     import mir.random.algorithm : range;
     import mir.ndslice.slice : sliced;
     import std.range : take;

     auto mu = [10.0, 0.0].sliced;
     auto sigma = [2.0, -1.5, -1.5, 2.0].sliced(2,2);

     Random* rng = threadLocalPtr!Random;
     auto sample = rng
                 .range(multivariateNormalVar(mu, 
sigma).specifyDimension!(double[2]))
                 .take(10);
     writeln(sample);
}
```


More information about the Digitalmars-d-learn mailing list