package scientific.stats.continuous
import std.math.*
import std.unittest.*
import std.unittest.testmacro.*
import scientific.numbers.*
import scientific.stats.random.*
/*
* Probability density function for exponential distribution
*/
public func exponentialPDF(x: Float64, lambda: Float64): Float64 {
return lambda * pow(Float64.getE(), -lambda * x)
}
/*
* Cumulative density function for exponential distribution
*/
public func exponentialCDF(x: Float64, lambda: Float64): Float64 {
if (x < 0.0) {
return 0.0
}
return 1.0 - pow(Float64.getE(), -lambda * x)
}
/*
* Compute cumulative density between x1, x2
*/
public func exponentialCDF(lambda: Float64, x1: Float64, x2: Float64): Float64{
if (x1 >= x2) {
return 0.0 // Require input to satisfy x1 < x2
}
if (x2 <= 0.0) {
return 0.0
}
if (x1 < 0.0 && x2 > 0.0) {
return exponentialCDF(lambda, x2)
}
return exponentialCDF(lambda, x2) - exponentialCDF(lambda, x1)
}
/*
* Sampling from the exponential distribution
*/
public func exponentialSample(m: Random, lambda: Float64): Float64{
let x = m.nextFloat64()
return - 1.0 / lambda * log(x)
}
@Test
public class TestExponential {
@TestCase
func testExponential(): Unit {
@Assert(approxEqual(exponentialPDF(1.0, 1.0), 0.36787944117144233, atol:1e-13))
@Assert(approxEqual(exponentialPDF(2.0, 1.0), 0.1353352832366127, atol:1e-13))
@Assert(approxEqual(exponentialPDF(3.0, 1.0), 0.049787068367863944, atol:1e-13))
@Assert(approxEqual(exponentialPDF(4.0, 1.0), 0.01831563888873418, atol:1e-13))
}
}