1 /++ 2 This module contains algorithms for the $(LINK2 https://en.wikipedia.org/wiki/Exponential_distribution, Exponential 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.exponential; 13 14 import mir.internal.utility: isFloatingPoint; 15 16 /++ 17 Computes the exponential probability density function (PDF). 18 19 Params: 20 x = value to evaluate PDF 21 lambda = number of events in an interval 22 23 See_also: 24 $(LINK2 https://en.wikipedia.org/wiki/Exponential_distribution, Exponential Distribution) 25 +/ 26 @safe pure nothrow @nogc 27 T exponentialPDF(T)(const T x, const T lambda) 28 if (isFloatingPoint!T) 29 in (x >= 0, "x must be greater than or equal to 0") 30 in (lambda > 0, "lambda must be greater than zero") 31 { 32 import mir.math.common: exp; 33 34 return lambda * exp(-lambda * x); 35 } 36 37 /// 38 version(mir_stat_test) 39 @safe pure nothrow @nogc 40 unittest { 41 import mir.math.common: approxEqual; 42 43 assert(0.5.exponentialPDF(2.0).approxEqual(0.7357589)); 44 assert(0.75.exponentialPDF(2.0).approxEqual(0.4462603)); 45 assert(0.25.exponentialPDF(0.5).approxEqual(0.4412485)); 46 } 47 48 /++ 49 Computes the exponential cumulative distribution function (CDF). 50 51 Params: 52 x = value to evaluate CDF 53 lambda = number of events in an interval 54 55 See_also: 56 $(LINK2 https://en.wikipedia.org/wiki/Exponential_distribution, Exponential Distribution) 57 +/ 58 @safe pure nothrow @nogc 59 T exponentialCDF(T)(const T x, const T lambda) 60 if (isFloatingPoint!T) 61 in (x >= 0, "x must be greater than or equal to 0") 62 in (lambda > 0, "lambda must be greater than zero") 63 { 64 import mir.math.common: exp; 65 66 return 1 - exp(-lambda * x); 67 } 68 69 /// 70 version(mir_stat_test) 71 @safe pure nothrow @nogc 72 unittest { 73 import mir.math.common: approxEqual; 74 75 assert(0.5.exponentialCDF(2.0).approxEqual(0.6321206)); 76 assert(0.75.exponentialCDF(2.0).approxEqual(0.7768698)); 77 assert(0.25.exponentialCDF(0.5).approxEqual(0.1175031)); 78 } 79 80 /++ 81 Computes the exponential complementary cumulative distribution function (CCDF). 82 83 Params: 84 x = value to evaluate CCDF 85 lambda = number of events in an interval 86 87 See_also: 88 $(LINK2 https://en.wikipedia.org/wiki/Exponential_distribution, Exponential Distribution) 89 +/ 90 @safe pure nothrow @nogc 91 T exponentialCCDF(T)(const T x, const T lambda) 92 if (isFloatingPoint!T) 93 in (x >= 0, "x must be greater than or equal to 0") 94 in (lambda > 0, "lambda must be greater than zero") 95 { 96 import mir.math.common: exp; 97 98 return exp(-lambda * x); 99 } 100 101 /// 102 version(mir_stat_test) 103 @safe pure nothrow @nogc 104 unittest { 105 import mir.math.common: approxEqual; 106 107 assert(0.5.exponentialCCDF(2.0).approxEqual(1 - exponentialCDF(0.5, 2.0))); 108 assert(0.75.exponentialCCDF(2.0).approxEqual(1 - exponentialCDF(0.75, 2.0))); 109 assert(0.25.exponentialCCDF(0.5).approxEqual(1 - exponentialCDF(0.25, 0.5))); 110 } 111 112 /++ 113 Computes the exponential inverse cumulative distribution function (InvCDF). 114 115 Params: 116 p = value to evaluate InvCDF 117 lambda = number of events in an interval 118 119 See_also: 120 $(LINK2 https://en.wikipedia.org/wiki/Exponential_distribution, Exponential Distribution) 121 +/ 122 123 @safe pure nothrow @nogc 124 T exponentialInvCDF(T)(const T p, const T lambda) 125 if (isFloatingPoint!T) 126 in (p >= 0, "p must be greater than or equal to 0") 127 in (p < 1, "p must be less than or equal to 1") 128 in (lambda > 0, "lambda must be greater than zero") 129 { 130 import mir.math.internal.log1p: log1p; 131 132 return -log1p(-p) / lambda; 133 } 134 135 /// 136 version(mir_stat_test) 137 @safe pure nothrow @nogc 138 unittest { 139 import mir.math.common: approxEqual; 140 141 assert(0.6321206.exponentialInvCDF(2.0).approxEqual(0.5)); 142 assert(0.7768698.exponentialInvCDF(2.0).approxEqual(0.75)); 143 assert(0.1175031.exponentialInvCDF(0.5).approxEqual(0.25)); 144 } 145 146 /++ 147 Computes the exponential log probability density function (LPDF). 148 149 Params: 150 x = value to evaluate LPDF 151 lambda = number of events in an interval 152 153 See_also: 154 $(LINK2 https://en.wikipedia.org/wiki/Exponential_distribution, Exponential Distribution) 155 +/ 156 @safe pure nothrow @nogc 157 T exponentialLPDF(T)(const T x, const T lambda) 158 if (isFloatingPoint!T) 159 in (x >= 0, "x must be greater than or equal to 0") 160 in (lambda > 0, "lambda must be greater than zero") 161 { 162 import mir.math.common: log; 163 164 return log(lambda) - x * lambda; 165 } 166 167 /// 168 version(mir_stat_test) 169 @safe pure nothrow @nogc 170 unittest { 171 import mir.math.common: approxEqual, log; 172 173 assert(0.5.exponentialLPDF(2.0).approxEqual(log(exponentialPDF(0.5, 2.0)))); 174 assert(0.75.exponentialLPDF(2.0).approxEqual(log(exponentialPDF(0.75, 2.0)))); 175 assert(0.25.exponentialLPDF(0.5).approxEqual(log(exponentialPDF(0.25, 0.5)))); 176 }