Skip to content

Commit 4d4e20a

Browse files
Merge pull request #189 from lxvm/interface
Migrate to SciMLBase v2
2 parents 56aa374 + 3cf503c commit 4d4e20a

31 files changed

+793
-744
lines changed

.github/workflows/CI.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ jobs:
1919
- Core
2020
version:
2121
- '1'
22-
- '1.6'
2322
steps:
2423
- uses: actions/checkout@v4
2524
- uses: julia-actions/setup-julia@v1
@@ -39,7 +38,7 @@ jobs:
3938
- uses: julia-actions/julia-runtest@v1
4039
- uses: julia-actions/julia-processcoverage@v1
4140
with:
42-
directories: src,ext,lib/IntegralsCuba/src,lib/IntegralsCubature/src
41+
directories: src,ext
4342
- uses: codecov/codecov-action@v3
4443
with:
4544
files: lcov.info

.github/workflows/CompatHelper.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ jobs:
2323
- name: CompatHelper.main()
2424
env:
2525
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26-
run: julia -e 'using CompatHelper; CompatHelper.main(;subdirs=["", "docs", "lib/IntegralsCubature", "lib/IntegralsCuba"])'
26+
run: julia -e 'using CompatHelper; CompatHelper.main(;subdirs=["", "docs"])'

.github/workflows/Documentation.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
run: julia --project=docs/ --code-coverage=user docs/make.jl
2626
- uses: julia-actions/julia-processcoverage@v1
2727
with:
28-
directories: src,lib/IntegralsCuba/src,lib/IntegralsCubature/src
28+
directories: src
2929
- uses: codecov/codecov-action@v3
3030
with:
3131
files: lcov.info

Project.toml

+13-4
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,41 @@ SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
1515

1616
[weakdeps]
1717
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
18+
Cuba = "8a292aeb-7a57-582c-b821-06e4c11590b1"
19+
Cubature = "667455a9-e2ce-5579-9412-b964f529a492"
1820
FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838"
1921
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
2022
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
2123

2224
[extensions]
25+
IntegralsCubaExt = "Cuba"
26+
IntegralsCubatureExt = "Cubature"
2327
IntegralsFastGaussQuadratureExt = "FastGaussQuadrature"
2428
IntegralsForwardDiffExt = "ForwardDiff"
2529
IntegralsZygoteExt = ["Zygote", "ChainRulesCore"]
2630

2731
[compat]
2832
ChainRulesCore = "0.10.7, 1"
2933
CommonSolve = "0.2"
34+
Cuba = "2"
35+
Cubature = "1"
3036
Distributions = "0.23, 0.24, 0.25"
3137
FastGaussQuadrature = "0.5"
3238
ForwardDiff = "0.10"
3339
HCubature = "1.4"
34-
MonteCarloIntegration = "0.0.1, 0.0.2, 0.0.3"
40+
LinearAlgebra = "1.9"
41+
MonteCarloIntegration = "0.0.1, 0.0.2, 0.0.3, 0.1"
3542
QuadGK = "2.5"
3643
Reexport = "0.2, 1.0"
3744
Requires = "1"
38-
SciMLBase = "1.98"
45+
SciMLBase = "2.6"
3946
Zygote = "0.4.22, 0.5, 0.6"
40-
julia = "1.6"
47+
julia = "1.9"
4148

4249
[extras]
4350
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
51+
Cuba = "8a292aeb-7a57-582c-b821-06e4c11590b1"
52+
Cubature = "667455a9-e2ce-5579-9412-b964f529a492"
4453
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
4554
FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838"
4655
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41"
@@ -53,4 +62,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
5362
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
5463

5564
[targets]
56-
test = ["SciMLSensitivity", "StaticArrays", "FiniteDiff", "Pkg", "SafeTestsets", "Test", "Distributions", "ForwardDiff", "Zygote", "ChainRulesCore", "FastGaussQuadrature"]
65+
test = ["SciMLSensitivity", "StaticArrays", "FiniteDiff", "Pkg", "SafeTestsets", "Test", "Distributions", "ForwardDiff", "Zygote", "ChainRulesCore", "FastGaussQuadrature", "Cuba", "Cubature"]

docs/Project.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
[deps]
2+
Cuba = "8a292aeb-7a57-582c-b821-06e4c11590b1"
3+
Cubature = "667455a9-e2ce-5579-9412-b964f529a492"
24
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
35
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
46
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41"
57
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
68
Integrals = "de52edbc-65ea-441a-8357-d3a637375a31"
7-
IntegralsCuba = "e00cd5f1-6337-4131-8b37-28b2fe4cd6cb"
8-
IntegralsCubature = "c31f79ba-6e32-46d4-a52f-182a8ac42a54"
99
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
1010

1111
[compat]
12+
Cuba = "2"
13+
Cubature = "1"
1214
Distributions = "0.25"
1315
Documenter = "1"
1416
FiniteDiff = "2"
1517
ForwardDiff = "0.10"
1618
Integrals = "3"
17-
IntegralsCuba = "0.3"
18-
IntegralsCubature = "0.2"
1919
Zygote = "0.6"

