Skip to content

Commit 3157319

Browse files
authored
Add log(-log(1 - x)) and 1 - exp(-exp(x)) (#56)
1 parent 5c8a025 commit 3157319

File tree

8 files changed

+54
-1
lines changed

8 files changed

+54
-1
lines changed

docs/src/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ logsumexp
2828
logsumexp!
2929
softmax!
3030
softmax
31+
cloglog
32+
cexpexp
3133
```

src/LogExpFunctions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import LinearAlgebra
1111

1212
export xlogx, xlogy, xlog1py, xexpx, xexpy, logistic, logit, log1psq, log1pexp, log1mexp, log2mexp, logexpm1,
1313
softplus, invsoftplus, log1pmx, logmxp1, logaddexp, logsubexp, logsumexp, logsumexp!, softmax,
14-
softmax!, logcosh
14+
softmax!, logcosh, cloglog, cexpexp
1515

1616
include("basicfuns.jl")
1717
include("logsumexp.jl")

src/basicfuns.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,3 +407,17 @@ function _softmax!(r, x, dims)
407407
end
408408
return r
409409
end
410+
411+
"""
412+
$(SIGNATURES)
413+
414+
Compute the complementary log-log, `log(-log(1 - x))`.
415+
"""
416+
cloglog(x) = log(-log1p(-x))
417+
418+
"""
419+
$(SIGNATURES)
420+
421+
Compute the complementary double exponential, `1 - exp(-exp(x))`.
422+
"""
423+
cexpexp(x) = -expm1(-exp(x))

src/chainrules.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,6 @@ function ChainRulesCore.rrule(::typeof(softmax), x::AbstractArray{<:Real}; dims=
163163
end
164164
return Ω, softmax_pullback
165165
end
166+
167+
ChainRulesCore.@scalar_rule(cloglog(x), (-inv((1 - x) * log1p(-x)),))
168+
ChainRulesCore.@scalar_rule(cexpexp(x), (-xexpx(-exp(x)),))

src/inverse.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ InverseFunctions.inverse(::typeof(log2mexp)) = log2mexp
77

88
InverseFunctions.inverse(::typeof(logit)) = logistic
99
InverseFunctions.inverse(::typeof(logistic)) = logit
10+
11+
InverseFunctions.inverse(::typeof(cloglog)) = cexpexp
12+
InverseFunctions.inverse(::typeof(cexpexp)) = cloglog

test/basicfuns.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,27 @@ end
410410
@test axes(s, 1) == OffsetArrays.IdOffsetRange(-2:0)
411411
@test collect(s) softmax(1:3)
412412
end
413+
414+
@testset "cloglog and cexpexp" begin
415+
cloglog_big(x::T) where {T} = T(log(-log(1 - BigFloat(x))))
416+
cexpexp_big(x::T) where {T} = 1 - exp(-exp(BigFloat(x)))
417+
418+
for x in 0.1:0.1:0.9
419+
@test cloglog(x) cloglog_big(x)
420+
@test cexpexp(x) cexpexp_big(x)
421+
end
422+
for _ in 1:10
423+
randf = rand(Float64)
424+
@test cloglog(randf) cloglog_big(randf)
425+
randi = rand(Int)
426+
@test cexpexp(randi) cexpexp_big(randi)
427+
end
428+
429+
@test cloglog(0) == -Inf
430+
@test cloglog(1) == Inf
431+
@test cloglog((ℯ - 1) / ℯ) == 0
432+
433+
@test cexpexp(Inf) == 1.0
434+
@test cexpexp(-Inf) == 0.0
435+
@test cexpexp(0) == (ℯ - 1) /
436+
end

test/chainrules.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,8 @@
112112
test_rrule(softmax, x; fkwargs=(dims=dims,))
113113
end
114114
end
115+
116+
test_scalar(cloglog, rand())
117+
118+
test_scalar(cexpexp, rand())
115119
end

test/inverse.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@
88

99
InverseFunctions.test_inverse(logistic, randn())
1010
InverseFunctions.test_inverse(logit, rand())
11+
12+
InverseFunctions.test_inverse(cloglog, rand())
13+
InverseFunctions.test_inverse(cexpexp, rand())
1114
end

0 commit comments

Comments
 (0)