Skip to content

Commit ef0edaf

Browse files
Merge pull request #129 from ArnoStrouwen/inf
start generalizing inf
2 parents b7a11ef + 9835c49 commit ef0edaf

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

src/Integrals.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ function checkkwargs(kwargs...)
5656
end
5757
return nothing
5858
end
59-
6059
"""
6160
```julia
6261
solve(prob::IntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm; kwargs...)

src/algorithms.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,15 @@ VEGAS(; nbins = 100, ncalls = 1000, debug = false) = VEGAS(nbins, ncalls, debug)
8989
Struct for evaluating an integral via (composite) Gauss-Legendre quadrature.
9090
The field `C` will be `true` if `subintervals > 1`, and `false` otherwise.
9191
92-
The fields `nodes::N` and `weights::W` are defined by
93-
`nodes, weights = gausslegendre(n)` for a given number of nodes `n`.
92+
The fields `nodes::N` and `weights::W` are defined by
93+
`nodes, weights = gausslegendre(n)` for a given number of nodes `n`.
9494
95-
The field `subintervals::Int64 = 1` (with default value `1`) defines the
96-
number of intervals to partition the original interval of integration
95+
The field `subintervals::Int64 = 1` (with default value `1`) defines the
96+
number of intervals to partition the original interval of integration
9797
`[a, b]` into, splitting it into `[xⱼ, xⱼ₊₁]` for `j = 1,…,subintervals`,
98-
where `xⱼ = a + (j-1)h` and `h = (b-a)/subintervals`. Gauss-Legendre
99-
quadrature is then applied on each subinterval. For example, if
100-
`[a, b] = [-1, 1]` and `subintervals = 2`, then Gauss-Legendre
98+
where `xⱼ = a + (j-1)h` and `h = (b-a)/subintervals`. Gauss-Legendre
99+
quadrature is then applied on each subinterval. For example, if
100+
`[a, b] = [-1, 1]` and `subintervals = 2`, then Gauss-Legendre
101101
quadrature will be applied separately on `[-1, 0]` and `[0, 1]`,
102102
summing the two results.
103103
"""

src/infinity_handling.jl

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,46 @@ function substitute_f_vector(t, p, f, lb, ub)
4949
end
5050
f(x, p) * prod(jac_diag)
5151
end
52+
function substitute_f_vector_iip(dt, t, p, f, lb, ub)
53+
x = similar(t)
54+
jac_diag = similar(t)
55+
for i in eachindex(lb)
56+
if isinf(lb[i]) && isinf(ub[i])
57+
x[i] = t[i] / (1 - t[i]^2)
58+
jac_diag[i] = (1 + t[i]^2) / (1 - t[i]^2)^2
59+
elseif isinf(lb[i])
60+
x[i] = ub[i] + (t[i] / (1 + t[i]))
61+
jac_diag[i] = 1 / ((1 + t[i])^2)
62+
elseif isinf(ub[i])
63+
x[i] = lb[i] + (t[i] / (1 - t[i]))
64+
jac_diag[i] = 1 / ((1 - t[i])^2)
65+
else
66+
x[i] = t[i]
67+
jac_diag[i] = one(lb[i])
68+
end
69+
end
70+
f(dt, x, p)
71+
dt .*= prod(jac_diag)
72+
end
73+
5274
function transformation_if_inf(prob, ::Val{true})
5375
lb = prob.lb
5476
ub = prob.ub
5577
f = prob.f
5678
if lb isa Number
5779
lb_sub, ub_sub = substitute_bounds(lb, ub)
5880
f_sub = (t, p) -> substitute_f_scalar(t, p, f, lb, ub)
59-
return remake(prob, f = f_sub, lb = lb_sub, ub = ub_sub)
6081
else
6182
bounds = substitute_bounds.(lb, ub)
6283
lb_sub = first.(bounds)
6384
ub_sub = last.(bounds)
64-
f_sub = (t, p) -> substitute_f_vector(t, p, f, lb, ub)
65-
return remake(prob, f = f_sub, lb = lb_sub, ub = ub_sub)
85+
if isinplace(prob)
86+
f_sub = (dt, t, p) -> substitute_f_vector_iip(dt, t, p, f, lb, ub)
87+
else
88+
f_sub = (t, p) -> substitute_f_vector(t, p, f, lb, ub)
89+
end
6690
end
91+
return remake(prob, f = f_sub, lb = lb_sub, ub = ub_sub)
6792
end
6893

6994
function transformation_if_inf(prob, ::Nothing)

test/inf_integral_tests.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ sol = solve(prob, HCubatureJL(), reltol = 1e-3, abstol = 1e-3)
1818
@test (0.500 - sol.u)^2 < 1e-6
1919
@test_nowarn @inferred Integrals.transformation_if_inf(prob, Val(true))
2020

21+
μ = [0.00, 0.00]
22+
Σ = [0.4 0.0; 0.00 0.4]
23+
d = MvNormal(μ, Σ)
24+
m_iip(dx, x, p) = dx .= pdf(d, x)
25+
prob = IntegralProblem(m_iip, [-Inf, 0.00], [Inf, Inf])
26+
sol = solve(prob, HCubatureJL(), reltol = 1e-3, abstol = 1e-3)
27+
@test (0.500 - sol.u[1])^2 < 1e-6
28+
2129
f(x, p) = pdf(Normal(0.00, 1.00), x)
2230
prob = IntegralProblem(f, -Inf, Inf)
2331
sol = solve(prob, HCubatureJL(), reltol = 1e-3, abstol = 1e-3)

0 commit comments

Comments
 (0)