Skip to content

Commit fb7b10d

Browse files
authored
Merge pull request #39 from bgctw/dev2
support fitting ScaledLogNormal of LogNormal(-x)
2 parents 50962e9 + 9b5162f commit fb7b10d

File tree

6 files changed

+79
-2
lines changed

6 files changed

+79
-2
lines changed

docs/src/lognormal.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,33 @@ d = fit_mean_relerror(LogNormal, 2, 0.2)
4545
(true, true)
4646
```
4747

48+
## ScaledLogNormal: LogNormal(-x)
49+
To support the use case of a distribution of strictly negative values, the
50+
fitting of a mirrored LogNormal on `-x` is supported.
51+
52+
There is a type-alias
53+
`ScaledLogNormal = LocationScale{T, Continuous, LogNormal{T}} where T`,
54+
denoting a scaled and shifted LogNormal distribution.
55+
56+
There are fitting function dispatched by this type that fit
57+
such a mirrored distribution.
58+
59+
```jldoctest; output = false, setup = :(using DistributionFits)
60+
d = fit_mean_Σ(ScaledLogNormal, -1, log(1.1))
61+
(mean(d), σstar(d)) .≈ (-1.0, 1.1)
62+
# output
63+
(true, true)
64+
```
65+
66+
```jldoctest; output = false, setup = :(using DistributionFits)
67+
d = fit(ScaledLogNormal, -1.0, @qp_ll(-1.32), Val(:mode))
68+
(mode(d), quantile(d, 0.025)) .≈ (-1.0, -1.32)
69+
# output
70+
(true, true)
71+
```
72+
Note the usage of lower quantile for the mirrored distribution, here.
73+
74+
4875
## Detailed API
4976

5077
```@docs

ext/DistributionFitsOptimExt.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function DistributionFits.optimize(f, ::OptimOptimizer, lower, upper)
1111
end
1212

1313
function __init__()
14-
@info "DistributionFits: setting OptimOptimizer"
14+
#@info "DistributionFits: setting OptimOptimizer"
1515
#DistributionFits.set_optimizer(DistributionFitsOptimExt.OptimOptimizer())
1616
DistributionFits.set_optimizer(OptimOptimizer())
1717
end

inst/scratch.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

src/DistributionFits.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export
3636
# optimize, set_optimizer
3737

3838
# LogNormal
39-
export AbstractΣstar, Σstar, σstar
39+
export AbstractΣstar, Σstar, σstar, ScaledLogNormal
4040

4141
# LogitNormal
4242
export fit_mode_flat, shifloNormal

src/univariate/continuous/lognormal.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,32 @@ function fit_mean_relerror(::Type{LogNormal}, mean, relerror)
166166
σ = sqrt(log(w))
167167
LogNormal(μ, σ)
168168
end
169+
170+
171+
#---- support LogNormal(-x) of negative values ------------
172+
const ScaledLogNormal{T} = LocationScale{T, Continuous, LogNormal{T}} where T
173+
174+
σstar(d::ScaledLogNormal) = exp(params(d.ρ)[2])
175+
176+
177+
function fit_mean_Σ(::Type{ScaledLogNormal}, mean::T1, σ::T2) where {T1 <: Real,T2 <: Real}
178+
_T = promote_type(T1, T2)
179+
fit_mean_Σ(ScaledLogNormal{_T}, mean, σ)
180+
end
181+
function fit_mean_Σ(d::Type{ScaledLogNormal{T}}, mean::Real, σ::Real) where T
182+
mean < 0 && return(-1 * fit_mean_Σ(LogNormal{T}, -mean, σ))
183+
1 * fit_mean_Σ(LogNormal{T}, mean, σ)
184+
end
185+
186+
function fit_mode_quantile(::Type{ScaledLogNormal}, mode::T, qp::QuantilePoint) where T<:Real
187+
fit_mode_quantile(ScaledLogNormal{T}, mode, qp)
188+
end
189+
function fit_mode_quantile(::Type{ScaledLogNormal{T}}, mode::Real, qp::QuantilePoint) where T
190+
if mode < 0
191+
return(-1 * fit_mode_quantile(LogNormal{T}, -mode, QuantilePoint(-qp.q,1-qp.p)))
192+
#return(-1 * fit_mode_quantile(LogNormal{T}, -mode, qp))
193+
end
194+
1 * fit_mode_quantile(LogNormal{T}, mode, qp)
195+
end
196+
197+

test/univariate/continuous/lognormal.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,23 @@ end;
5454
@test mode(d) 0.5
5555
@test quantile(d, 0.95) 0.9
5656
end;
57+
58+
@testset "fitting ScaledLogNormal" begin
59+
d2 = fit_mean_Σ(ScaledLogNormal, -1, log(1.1))
60+
@test d2 isa ScaledLogNormal
61+
@test σstar(d2) == 1.1
62+
63+
d2 = fit_mean_Σ(ScaledLogNormal, 1.0, log(1.1))
64+
@test d2 isa ScaledLogNormal
65+
@test mean(d2) == 1.0
66+
@test σstar(d2) == 1.1
67+
68+
# take care to specify qp_ll here, its lower than mode
69+
d3 = fit(ScaledLogNormal, -1.0, @qp_ll(-1.32), Val(:mode))
70+
@test d3 isa ScaledLogNormal
71+
@test mode(d3) == -1.0
72+
@test quantile(d3, 0.025) -1.32
73+
74+
d3 = fit(ScaledLogNormal, 1.0, @qp_uu(1.32), Val(:mode))
75+
@test d3 isa ScaledLogNormal
76+
end;

0 commit comments

Comments
 (0)