From 6422129b4fb633d88fb5bc22502d2356f00338cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20K=2E=20Papp?= Date: Wed, 9 Jul 2025 14:25:09 +0200 Subject: [PATCH 1/4] make tests have their own environment --- Project.toml | 14 -------------- test/Project.toml | 10 ++++++++++ 2 files changed, 10 insertions(+), 14 deletions(-) create mode 100644 test/Project.toml diff --git a/Project.toml b/Project.toml index 2c843af..1c46144 100644 --- a/Project.toml +++ b/Project.toml @@ -28,17 +28,3 @@ DocStringExtensions = "0.8, 0.9" InverseFunctions = "0.1" IrrationalConstants = "0.1, 0.2" julia = "1.10" - -[extras] -ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -ChainRulesTestUtils = "cdddcdb0-9152-4a09-a978-84456f9df70a" -ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" -ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" -InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" -OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["ChainRulesCore", "ChainRulesTestUtils", "ChangesOfVariables", "FiniteDifferences", "ForwardDiff", "InverseFunctions", "OffsetArrays", "Random", "Test"] diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..10e84c2 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,10 @@ +[deps] +ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +ChainRulesTestUtils = "cdddcdb0-9152-4a09-a978-84456f9df70a" +ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" +FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" +OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" From 1961420daace371f57049f9de2e99d7a0baa498b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20K=2E=20Papp?= Date: Wed, 9 Jul 2025 15:02:52 +0200 Subject: [PATCH 2/4] rearrange branches and test early for +-Inf case This should work for ForwardDiff, too. --- src/logsumexp.jl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/logsumexp.jl b/src/logsumexp.jl index 0540cca..0c655f4 100644 --- a/src/logsumexp.jl +++ b/src/logsumexp.jl @@ -114,6 +114,9 @@ _logsumexp_onepass_op((xmax, r)::Tuple{<:Number,<:Number}, x::Number) = _logsumexp_onepass_op(x::Number, xmax::Number, r::Number) = _logsumexp_onepass_op(promote(x, xmax)..., r) function _logsumexp_onepass_op(x::T, xmax::T, r::Number) where {T<:Number} + # The following invariants are maintained through the reduction: + # `xmax` is the maximum of the elements encountered so far, + # ``r = ∑ᵢ exp(xᵢ - xmax)`` over the same elements. _xmax, _r = if isnan(x) || isnan(xmax) # ensure that `NaN` is propagated correctly for complex numbers z = oftype(x, NaN) @@ -121,14 +124,13 @@ function _logsumexp_onepass_op(x::T, xmax::T, r::Number) where {T<:Number} else real_x = real(x) real_xmax = real(xmax) - if real_x > real_xmax + if isinf(real_x) && isinf(real_xmax) && (real_x * real_xmax) > 0 + # handle `x = xmax = ±Inf` correctly, without relying on ForwardDiff.value + xmax, r + exp(zero(x - xmax)) + elseif real_x > real_xmax x, (r + one(r)) * exp(xmax - x) - elseif real_x < real_xmax - xmax, r + exp(x - xmax) else - # handle `x = xmax = ±Inf` correctly - # checking inequalities above instead of equality fixes issue #59 - xmax, r + exp(zero(x - xmax)) + xmax, r + exp(x - xmax) end end return _xmax, _r From 304998bdc463008678615cdbcab0173932316fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20K=2E=20Papp?= Date: Wed, 9 Jul 2025 15:03:25 +0200 Subject: [PATCH 3/4] dev .. for test project --- test/Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Project.toml b/test/Project.toml index 10e84c2..f0967c7 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -5,6 +5,7 @@ ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" +LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" From b99446597be479f80202bb06c4776c8ae3b20526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20K=2E=20Papp?= Date: Mon, 14 Jul 2025 10:00:51 +0200 Subject: [PATCH 4/4] Add QA with Aqua and JET, fix missing compat --- Project.toml | 1 + test/Project.toml | 2 ++ test/runtests.jl | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/Project.toml b/Project.toml index 1c46144..17f3aab 100644 --- a/Project.toml +++ b/Project.toml @@ -27,4 +27,5 @@ ChangesOfVariables = "0.1" DocStringExtensions = "0.8, 0.9" InverseFunctions = "0.1" IrrationalConstants = "0.1, 0.2" +LinearAlgebra = "1.10" julia = "1.10" diff --git a/test/Project.toml b/test/Project.toml index f0967c7..fdbcaac 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,10 +1,12 @@ [deps] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" ChainRulesTestUtils = "cdddcdb0-9152-4a09-a978-84456f9df70a" ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" +JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" diff --git a/test/runtests.jl b/test/runtests.jl index b9665e7..27b247f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,3 +16,9 @@ include("basicfuns.jl") include("chainrules.jl") include("inverse.jl") include("with_logabsdet_jacobian.jl") + +# QA +import JET +JET.report_package("LogExpFunctions") +import Aqua +Aqua.test_all(LogExpFunctions)