Skip to content
Merged

Dev2 #39

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/src/lognormal.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,33 @@ d = fit_mean_relerror(LogNormal, 2, 0.2)
(true, true)
```

## ScaledLogNormal: LogNormal(-x)
To support the use case of a distribution of strictly negative values, the
fitting of a mirrored LogNormal on `-x` is supported.

There is a type-alias
`ScaledLogNormal = LocationScale{T, Continuous, LogNormal{T}} where T`,
denoting a scaled and shifted LogNormal distribution.

There are fitting function dispatched by this type that fit
such a mirrored distribution.

```jldoctest; output = false, setup = :(using DistributionFits)
d = fit_mean_Σ(ScaledLogNormal, -1, log(1.1))
(mean(d), σstar(d)) .≈ (-1.0, 1.1)
# output
(true, true)
```

```jldoctest; output = false, setup = :(using DistributionFits)
d = fit(ScaledLogNormal, -1.0, @qp_ll(-1.32), Val(:mode))
(mode(d), quantile(d, 0.025)) .≈ (-1.0, -1.32)
# output
(true, true)
```
Note the usage of lower quantile for the mirrored distribution, here.


## Detailed API

```@docs
Expand Down
2 changes: 1 addition & 1 deletion ext/DistributionFitsOptimExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function DistributionFits.optimize(f, ::OptimOptimizer, lower, upper)
end

function __init__()
@info "DistributionFits: setting OptimOptimizer"
#@info "DistributionFits: setting OptimOptimizer"
#DistributionFits.set_optimizer(DistributionFitsOptimExt.OptimOptimizer())
DistributionFits.set_optimizer(OptimOptimizer())
end
Expand Down
1 change: 1 addition & 0 deletions inst/scratch.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 1 addition & 1 deletion src/DistributionFits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export
# optimize, set_optimizer

# LogNormal
export AbstractΣstar, Σstar, σstar
export AbstractΣstar, Σstar, σstar, ScaledLogNormal

# LogitNormal
export fit_mode_flat, shifloNormal
Expand Down
29 changes: 29 additions & 0 deletions src/univariate/continuous/lognormal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,32 @@ function fit_mean_relerror(::Type{LogNormal}, mean, relerror)
σ = sqrt(log(w))
LogNormal(μ, σ)
end


#---- support LogNormal(-x) of negative values ------------
const ScaledLogNormal{T} = LocationScale{T, Continuous, LogNormal{T}} where T

σstar(d::ScaledLogNormal) = exp(params(d.ρ)[2])


function fit_mean_Σ(::Type{ScaledLogNormal}, mean::T1, σ::T2) where {T1 <: Real,T2 <: Real}
_T = promote_type(T1, T2)
fit_mean_Σ(ScaledLogNormal{_T}, mean, σ)
end
function fit_mean_Σ(d::Type{ScaledLogNormal{T}}, mean::Real, σ::Real) where T
mean < 0 && return(-1 * fit_mean_Σ(LogNormal{T}, -mean, σ))
1 * fit_mean_Σ(LogNormal{T}, mean, σ)
end

function fit_mode_quantile(::Type{ScaledLogNormal}, mode::T, qp::QuantilePoint) where T<:Real
fit_mode_quantile(ScaledLogNormal{T}, mode, qp)
end
function fit_mode_quantile(::Type{ScaledLogNormal{T}}, mode::Real, qp::QuantilePoint) where T
if mode < 0
return(-1 * fit_mode_quantile(LogNormal{T}, -mode, QuantilePoint(-qp.q,1-qp.p)))
#return(-1 * fit_mode_quantile(LogNormal{T}, -mode, qp))
end
1 * fit_mode_quantile(LogNormal{T}, mode, qp)
end


20 changes: 20 additions & 0 deletions test/univariate/continuous/lognormal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,23 @@ end;
@test mode(d) ≈ 0.5
@test quantile(d, 0.95) ≈ 0.9
end;

@testset "fitting ScaledLogNormal" begin
d2 = fit_mean_Σ(ScaledLogNormal, -1, log(1.1))
@test d2 isa ScaledLogNormal
@test σstar(d2) == 1.1

d2 = fit_mean_Σ(ScaledLogNormal, 1.0, log(1.1))
@test d2 isa ScaledLogNormal
@test mean(d2) == 1.0
@test σstar(d2) == 1.1

# take care to specify qp_ll here, its lower than mode
d3 = fit(ScaledLogNormal, -1.0, @qp_ll(-1.32), Val(:mode))
@test d3 isa ScaledLogNormal
@test mode(d3) == -1.0
@test quantile(d3, 0.025) ≈ -1.32

d3 = fit(ScaledLogNormal, 1.0, @qp_uu(1.32), Val(:mode))
@test d3 isa ScaledLogNormal
end;