1 module rmathd.uniform;
2 
3 public import rmathd.common;
4 
5 /*
6 ** dmd uniform.d common.d && ./uniform
7 ** dmd uniform.d common.d && ./uniform && rm uniform
8 */
9 
10 T dunif(T: double)(T x, T a, T b, int give_log)
11 {
12     if (isNaN(x) || isNaN(a) || isNaN(b))
13 	    return x + a + b;
14 
15     if (b <= a)
16     	return T.nan;
17 
18     if (a <= x && x <= b)
19 	    return give_log ? -log(b - a) : 1. / (b - a);
20 	mixin R_D__0!log_p;
21     return R_D__0;
22 }
23 
24 T punif(T: double)(T x, T a, T b, int lower_tail, int log_p)
25 {
26     if (isNaN(x) || isNaN(a) || isNaN(b))
27 	    return x + a + b;
28     if (b < a)
29     	return T.nan;
30     if (!isFinite(a) || !isFinite(b))
31     	return T.nan;
32 
33     if (x >= b)
34 	    return R_DT_1!T(lower_tail, log_p);
35     if (x <= a)
36 	    return R_DT_0!T(lower_tail, log_p);
37     if (lower_tail)
38     	return R_D_val!T((x - a) / (b - a), log_p);
39     else
40     	return R_D_val!T((b - x) / (b - a), log_p);
41 }
42 
43 T qunif(T: double)(T p, T a, T b, int lower_tail, int log_p)
44 {
45     if (isNaN(p) || isNaN(a) || isNaN(b))
46 	    return p + a + b;
47 
48     mixin (R_Q_P01_check!(p)());
49     if (!isFinite(a) || !isFinite(b))
50     	return T.nan;
51     if (b < a)
52     	return T.nan;
53     if (b == a)
54     	return a;
55 
56     mixin R_DT_qIv!(p);
57     return a + R_DT_qIv * (b - a);
58 }
59 
60 T runif(T: double)(T a, T b)
61 {
62     if (!isFinite(a) || !isFinite(b) || b < a)
63     	return T.nan;
64     if (a == b)
65 	    return a;
66     else {
67 	    T u;
68 	    do {
69 	    	u = unif_rand!T();
70 	    } while (u <= 0 || u >= 1);
71 	    return a + (b - a) * u;
72     }
73 }
74 
75 
76 void demo_uniform()
77 {
78 	import std.stdio : writeln;
79 	writeln(unif_rand!double());
80 	writeln(unif_rand!double());
81 	writeln("punif: ", punif(0.5, 0., 1., 0, 0));
82 	writeln("qunif: ", qunif(0.5, 0., 1., 0, 0));
83 	writeln("runif: ", runif(0., 1.), ", ", runif(0., 1.), ", ", runif(0., 1.), ", ", runif(0., 1.));
84 }