Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ LinearAlgebra = "1.10"
MCIntegration = "0.4.2"
MonteCarloIntegration = "0.2"
Mooncake = "0.5.6"
Pkg = "1.10"
QuadGK = "2.11"
Random = "1.10"
Reexport = "1.2"
Expand All @@ -87,11 +88,12 @@ FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838"
FastTanhSinhQuadrature = "b650e0df-f744-4436-b963-b44034668c57"
HAdaptiveIntegration = "eaa5ad34-b243-48e9-b09c-54bc0655cecf"
MCIntegration = "ea1e2de9-7db7-4b42-91ee-0cd1bf6df167"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[targets]
test = ["ADTypes", "Arblib", "StaticArrays", "SafeTestsets", "SciMLTesting", "Test", "Distributions", "ChainRulesCore", "FastGaussQuadrature", "FastTanhSinhQuadrature", "Cuba", "Cubature", "MCIntegration", "DifferentiationInterface", "HAdaptiveIntegration", "Unitful"]
test = ["ADTypes", "Arblib", "StaticArrays", "SafeTestsets", "SciMLTesting", "Test", "Distributions", "ChainRulesCore", "FastGaussQuadrature", "FastTanhSinhQuadrature", "Cuba", "Cubature", "MCIntegration", "DifferentiationInterface", "HAdaptiveIntegration", "Pkg", "Unitful"]
3 changes: 3 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
Integrals = "de52edbc-65ea-441a-8357-d3a637375a31"
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"

[sources]
Integrals = {path = ".."}

[compat]
Cuba = "2"
Cubature = "1"
Expand Down
11 changes: 11 additions & 0 deletions docs/src/basics/solve.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,14 @@
```@docs
solve(prob::IntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm)
```

## Related SciML interface utilities

```@docs
init(prob::IntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm)
init(prob::SampledIntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm)
solve!(cache::Integrals.IntegralCache)
solve!(cache::Integrals.SampledIntegralCache)
isinplace(cache::Integrals.IntegralCache)
ReturnCode
```
145 changes: 145 additions & 0 deletions src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,71 @@ mutable struct IntegralCache{iip, F, D, P, PK, A, S, K, Tc, VT}
verbosity::VT
end

"""
isinplace(cache::IntegralCache) -> Bool

Return whether an initialized integral cache wraps an in-place integrand.

## Arguments

- `cache`: Cache returned by [`init`](@ref) for an `IntegralProblem`.

## Returns

Returns `true` when the cached integral function mutates its output argument, and
`false` otherwise.

## Example

```julia
using Integrals

prob = IntegralProblem((x, p) -> x^2, (0.0, 1.0))
cache = init(prob, QuadGKJL())
isinplace(cache)
```
"""
SciMLBase.isinplace(::IntegralCache{iip}) where {iip} = iip

init_cacheval(::SciMLBase.AbstractIntegralAlgorithm, args...) = nothing

