Skip to content

Commit 1bb0913

Browse files
authored
add logerf(a, b) (#229)
1 parent fc960c6 commit 1bb0913

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "SpecialFunctions"
22
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
3-
version = "0.10.2"
3+
version = "0.10.3"
44

55
[deps]
66
OpenSpecFun_jll = "efe28fd5-8261-553b-a9e1-b2916fc3738e"

src/SpecialFunctions.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export
3636
erfcx,
3737
erfi,
3838
erfinv,
39+
logerf,
3940
logerfc,
4041
logerfcx,
4142
eta,

src/erf.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,3 +506,27 @@ end
506506

507507
logerfcx(x::Real) = logerfcx(float(x))
508508
logerfcx(x::AbstractFloat) = throw(MethodError(logerfcx, x))
509+
510+
@doc raw"""
511+
logerf(x, y)
512+
513+
Compute the natural logarithm of two-argument error function. This is an accurate version of
514+
`log(erf(x, y))`, which works for large `x, y`.
515+
516+
External links: [Wikipedia](https://en.wikipedia.org/wiki/Error_function).
517+
518+
See also: [`erf(x,y)`](@ref SpecialFunctions.erf).
519+
"""
520+
function logerf(a::Real, b::Real)
521+
if abs(a) 1/√2 && abs(b) 1/√2
522+
return log(erf(a, b))
523+
elseif b > a > 0
524+
return logerfc(a) + log1mexp(logerfc(b) - logerfc(a))
525+
elseif a < b < 0
526+
return logerfc(-b) + log1mexp(logerfc(-a) - logerfc(-b))
527+
else
528+
return log(erf(a, b))
529+
end
530+
end
531+
532+
log1mexp(x::Real) = x < -log(oftype(x, 2)) ? log1p(-exp(x)) : log(-expm1(x))

test/erf.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,22 @@
141141
@test isnan(erf(NaN, 0))
142142
@test isnan(erf(0, NaN))
143143
@test isnan(erf(NaN, NaN))
144+
145+
@test logerf(-5, 35) 0.693147180559176579520017808560
146+
@test logerf(30, 35) -903.974117110643878079600243618
147+
@test logerf(-35, -30) -903.974117110643878079600243618
148+
@test logerf(10, Inf) -102.879889024844888574804787140
149+
@test logerf(-Inf, Inf) 0.693147180559945309417232121458
150+
@test logerf(Inf, Inf) == -Inf
151+
@test logerf(-Inf, -Inf) == -Inf
152+
@test logerf(-Inf, Inf) log(2)
153+
@test logerf(-1e-6, 1e-6) -13.0015811397694169056785314498
154+
@test isnan(logerf(NaN, 0))
155+
@test isnan(logerf(0, NaN))
156+
@test isnan(logerf(NaN, NaN))
157+
@test logerf(-1e-30, 1e-30) -68.2636233716261799887769930733
158+
@test logerf(1e-30, 2e-30) -68.9567705521861252981942251947
159+
@test logerf(-2e-30, -1e-30) -68.9567705521861252981942251947
160+
@test_throws DomainError logerf(2, 1)
144161
end
145162
end

0 commit comments

Comments
 (0)