sample usage:
auto r=new Random();
int i; float f; real rv; real[100] ar0; real[] ar=ar0[];
// initialize with uniform distribution
i=r.uniform!(int);
f=r.uniform!(float);
rv=r.uniform!(real);
foreach (ref el;ar)
el=r.uniform!(real);
// another way to do all the previous in one go:
r(i)(f)(rv)(ar);
// unfortunetely one cannot use directly ar0...
// uniform distribution 0..10
i=r.uniformR(10);
f=r.uniformR(10.0f);
rv=r.uniformR(10.0L);
foreach (ref el;ar)
el=r.uniformR(10.0L);
// another way to do all the previous in one go:
r.uniformRD(10)(i)(f)(r)(ar);
// uniform numbers in [5;10)
i=r.uniformR2(5,10);
// uniform numbers in (5;10)
f=r.uniformR2(5.0f,10.0f);
rv=r.uniformR2(5.0L,10.0L);
foreach (ref el;ar)
el=r.uniformR2(5.0L,10.0L);
// another way to do all the previous in one go:
r.uniformR2D(5.0L,10.0L)(i)(f)(r)(ar);
// uniform distribution -10..10
i=r.uniformRSymm(10);
// well you get it...
r.uniformRSymmD(10)(i)(f)(r)(ar);
// any distribution can be stored
auto r2=r.uniformRSymmD(10);
// and used later
r2(ar);
// complex distributions (normal,exp,gamma) are produced for the requested type
r.normalSource!(float)()(f);
// with sigma=2
r.normalD(2.0f)(f);
// and can be used also to initialize other types
r.normalSource!(float)()(r)(ar);
r.normalD(2.0f)(r)(ar);
// but this is different from
r.normalSource!(real)()(i)(r)(ar);
r.normalD(2.0L)(i)(r)(ar);
// as the source generates numbers of its type that then are simply cast to
// the type needed.
// Uniform distribution (as its creation for different types has no overhead)
// is never cast, so that (for example) bounds exclusion for floats is really
// guaranteed.
// For the other distribution using a distribution of different type than
// the variable should be done with care, as underflow/overflow might ensue.
//
// Some utility functions are also available
int i2=r.uniform!(int)();
int i2=r.randomize(i); // both i and i2 are initialized to the same value
float f2=r.normalSigma(3.0f);
)
)