"""
init(prob::IntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm; kwargs...)

Initialize a reusable integral solver cache for `prob` and `alg`.

## Arguments

- `prob`: Integral problem containing the integrand, domain, parameters, and problem
keyword options.
- `alg`: Integration algorithm, such as `QuadGKJL()`, `HCubatureJL()`, or another
subtype of `SciMLBase.AbstractIntegralAlgorithm`.

## Keyword Arguments

- `sensealg`: Sensitivity algorithm used by automatic differentiation paths. Defaults to
`ReCallVJP(ZygoteVJP())`.
- `verbose`: Verbosity control via [`IntegralVerbosity`](@ref). Defaults to
`IntegralVerbosity()`.
- `do_inf_transformation`: Deprecated. Infinite-domain transformations are always
applied when needed.
- Additional keyword arguments are forwarded to the eventual solve.

## Returns

Returns an internal cache object that stores the transformed algorithm, cached backend
state, verbosity settings, and solve keyword arguments for reuse with [`solve!`](@ref).

## Example

```julia
using Integrals

prob = IntegralProblem((x, p) -> sin(x), (0.0, pi))
cache = init(prob, QuadGKJL(); reltol = 1e-10)
solve!(cache)
```
"""
function SciMLBase.init(
prob::IntegralProblem{iip},
alg::SciMLBase.AbstractIntegralAlgorithm;
Expand Down Expand Up @@ -160,6 +221,30 @@ function SciMLBase.solve(
return solve!(init(prob, alg; kwargs...))
end

"""
solve!(cache::IntegralCache)

Solve an initialized integral cache.

## Arguments

- `cache`: Cache returned by [`init`](@ref) for an `IntegralProblem`.

## Returns

Returns a SciMLBase integral solution whose `u` field is the integral estimate and whose
`resid` field is the backend residual or error estimate when available.

## Example

```julia
using Integrals

prob = IntegralProblem((x, p) -> x^2, (0.0, 1.0))
cache = init(prob, QuadGKJL())
sol = solve!(cache)
```
"""
function SciMLBase.solve!(cache::IntegralCache)
return __solve(
cache, cache.alg, cache.sensealg, cache.domain, cache.p;
Expand Down Expand Up @@ -195,6 +280,42 @@ function Base.setproperty!(cache::SampledIntegralCache, name::Symbol, x)
return setfield!(cache, name, x)
end

"""
init(prob::SampledIntegralProblem, alg::SciMLBase.AbstractIntegralAlgorithm; kwargs...)

Initialize a reusable sampled-data integral solver cache.

## Arguments

- `prob`: Sampled integral problem containing sampled values, sampling points, and the
integration dimension.
- `alg`: Sampled-data integration algorithm, such as `TrapezoidalRule()` or
`SimpsonsRule()`.

## Keyword Arguments

- `verbose`: Verbosity control via [`IntegralVerbosity`](@ref). Defaults to
`IntegralVerbosity()`.

No other keyword arguments are accepted by this cache initializer.

## Returns

Returns an internal cache object that can be reused with [`solve!`](@ref). Updating the
sample locations marks the cached weights stale so they are recomputed before the next
solve.

## Example

```julia
using Integrals

x = range(0, 1, length = 21)
prob = SampledIntegralProblem(x .^ 2, x)
cache = init(prob, SimpsonsRule())
solve!(cache)
```
"""
function SciMLBase.init(
prob::SampledIntegralProblem,
alg::SciMLBase.AbstractIntegralAlgorithm;
Expand Down Expand Up @@ -260,6 +381,30 @@ function SciMLBase.solve(
return solve!(init(prob, alg; kwargs...))
end

"""
solve!(cache::SampledIntegralCache)

Solve an initialized sampled-data integral cache.

## Arguments

- `cache`: Cache returned by [`init`](@ref) for a `SampledIntegralProblem`.

## Returns

Returns a SciMLBase integral solution whose `u` field is the sampled integral estimate.

## Example

```julia
using Integrals

x = range(0, 1, length = 21)
prob = SampledIntegralProblem(x .^ 2, x)
cache = init(prob, TrapezoidalRule())
sol = solve!(cache)
```
"""
function SciMLBase.solve!(cache::SampledIntegralCache)
return __solvebp(cache, cache.alg; cache.kwargs...)
end
Expand Down
2 changes: 1 addition & 1 deletion test/qa/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ Aqua = "0.8"
Integrals = "5"
JET = "0.9, 0.10, 0.11.3"
SafeTestsets = "0.1, 1"
SciMLTesting = "1.7"
SciMLTesting = "2.1"
Test = "1.10"
julia = "1.10"
46 changes: 0 additions & 46 deletions test/qa/public_api_docs.jl

This file was deleted.

3 changes: 2 additions & 1 deletion test/qa/qa.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using SciMLTesting, Integrals, Test
using JET

include("public_api_docs.jl")
const UPSTREAM_RENDERED_API = (:SciMLBase, :remake)

run_qa(
Integrals;
explicit_imports = true,
api_docs_kwargs = (; rendered = true, rendered_ignore = UPSTREAM_RENDERED_API),
aqua_kwargs = (;
# IntegralProblem / SampledIntegralProblem are SciMLBase types this package
# owns the integral-solver methods for, so dispatching on them is not piracy.
Expand Down
6 changes: 6 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
if get(ENV, "GROUP", "All") == "QA"
import Pkg
Pkg.activate(joinpath(@__DIR__, "qa"))
Pkg.instantiate()
end

using SciMLTesting
run_tests()
Loading