1 module rmathd.weibull; 2 3 import rmathd.common; 4 5 /* 6 ** beta.d poisson.d toms708 normal.d gamma.d 7 ** dmd weibull.d common.d && ./weibull 8 */ 9 10 11 T dweibull(T: double)(T x, T shape, T scale, int give_log) 12 { 13 T tmp1, tmp2; 14 mixin R_D__0!give_log; 15 16 if (isNaN(x) || isNaN(shape) || isNaN(scale)) 17 return x + shape + scale; 18 19 if (shape <= 0 || scale <= 0) 20 return T.nan; 21 22 if (x < 0) return 23 R_D__0; 24 if (!isFinite(x)) 25 return R_D__0; 26 /* need to handle x == 0 separately */ 27 if(x == 0 && shape < 1) 28 return T.infinity; 29 tmp1 = pow(x / scale, shape - 1); 30 tmp2 = tmp1 * (x / scale); 31 /* These are incorrect if tmp1 == 0 */ 32 return give_log ? 33 -tmp2 + log(shape * tmp1 / scale) : 34 shape * tmp1 * exp(-tmp2) / scale; 35 } 36 37 38 T pweibull(T: double)(T x, T shape, T scale, int lower_tail, int log_p) 39 { 40 if (isNaN(x) || isNaN(shape) || isNaN(scale)) 41 return x + shape + scale; 42 43 if(shape <= 0 || scale <= 0) 44 return T.nan; 45 46 if (x <= 0) 47 return R_DT_0!T(lower_tail, log_p); 48 x = -pow(x / scale, shape); 49 return lower_tail 50 ? (log_p ? R_Log1_Exp!T(x) : -expm1(x)) 51 : R_D_exp!T(x, log_p); 52 } 53 54 55 T qweibull(T: double)(T p, T shape, T scale, int lower_tail, int log_p) 56 { 57 if (isNaN(p) || isNaN(shape) || isNaN(scale)) 58 return p + shape + scale; 59 60 if (shape <= 0 || scale <= 0) 61 return T.nan; 62 63 immutable(T) INF = T.infinity; 64 mixin (R_Q_P01_boundaries!(p, 0, INF)); 65 66 return scale * pow(-R_DT_Clog!T(p, lower_tail, log_p), 1./shape); 67 } 68 69 70 T rweibull(T: double)(T shape, T scale) 71 { 72 if (!isFinite(shape) || !isFinite(scale) || shape <= 0. || scale <= 0.) { 73 if(scale == 0.) 74 return 0.; 75 /* else */ 76 return T.nan; 77 } 78 79 return scale * pow(-log(unif_rand!T()), 1.0 / shape); 80 } 81 82 83 void test_weibull() 84 { 85 import std.stdio: writeln; 86 writeln("dweibull: ", dweibull(2., 3., 4., 0)); 87 writeln("pweibull: ", pweibull(2., 3., 4., 1, 0)); 88 writeln("qweibull: ", qweibull(.7, 3., 4., 1, 0)); 89 writeln("rweibull: ", rweibull(3., 4.), ", rweibull: ", rweibull(3., 4.), ", rweibull: ", rweibull(3., 4.)); 90 }