|
1 | 1 | ## --- Fitting non-Gaussian distributions
|
2 | 2 |
|
3 |
| - struct BilinearExponential{T} |
| 3 | + struct BilinearExponential{T<:Real} <: ContinuousUnivariateDistribution |
4 | 4 | A::T
|
5 | 5 | μ::T
|
6 | 6 | σ::T
|
7 |
| - sharpness::T |
8 |
| - skew::T |
| 7 | + shp::T |
| 8 | + skw::T |
9 | 9 | end
|
10 |
| - function BilinearExponential(p::AbstractVector) |
| 10 | + function BilinearExponential(p::AbstractVector{T}) where {T} |
11 | 11 | @assert length(p) == 5
|
12 | 12 | @assert all(x->!(x<0), Iterators.drop(p,1))
|
13 |
| - BilinearExponential(p...) |
| 13 | + BilinearExponential{T}(p...) |
| 14 | + end |
| 15 | + function BilinearExponential(p::NTuple{5,T}) where {T} |
| 16 | + @assert all(x->!(x<0), Iterators.drop(p,1)) |
| 17 | + BilinearExponential{T}(p...) |
| 18 | + end |
| 19 | + |
| 20 | + ## Conversions |
| 21 | + Base.convert(::Type{BilinearExponential{T}}, d::Normal) where {T<:Real} = BilinearExponential{T}(T(d.A), T(d.μ), T(d.σ), T(d.shp), T(d.skw)) |
| 22 | + Base.convert(::Type{BilinearExponential{T}}, d::Normal{T}) where {T<:Real} = d |
| 23 | + |
| 24 | + ## Parameters |
| 25 | + Distributions.params(d::BilinearExponential) = (d.A, d.μ, d.σ, d.shp, d.skw) |
| 26 | + @inline Distributions.partype(d::BilinearExponential{T}) where {T<:Real} = T |
| 27 | + |
| 28 | + Distributions.location(d::BilinearExponential) = d.μ |
| 29 | + Distributions.scale(d::BilinearExponential) = d.σ |
| 30 | + |
| 31 | + Base.eltype(::Type{BilinearExponential{T}}) where {T} = T |
| 32 | + |
| 33 | + ## Evaluation |
| 34 | + function Distributions.pdf(d::BilinearExponential, x::Real) |
| 35 | + xs = (x - d.μ)/d.σ # X scaled by mean and variance |
| 36 | + v = 1/2 - atan(xs)/3.141592653589793 # Sigmoid (positive on LHS) |
| 37 | + return exp(d.A + d.shp*d.skw*xs*v - d.shp/d.skw*xs*(1-v)) |
14 | 38 | end
|
15 | 39 |
|
| 40 | + function Distributions.logpdf(d::BilinearExponential, x::Real) |
| 41 | + xs = (x - d.μ)/d.σ # X scaled by mean and variance |
| 42 | + v = 1/2 - atan(xs)/3.141592653589793 # Sigmoid (positive on LHS) |
| 43 | + return d.A + d.shp*d.skw*xs*v - d.shp/d.skw*xs*(1-v) |
| 44 | + end |
| 45 | + |
| 46 | + ## Affine transformations |
| 47 | + Base.:+(d::BilinearExponential{T}, c::Real) where {T} = BilinearExponential{T}(d.A, d.μ + c, d.σ, d.shp, d.skw) |
| 48 | + Base.:*(d::BilinearExponential{T}, c::Real) where {T} = BilinearExponential{T}(d.A, d.μ * c, d.σ * abs(c), d.shp, d.skw) |
| 49 | + |
16 | 50 | """
|
17 | 51 | ```Julia
|
18 | 52 | bilinear_exponential(x::Number, p::AbstractVector)
|
|
95 | 129 | skw = abs(p[5,i])
|
96 | 130 | ll += shp*skw*xs*v - shp/skw*xs*(1-v)
|
97 | 131 | end
|
98 |
| - return ll |
| 132 | + return lles |
99 | 133 | end
|
100 | 134 | function bilinear_exponential_ll(x::AbstractVector, ages::AbstractVector{BilinearExponential{T}}) where T
|
101 | 135 | ll = zero(T)
|
|
104 | 138 | isnan(pᵢ.μ) && continue
|
105 | 139 | xs = (x[i]-pᵢ.μ)/(pᵢ.σ) # X scaled by mean and variance
|
106 | 140 | v = 1/2 - atan(xs)/3.141592653589793 # Sigmoid (positive on LHS)
|
107 |
| - shp, skw = pᵢ.sharpness, pᵢ.skew |
| 141 | + shp, skw = pᵢ.shp, pᵢ.skw |
108 | 142 | ll += shp*skw*xs*v - shp/skw*xs*(1-v)
|
109 | 143 | end
|
110 | 144 | return ll
|
|
146 | 180 | ## --- Biquadratic distribution (like bilinear, with quadratic sides)
|
147 | 181 |
|
148 | 182 |
|
149 |
| - struct BiquadraticExponential{T} |
| 183 | + struct BiquadraticExponential{T<:Real} |
150 | 184 | A::T
|
151 | 185 | μ::T
|
152 | 186 | σ::T
|
153 |
| - sharpness::T |
154 |
| - skew::T |
| 187 | + shp::T |
| 188 | + skw::T |
155 | 189 | end
|
156 | 190 | function BiquadraticExponential(p::AbstractVector)
|
157 | 191 | @assert length(p) == 5
|
|
191 | 225 | pᵢ = ages[i]
|
192 | 226 | xs = (x[i]-pᵢ.μ)/(pᵢ.σ) # X scaled by mean and variance
|
193 | 227 | v = 1/2 - atan(xs)/3.141592653589793 # Sigmoid (positive on LHS)
|
194 |
| - shp = pᵢ.sharpness |
195 |
| - skw = pᵢ.skew |
| 228 | + shp = pᵢ.shp |
| 229 | + skw = pᵢ.skw |
196 | 230 | ll -= (shp*skw*xs*v - shp/skw*xs*(1-v))^2
|
197 | 231 | end
|
198 | 232 | return ll
|
|
0 commit comments