docs/src/solvers/IntegralSolvers.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ The following algorithms are available:
55
- `QuadGKJL`: Uses QuadGK.jl. Requires `nout=1` and `batch=0`, in-place is not allowed.
66
- `HCubatureJL`: Uses HCubature.jl. Requires `batch=0`.
77
- `VEGAS`: Uses MonteCarloIntegration.jl. Requires `nout=1`. Works only for `>1`-dimensional integrations.
8-
- `CubatureJLh`: h-Cubature from Cubature.jl. Requires `using IntegralsCubature`.
9-
- `CubatureJLp`: p-Cubature from Cubature.jl. Requires `using IntegralsCubature`.
10-
- `CubaVegas`: Vegas from Cuba.jl. Requires `using IntegralsCuba`, `nout=1`.
11-
- `CubaSUAVE`: SUAVE from Cuba.jl. Requires `using IntegralsCuba`.
12-
- `CubaDivonne`: Divonne from Cuba.jl. Requires `using IntegralsCuba`. Works only for `>1`-dimensional integrations.
13-
- `CubaCuhre`: Cuhre from Cuba.jl. Requires `using IntegralsCuba`. Works only for `>1`-dimensional integrations.
8+
- `CubatureJLh`: h-Cubature from Cubature.jl. Requires `using Cubature`.
9+
- `CubatureJLp`: p-Cubature from Cubature.jl. Requires `using Cubature`.
10+
- `CubaVegas`: Vegas from Cuba.jl. Requires `using Cuba`, `nout=1`.
11+
- `CubaSUAVE`: SUAVE from Cuba.jl. Requires `using Cuba`.
12+
- `CubaDivonne`: Divonne from Cuba.jl. Requires `using Cuba`. Works only for `>1`-dimensional integrations.
13+
- `CubaCuhre`: Cuhre from Cuba.jl. Requires `using Cuba`. Works only for `>1`-dimensional integrations.
1414
- `GaussLegendre`: Uses Gauss-Legendre quadrature with nodes and weights from FastGaussQuadrature.jl.
1515
- `QuadratureRule`: Accepts a user-defined function that returns nodes and weights.
1616

docs/src/tutorials/differentiating_integrals.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ calls. It integrates with ForwardDiff.jl for forward-mode automatic differentiat
66
and Zygote.jl for reverse-mode automatic differentiation. For example:
77

88
```@example AD
9-
using Integrals, ForwardDiff, FiniteDiff, Zygote, IntegralsCuba
9+
using Integrals, ForwardDiff, FiniteDiff, Zygote, Cuba
1010
f(x, p) = sum(sin.(x .* p))
1111
lb = ones(2)
1212
ub = 3ones(2)

docs/src/tutorials/numerical_integrals.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ This means that a new output vector is created every time the function `f` is ca
5353
If we do not want these allocations, we can also define `f` in-position.
5454

5555
```@example integrate3
56-
using Integrals, IntegralsCubature
56+
using Integrals, Cubature
5757
function f(y, u, p)
5858
y[1] = sum(sin.(u))
5959
y[2] = sum(cos.(u))
@@ -74,7 +74,7 @@ The batch interface allows us to compute multiple points at once.
7474
For example, here we do allocation-free multithreading with Cubature.jl:
7575

7676
```@example integrate4
77-
using Integrals, IntegralsCubature, Base.Threads
77+
using Integrals, Cubature, Base.Threads
7878
function f(y, u, p)
7979
Threads.@threads for i in 1:size(u, 2)
8080
y[1, i] = sum(sin.(@view(u[:, i])))
@@ -97,7 +97,7 @@ the change is a one-argument change:
9797

9898
```@example integrate5
9999
using Integrals
100-
using IntegralsCuba
100+
using Cuba
101101
f(u, p) = sum(sin.(u))
102102
prob = IntegralProblem(f, ones(3), 3ones(3))
103103
sol = solve(prob, CubaCuhre(); reltol = 1e-3, abstol = 1e-3)

