|
| 1 | +""" |
| 2 | + DistributionTools |
| 3 | +
|
| 4 | +A module containing tools for working with size distributions. |
| 5 | +
|
| 6 | +Currently, it contains tools for working with the generalized gamma distribution |
| 7 | +and the exponential distribution. |
| 8 | +
|
| 9 | +Mostly used for the 2-moment microphysics. |
| 10 | +""" |
| 11 | +module DistributionTools |
| 12 | + |
| 13 | +import SpecialFunctions as SF |
| 14 | + |
| 15 | +""" |
| 16 | + generalized_gamma_quantile(ν, μ, B, Y) |
| 17 | +
|
| 18 | +Calculate the quantile (inverse cumulative distribution function) for a |
| 19 | + generalized gamma distribution parameterized in the form: |
| 20 | +
|
| 21 | + g(x) = A ⋅ x^ν ⋅ exp(-B ⋅ x^μ) |
| 22 | +
|
| 23 | +# Arguments |
| 24 | +- `ν, μ, B`: The PDF parameters |
| 25 | +- `Y`: The probability level (0 ≤ Y ≤ 1) for which to compute the quantile |
| 26 | +
|
| 27 | +# Returns |
| 28 | +- `x`: The value x such that P(X ≤ x) = Y |
| 29 | +""" |
| 30 | +function generalized_gamma_quantile(ν, μ, B, Y) |
| 31 | + # Compute the inverse of the regularized incomplete gamma function |
| 32 | + z = SF.gamma_inc_inv((ν + 1) / μ, Y, 1 - Y) |
| 33 | + return (z / B)^(1 / μ) |
| 34 | +end |
| 35 | + |
| 36 | +""" |
| 37 | + generalized_gamma_cdf(ν, μ, B, x) |
| 38 | +
|
| 39 | +Calculate the cumulative distribution function (CDF) for a generalized gamma distribution |
| 40 | +parameterized in the form: |
| 41 | +
|
| 42 | + g(x) = A * x^ν * exp(-B * x^μ) |
| 43 | +
|
| 44 | +The CDF gives the probability P(X ≤ x). |
| 45 | +
|
| 46 | +# Arguments |
| 47 | + - `ν, μ, B`: The PDF parameters |
| 48 | + - `x`: The value at which to evaluate the CDF |
| 49 | +
|
| 50 | +# Returns |
| 51 | + - `p`: The probability P(X ≤ x) |
| 52 | +""" |
| 53 | +function generalized_gamma_cdf(ν, μ, B, x) |
| 54 | + # Check input validity |
| 55 | + μ > 0 || throw(DomainError(μ, "Parameter μ must be positive")) |
| 56 | + B > 0 || throw(DomainError(B, "Parameter B must be positive")) |
| 57 | + # Handle edge cases |
| 58 | + x ≤ 0 && return zero(x) |
| 59 | + |
| 60 | + # Compute the regularized incomplete gamma function |
| 61 | + p, _ = SF.gamma_inc((ν + 1) / μ, (B * x)^μ) |
| 62 | + return p |
| 63 | +end |
| 64 | + |
| 65 | +""" |
| 66 | + exponential_cdf(D_mean, D) |
| 67 | +
|
| 68 | +Calculate the cumulative distribution function (CDF) for an exponential distribution |
| 69 | +parameterized in the form: |
| 70 | +
|
| 71 | + n(D) = N₀ * exp(-D / D_mean) |
| 72 | +
|
| 73 | +where N₀ is a normalizing constant such that the total probability is 1. |
| 74 | +
|
| 75 | +# Arguments |
| 76 | +- `D_mean`: The mean value of the distribution |
| 77 | +- `D`: The point at which to evaluate the CDF (must be ≥ 0) |
| 78 | +
|
| 79 | +# Returns |
| 80 | +- `p`: The probability P(X ≤ D) |
| 81 | +""" |
| 82 | +function exponential_cdf(D_mean, D) |
| 83 | + # Check input validity |
| 84 | + D_mean > 0 || throw(DomainError(D_mean, "Mean parameter must be positive")) |
| 85 | + # Handle edge cases |
| 86 | + D < 0 && return zero(D) |
| 87 | + # Calculate CDF: P(X ≤ D) = 1 - exp(-D/D_mean) |
| 88 | + return 1 - exp(-D / D_mean) |
| 89 | +end |
| 90 | + |
| 91 | +""" |
| 92 | + exponential_quantile(D_mean, Y) |
| 93 | +
|
| 94 | +Calculate the quantile (inverse cumulative distribution function) for an exponential distribution |
| 95 | +parameterized in the form: |
| 96 | +
|
| 97 | + n(D) = N₀ * exp(-D / D_mean) |
| 98 | +
|
| 99 | +where N₀ is a normalizing constant such that the total probability is 1. |
| 100 | +
|
| 101 | +# Arguments |
| 102 | +- `Y`: The probability level (0 ≤ Y ≤ 1) for which to compute the quantile |
| 103 | +- `D_mean`: The mean value of the distribution |
| 104 | +
|
| 105 | +# Returns |
| 106 | +- `D`: The value D such that P(X ≤ D) = Y |
| 107 | +""" |
| 108 | +function exponential_quantile(D_mean, Y) |
| 109 | + # Check input validity |
| 110 | + (0 ≤ Y ≤ 1) || throw(DomainError(Y, "Probability Y must be in [0,1]")) |
| 111 | + D_mean > 0 || throw(DomainError(D_mean, "Mean parameter must be positive")) |
| 112 | + # Calculate quantile: x = -D_mean * ln(1-Y) |
| 113 | + return -D_mean * log(1 - Y) |
| 114 | +end |
| 115 | + |
| 116 | +end # module DistributionTools |
0 commit comments