diff --git a/docs/Project.toml b/docs/Project.toml index 3a71e3d4024..cba35ff7645 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -35,6 +35,7 @@ OrdinaryDiffEqStabilizedRK = "358294b1-0aab-51c3-aafe-ad5ab194a2ad" OrdinaryDiffEqSymplecticRK = "fa646aed-7ef9-47eb-84c4-9443fc8cbfa8" OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a" OrdinaryDiffEqVerner = "79d7bb75-1356-48c1-b8c0-6832512096c2" +StochasticDiffEqLevyArea = "90dbc90e-856a-4131-af2c-e8c5aa0f35b5" [sources] DiffEqBase = {path = "../lib/DiffEqBase"} @@ -71,6 +72,7 @@ OrdinaryDiffEqStabilizedRK = {path = "../lib/OrdinaryDiffEqStabilizedRK"} OrdinaryDiffEqSymplecticRK = {path = "../lib/OrdinaryDiffEqSymplecticRK"} OrdinaryDiffEqTsit5 = {path = "../lib/OrdinaryDiffEqTsit5"} OrdinaryDiffEqVerner = {path = "../lib/OrdinaryDiffEqVerner"} +StochasticDiffEqLevyArea = {path = "../lib/StochasticDiffEqLevyArea"} [compat] DiffEqBase = "7.6.1" @@ -109,3 +111,4 @@ OrdinaryDiffEqStabilizedRK = "2.0.0" OrdinaryDiffEqSymplecticRK = "2.0.0" OrdinaryDiffEqTsit5 = "2.0.0" OrdinaryDiffEqVerner = "2.0.0" +StochasticDiffEqLevyArea = "2" diff --git a/docs/make.jl b/docs/make.jl index d38efdd47de..e859438280f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -8,6 +8,7 @@ using OrdinaryDiffEqCore: default_controller, resolve_basic, get_EEst, set_EEst!, CompositeController using OrdinaryDiffEqNonlinearSolve using ImplicitDiscreteSolve +using StochasticDiffEqLevyArea using OrdinaryDiffEqAMF using OrdinaryDiffEqAdamsBashforthMoulton using OrdinaryDiffEqBDF @@ -82,6 +83,7 @@ makedocs( OrdinaryDiffEqVerner, OrdinaryDiffEqAMF, ImplicitDiscreteSolve, + StochasticDiffEqLevyArea, DiffEqDevTools, ], linkcheck_ignore = [r"https://github.com/JuliaDiff/ForwardDiff.jl"], diff --git a/docs/pages.jl b/docs/pages.jl index 59530779167..e829ba0f876 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -47,6 +47,9 @@ pages = [ "massmatrixdae/Rosenbrock.md", "massmatrixdae/BDF.md", ], + "Stochastic Utilities" => [ + "stochastic/LevyArea.md", + ], "Fully Implicit DAE Solvers" => [ "fullyimplicitdae/BDF.md", ], diff --git a/docs/src/stochastic/LevyArea.md b/docs/src/stochastic/LevyArea.md new file mode 100644 index 00000000000..a22feadcafb --- /dev/null +++ b/docs/src/stochastic/LevyArea.md @@ -0,0 +1,38 @@ +# Lévy Area and Iterated Stochastic Integrals + +`StochasticDiffEqLevyArea` provides Fourier-series approximations of Lévy areas +and iterated stochastic integrals. It supports direct random sampling, +pre-generated coefficients for deterministic reuse, and Brownian-path +reconstruction within a time step. + +## Algorithms + +```@docs +StochasticDiffEqLevyArea.AbstractIteratedIntegralAlgorithm +StochasticDiffEqLevyArea.Fourier +StochasticDiffEqLevyArea.Milstein +StochasticDiffEqLevyArea.Wiktorsson +StochasticDiffEqLevyArea.MronRoe +``` + +## Error norms + +```@docs +StochasticDiffEqLevyArea.AbstractErrorNorm +StochasticDiffEqLevyArea.MaxL2 +StochasticDiffEqLevyArea.FrobeniusL2 +``` + +## Coefficients and iterated integrals + +```@docs +StochasticDiffEqLevyArea.LevyAreaCoefficients +StochasticDiffEqLevyArea.coefficient_length +StochasticDiffEqLevyArea.generate_coefficients +StochasticDiffEqLevyArea.levyarea +StochasticDiffEqLevyArea.terms_needed +StochasticDiffEqLevyArea.optimal_algorithm +StochasticDiffEqLevyArea.iterated_integrals +StochasticDiffEqLevyArea.reconstruct_path +StochasticDiffEqLevyArea.iterated_integrals_subinterval +``` diff --git a/lib/StochasticDiffEqLevyArea/src/error_norms.jl b/lib/StochasticDiffEqLevyArea/src/error_norms.jl index da0dd746ed9..4c21cb8e9fb 100644 --- a/lib/StochasticDiffEqLevyArea/src/error_norms.jl +++ b/lib/StochasticDiffEqLevyArea/src/error_norms.jl @@ -35,5 +35,19 @@ function errcoeff(m, q_12, stepsize, alg::AbstractIteratedIntegralAlgorithm, ::L return 1 / (2^(1 / p)) * errcoeff(m, q_12, stepsize, alg, SchattenqLp{p, p}()) end +""" + MaxL2 + +Error-norm type that takes the maximum of the entrywise ``L^2`` norms of an +iterated-integral approximation. Construct an instance with `MaxL2()`. +""" const MaxL2 = MaxLp{2} + +""" + FrobeniusL2 + +Error-norm type that takes the Frobenius norm of the entrywise ``L^2`` norms +of an iterated-integral approximation. Construct an instance with +`FrobeniusL2()`. +""" const FrobeniusL2 = SchattenqLp{2, 2} diff --git a/lib/StochasticDiffEqLevyArea/src/fourier.jl b/lib/StochasticDiffEqLevyArea/src/fourier.jl index dd0d01479d5..c7a7149c8b5 100644 --- a/lib/StochasticDiffEqLevyArea/src/fourier.jl +++ b/lib/StochasticDiffEqLevyArea/src/fourier.jl @@ -1,9 +1,27 @@ +""" + Fourier() + +Basic Fourier-series approximation of Lévy areas. Its truncation error has +convergence order ``1/2`` in the number of retained Fourier terms. +""" struct Fourier <: AbstractIteratedIntegralAlgorithm end convorder(::Fourier) = 1 // 2 errcoeff(m, h, ::Fourier, ::MaxLp{2}) = h * √3 / (√2 * π) norv(m, n, ::Fourier) = 2 * m * n +""" + levyarea(W, n, alg; rng=default_rng()) + levyarea(W, n, alg, coeffs) + +Approximate the antisymmetric Lévy-area matrix for the normalized Wiener +increment `W` using `n` Fourier terms and algorithm `alg`. + +The keyword form draws the required random coefficients from `rng`. Passing +pre-generated [`LevyAreaCoefficients`](@ref) makes the computation +deterministic. Use [`iterated_integrals`](@ref) to obtain the complete matrix +of iterated integrals over a time step of length `h`. +""" function levyarea( W::AbstractVector{T}, n::Integer, alg::Fourier; rng::AbstractRNG = default_rng() diff --git a/lib/StochasticDiffEqLevyArea/src/milstein.jl b/lib/StochasticDiffEqLevyArea/src/milstein.jl index 873eeb5697b..db209038ad7 100644 --- a/lib/StochasticDiffEqLevyArea/src/milstein.jl +++ b/lib/StochasticDiffEqLevyArea/src/milstein.jl @@ -1,3 +1,10 @@ +""" + Milstein() + +Fourier-series Lévy-area approximation with Milstein's Gaussian tail +approximation. Its truncation error has convergence order ``1/2`` in the +number of retained Fourier terms. +""" struct Milstein <: AbstractIteratedIntegralAlgorithm end convorder(::Milstein) = 1 // 2 diff --git a/lib/StochasticDiffEqLevyArea/src/mronroe.jl b/lib/StochasticDiffEqLevyArea/src/mronroe.jl index e45fafcb652..aec6ce77b23 100644 --- a/lib/StochasticDiffEqLevyArea/src/mronroe.jl +++ b/lib/StochasticDiffEqLevyArea/src/mronroe.jl @@ -1,3 +1,10 @@ +""" + MronRoe() + +Mrongowius--Rößler Fourier-series Lévy-area approximation with an improved +tail-sum correction. Its truncation error has convergence order ``1`` in the +number of retained Fourier terms. +""" struct MronRoe <: AbstractIteratedIntegralAlgorithm end convorder(::MronRoe) = 1 // 1 diff --git a/lib/StochasticDiffEqLevyArea/src/wiktorsson.jl b/lib/StochasticDiffEqLevyArea/src/wiktorsson.jl index 31dbb61210a..852b33c3525 100644 --- a/lib/StochasticDiffEqLevyArea/src/wiktorsson.jl +++ b/lib/StochasticDiffEqLevyArea/src/wiktorsson.jl @@ -1,3 +1,10 @@ +""" + Wiktorsson() + +Wiktorsson's Fourier-series Lévy-area approximation with a Gaussian tail-sum +correction. Its truncation error has convergence order ``1`` in the number of +retained Fourier terms. +""" struct Wiktorsson <: AbstractIteratedIntegralAlgorithm end convorder(::Wiktorsson) = 1 // 1