ext/IntegralsCubaExt.jl

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
module IntegralsCubaExt
2+
3+
using Integrals, Cuba
4+
import Integrals: transformation_if_inf, scale_x, scale_x!, CubaVegas, AbstractCubaAlgorithm,
5+
CubaSUAVE, CubaDivonne, CubaCuhre
6+
7+
function Integrals.__solvebp_call(prob::IntegralProblem, alg::AbstractCubaAlgorithm,
8+
sensealg,
9+
domain, p;
10+
reltol = 1e-8, abstol = 1e-8,
11+
maxiters = alg isa CubaSUAVE ? 1000000 : typemax(Int))
12+
@assert maxiters>=1000 "maxiters for $alg should be larger than 1000"
13+
lb, ub = domain
14+
mid = (lb + ub) / 2
15+
ndim = length(mid)
16+
(vol = prod(map(-, ub, lb))) isa Real ||
17+
throw(ArgumentError("Cuba.jl only supports real-valued integrands"))
18+
# we could support other types by multiplying by the jacobian determinant at the end
19+
20+
if prob.f isa BatchIntegralFunction
21+
# nvec == 1 in Cuba will change vectors to matrices, so we won't support it when
22+
# batching
23+
(nvec = prob.f.max_batch) > 1 ||
24+
throw(ArgumentError("BatchIntegralFunction must take multiple batch points"))
25+
26+
if mid isa Real
27+
_x = zeros(typeof(mid), prob.f.max_batch)
28+
scale = x -> scale_x!(resize!(_x, length(x)), ub, lb, vec(x))
29+
else
30+
_x = zeros(eltype(mid), length(mid), prob.f.max_batch)
31+
scale = x -> scale_x!(view(_x, :, 1:size(x, 2)), ub, lb, x)
32+
end
33+
34+
if isinplace(prob)
35+
fsize = size(prob.f.integrand_prototype)[begin:(end - 1)]
36+
y = similar(prob.f.integrand_prototype, fsize..., nvec)
37+
ax = map(_ -> (:), fsize)
38+
f = function (x, dx)
39+
dy = @view(y[ax..., begin:(begin + size(dx, 2) - 1)])
40+
prob.f(dy, scale(x), p)
41+
dx .= reshape(dy, :, size(dx, 2)) .* vol
42+
end
43+
else
44+
y = mid isa Number ? prob.f(typeof(mid)[], p) :
45+
prob.f(Matrix{typeof(mid)}(undef, length(mid), 0), p)
46+
fsize = size(y)[begin:(end - 1)]
47+
f = (x, dx) -> dx .= reshape(prob.f(scale(x), p), :, size(dx, 2)) .* vol
48+
end
49+
ncomp = prod(fsize)
50+
else
51+
nvec = 1
52+
53+
if mid isa Real
54+
scale = x -> scale_x(ub, lb, only(x))
55+
else
56+
_x = zeros(eltype(mid), length(mid))
57+
scale = x -> scale_x!(_x, ub, lb, x)
58+
end
59+
60+
if isinplace(prob)
61+
y = similar(prob.f.integrand_prototype)
62+
f = (x, dx) -> dx .= vec(prob.f(y, scale(x), p)) .* vol
63+
else
64+
y = prob.f(mid, p)
65+
f = (x, dx) -> dx .= Iterators.flatten(prob.f(scale(x), p)) .* vol
66+
end
67+
ncomp = length(y)
68+
end
69+
70+
if alg isa CubaVegas
71+
out = Cuba.vegas(f, ndim, ncomp; rtol = reltol,
72+
atol = abstol, nvec = nvec,
73+
maxevals = maxiters,
74+
flags = alg.flags, seed = alg.seed, minevals = alg.minevals,
75+
nstart = alg.nstart, nincrease = alg.nincrease,
76+
gridno = alg.gridno)
77+
elseif alg isa CubaSUAVE
78+
out = Cuba.suave(f, ndim, ncomp; rtol = reltol,
79+
atol = abstol, nvec = nvec,
80+
maxevals = maxiters,
81+
flags = alg.flags, seed = alg.seed, minevals = alg.minevals,
82+
nnew = alg.nnew, nmin = alg.nmin, flatness = alg.flatness)
83+
elseif alg isa CubaDivonne
84+
out = Cuba.divonne(f, ndim, ncomp; rtol = reltol,
85+
atol = abstol, nvec = nvec,
86+
maxevals = maxiters,
87+
flags = alg.flags, seed = alg.seed, minevals = alg.minevals,
88+
key1 = alg.key1, key2 = alg.key2, key3 = alg.key3,
89+
maxpass = alg.maxpass, border = alg.border,
90+
maxchisq = alg.maxchisq, mindeviation = alg.mindeviation)
91+
elseif alg isa CubaCuhre
92+
out = Cuba.cuhre(f, ndim, ncomp; rtol = reltol,
93+
atol = abstol, nvec = nvec,
94+
maxevals = maxiters,
95+
flags = alg.flags, minevals = alg.minevals, key = alg.key)
96+
end
97+
98+
# out.integral is a Vector{Float64}, but we want to return it to the shape of the integrand
99+
if prob.f isa BatchIntegralFunction
100+
if y isa AbstractVector
101+
val = out.integral[1]
102+
else
103+
val = reshape(out.integral, fsize)
104+
end
105+
else
106+
if y isa Real
107+
val = out.integral[1]
108+
elseif y isa AbstractVector
109+
val = out.integral
110+
else
111+
val = reshape(out.integral, size(y))
112+
end
113+
end
114+
115+
SciMLBase.build_solution(prob, alg, val, out.error,
116+
chi = out.probability, retcode = ReturnCode.Success)
117+
end
118+
119+
end

0 commit comments

Comments
 (0)