1 /++ 2 This module contains algorithms for the continuous $(LINK2 https://en.wikipedia.org/wiki/Continuous_uniform_distribution, Uniform Distribution). 3 4 License: $(HTTP www.apache.org/licenses/LICENSE-2.0, Apache-2.0) 5 6 Authors: John Michael Hall 7 8 Copyright: 2022-3 Mir Stat Authors. 9 10 +/ 11 12 module mir.stat.distribution.uniform; 13 14 import mir.internal.utility: isFloatingPoint; 15 16 /++ 17 Computes the uniform probability density function (PDF). 18 19 Params: 20 x = value to evaluate PDF 21 lower = lower bound 22 upper = upper bound 23 24 See_also: 25 $(LINK2 https://en.wikipedia.org/wiki/Continuous_uniform_distribution, Uniform Distribution) 26 +/ 27 @safe pure nothrow @nogc 28 T uniformPDF(T)(const T x, const T lower = 0, const T upper = 1) 29 if (isFloatingPoint!T) 30 in (x >= lower, "x must be greater than or equal to lower bound") 31 in (x <= upper, "x must be less than or equal to upper bound") 32 in (lower < upper, "lower must be less than upper") 33 { 34 return 1.0L / (upper - lower); 35 } 36 37 /// 38 version(mir_stat_test) 39 @safe pure nothrow @nogc 40 unittest { 41 import mir.math.common: approxEqual; 42 assert(0.5.uniformPDF == 1); 43 assert(0.5.uniformPDF(0.0, 1.5).approxEqual(2.0 / 3)); 44 assert(2.5.uniformPDF(1.0, 3.0).approxEqual(0.5)); 45 } 46 47 /++ 48 Computes the uniform cumulative distribution function (CDF). 49 50 Params: 51 x = value to evaluate CDF 52 lower = lower bound 53 upper = upper bound 54 55 See_also: 56 $(LINK2 https://en.wikipedia.org/wiki/Continuous_uniform_distribution, Uniform Distribution) 57 +/ 58 @safe pure nothrow @nogc 59 T uniformCDF(T)(const T x, const T lower = 0, const T upper = 1) 60 if (isFloatingPoint!T) 61 in (x >= lower, "x must be greater than or equal to lower bound") 62 in (x <= upper, "x must be less than or equal to upper bound") 63 in (lower < upper, "lower must be less than upper") 64 { 65 return (x - lower) / (upper - lower); 66 } 67 68 /// 69 version(mir_stat_test) 70 @safe pure nothrow @nogc 71 unittest { 72 import mir.math.common: approxEqual; 73 assert(0.5.uniformCDF == 0.5); 74 assert(0.5.uniformCDF(0.0, 1.5).approxEqual(1.0 / 3)); 75 assert(2.5.uniformCDF(1.0, 3.0).approxEqual(3.0 / 4)); 76 } 77 78 /++ 79 Computes the uniform complementary cumulative distribution function (CCDF). 80 81 Params: 82 x = value to evaluate CCDF 83 lower = lower bound 84 upper = upper bound 85 86 See_also: 87 $(LINK2 https://en.wikipedia.org/wiki/Continuous_uniform_distribution, Uniform Distribution) 88 +/ 89 @safe pure nothrow @nogc 90 T uniformCCDF(T)(const T x, const T lower = 0, const T upper = 1) 91 if (isFloatingPoint!T) 92 in (x >= lower, "x must be greater than or equal to lower bound") 93 in (x <= upper, "x must be less than or equal to upper bound") 94 in (lower < upper, "lower must be less than upper") 95 { 96 return (upper - x) / (upper - lower); 97 } 98 99 /// 100 version(mir_stat_test) 101 @safe pure nothrow @nogc 102 unittest { 103 import mir.math.common: approxEqual; 104 assert(0.5.uniformCCDF == 0.5); 105 assert(0.5.uniformCCDF(0.0, 1.5).approxEqual(2.0 / 3)); 106 assert(2.5.uniformCCDF(1.0, 3.0).approxEqual(1.0 / 4)); 107 } 108 109 /++ 110 Computes the uniform inverse cumulative distribution function (InvCDF) 111 112 Params: 113 p = value to evaluate InvCDF 114 lower = lower bound 115 upper = upper bound 116 117 See_also: 118 $(LINK2 https://en.wikipedia.org/wiki/Continuous_uniform_distribution, Uniform Distribution) 119 +/ 120 @safe pure nothrow @nogc 121 T uniformInvCDF(T)(const T p, const T lower = 0, const T upper = 1) 122 if (isFloatingPoint!T) 123 in (p >= 0, "p must be greater than or equal to 0") 124 in (p <= 1, "p must be less than or equal to 1") 125 in (lower < upper, "lower must be less than upper") 126 { 127 return lower + p * (upper - lower); 128 } 129 130 /// 131 version(mir_stat_test) 132 @safe pure nothrow @nogc 133 unittest { 134 import mir.math.common: approxEqual; 135 assert(0.5.uniformInvCDF == 0.5); 136 assert((1.0 / 3).uniformInvCDF(0.0, 1.5).approxEqual(0.5)); 137 assert((3.0 / 4).uniformInvCDF(1.0, 3.0).approxEqual(2.5)); 138 } 139 140 /++ 141 Computes the uniform log probability density function (LPDF) 142 143 Params: 144 x = value to evaluate LPDF 145 lower = lower bound 146 upper = upper bound 147 148 See_also: 149 $(LINK2 https://en.wikipedia.org/wiki/Continuous_uniform_distribution, Uniform Distribution) 150 +/ 151 @safe pure nothrow @nogc 152 T uniformLPDF(T)(const T x, const T lower = 0, const T upper = 1) 153 if (isFloatingPoint!T) 154 in (x >= lower, "x must be greater than or equal to lower bound") 155 in (x <= upper, "x must be less than or equal to upper bound") 156 in (lower < upper, "lower must be less than upper") 157 { 158 import mir.math.common: log; 159 160 return -log(upper - lower); 161 } 162 163 /// 164 version(mir_stat_test) 165 @safe pure nothrow @nogc 166 unittest { 167 import mir.math.common: approxEqual, log; 168 assert(0.5.uniformLPDF == 0); 169 assert(0.5.uniformLPDF(0.0, 1.5).approxEqual(-log(1.5))); 170 assert(1.5.uniformLPDF(1.0, 3.0).approxEqual(-log(2.0))); 171 }