From 384d957c5a8d033e4c960c5549cfa62ebe1ebbd2 Mon Sep 17 00:00:00 2001 From: Orjan Ameye Date: Fri, 1 May 2026 16:56:03 +0200 Subject: [PATCH 1/5] fix: use public api in `diffusion_function` --- CHANGELOG.md | 5 +++++ Project.toml | 2 +- docs/src/CoupledSDEs.md | 4 ++++ ext/src/classification.jl | 3 ++- test/stochastic.jl | 5 ++++- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c77518ac..23806403 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v3.16 + +- Support StochasticDiffEq v6.96+, where the diffusion function is no longer reachable via `integrator.g`. The extension now reads it from the `SDEProblem` (`prob.g`), which is a stable SciMLBase accessor that works across both old and new StochasticDiffEq versions. +- Run the multiplicative and non-diagonal noise examples on the `CoupledSDEs` docs page so they actually integrate a trajectory. + # v3.15 - New function `named_variables(ds)` for getting the variable names of an MTK-generated dynamical system. diff --git a/Project.toml b/Project.toml index a65de88c..91add9c3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DynamicalSystemsBase" uuid = "6e36e845-645a-534a-86f2-f5d4aa5a06b4" repo = "https://github.com/JuliaDynamics/DynamicalSystemsBase.jl.git" -version = "3.15.6" +version = "3.16.0" [deps] ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" diff --git a/docs/src/CoupledSDEs.md b/docs/src/CoupledSDEs.md index add9f3ce..355f38b0 100644 --- a/docs/src/CoupledSDEs.md +++ b/docs/src/CoupledSDEs.md @@ -84,6 +84,8 @@ function g!(du, u, p, t) return nothing end sde = CoupledSDEs(f!, rand(2)./10; g=g!) +tr = trajectory(sde, 1.0) +plot_trajectory(tr...) ``` #### Non-diagonal noise @@ -105,6 +107,8 @@ function g!(du, u, p, t) end diffeq = (alg = RKMilCommute(), reltol = 1e-3, abstol = 1e-3, dt=0.1) sde = CoupledSDEs(f!, rand(2)./10; g=g!, noise_prototype = zeros(2, 2), diffeq = diffeq) +tr = trajectory(sde, 1.0) +plot_trajectory(tr...) ``` !!! warning diff --git a/ext/src/classification.jl b/ext/src/classification.jl index 252aa294..9b4d54b3 100644 --- a/ext/src/classification.jl +++ b/ext/src/classification.jl @@ -50,7 +50,8 @@ function diffusion_function(g, IIP, noise_prototype) end function diffusion_function(ds::CoupledSDEs{IIP}) where {IIP} - return diffusion_function(ds.integ.g, IIP, referrenced_sciml_prob(ds).noise_rate_prototype) + prob = referrenced_sciml_prob(ds) + return diffusion_function(prob.g, IIP, prob.noise_rate_prototype) end """ diff --git a/test/stochastic.jl b/test/stochastic.jl index b48172f6..c1795aed 100644 --- a/test/stochastic.jl +++ b/test/stochastic.jl @@ -104,7 +104,10 @@ end corr = CoupledSDEs(f, zeros(2); covariance = [1 0.3; 0.3 1]) corr_alt = CoupledSDEs(f, zeros(2); g = g, noise_prototype = zeros(2, 2)) @test corr.noise_type == corr_alt.noise_type - @test all(corr.integ.g(zeros(2), (), 0.0) .== corr_alt.integ.g(zeros(2), (), 0.0)) + @test all( + DynamicalSystemsBase.referrenced_sciml_prob(corr).g(zeros(2), (), 0.0) .== + DynamicalSystemsBase.referrenced_sciml_prob(corr_alt).g(zeros(2), (), 0.0) + ) end @testset "ArgumentError" begin From f277c290152e4a13403711ce40e9aa86916422c5 Mon Sep 17 00:00:00 2001 From: Orjan Ameye Date: Fri, 1 May 2026 17:01:17 +0200 Subject: [PATCH 2/5] format --- test/stochastic.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/stochastic.jl b/test/stochastic.jl index c1795aed..91c5ea59 100644 --- a/test/stochastic.jl +++ b/test/stochastic.jl @@ -106,7 +106,7 @@ end @test corr.noise_type == corr_alt.noise_type @test all( DynamicalSystemsBase.referrenced_sciml_prob(corr).g(zeros(2), (), 0.0) .== - DynamicalSystemsBase.referrenced_sciml_prob(corr_alt).g(zeros(2), (), 0.0) + DynamicalSystemsBase.referrenced_sciml_prob(corr_alt).g(zeros(2), (), 0.0) ) end From 63152a06199e585a3e161880389d97d5ec1215ab Mon Sep 17 00:00:00 2001 From: Orjan Ameye Date: Fri, 1 May 2026 17:41:37 +0200 Subject: [PATCH 3/5] fix: CI failures from SciML upstream API changes - CoupledSDEs: pin `dtmin = 0.0` so the open-ended tspan (0, 1e11) does not produce a too-coarse SciML default `dtmin` (~1.5e-5) that aborts the SOSRA adaptive controller with `DtLessThanMin`. - Tests: update verbose checks from `verbose == false` (Bool) to inspecting the new `DEVerbosity.linear_verbosity` struct field. - Tests: pass `prob.p` (MTKParameters) to the MTK-generated Jacobian instead of `[]`, which now triggers a BoundsError; switch to the non-deprecated `@brownians`/`@mtkcompile` macros. --- ext/src/CoupledSDEs.jl | 4 ++++ test/continuous.jl | 3 ++- test/jacobian.jl | 8 ++++---- test/stochastic.jl | 5 +++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ext/src/CoupledSDEs.jl b/ext/src/CoupledSDEs.jl index 1e4aca21..12a6fb33 100644 --- a/ext/src/CoupledSDEs.jl +++ b/ext/src/CoupledSDEs.jl @@ -85,6 +85,10 @@ function DynamicalSystemsBase.CoupledSDEs( end solver, remaining = _decompose_into_sde_solver_and_remaining(diffeq) + # The default `dtmin` from SciML scales with `tspan`. With our open-ended + # `tspan = (0, 1e11)` it becomes ~1e-5, which is too coarse for the SDE + # adaptive controller and causes spurious `DtLessThanMin` aborts. + remaining = haskey(remaining, :dtmin) ? remaining : merge((dtmin = 0.0,), remaining) integ = __init( prob, solver; diff --git a/test/continuous.jl b/test/continuous.jl index 1249a0d2..846051d6 100644 --- a/test/continuous.jl +++ b/test/continuous.jl @@ -41,6 +41,7 @@ end prob = lorenz_oop.integ.sol.prob ds = CoupledODEs(prob, (alg = Vern9(), abstol = 0.0, reltol = 1.0e-6, verbose = false)) @test ds.integ.alg isa Vern9 - @test ds.integ.opts.verbose == false + # SciML moved from Bool verbose to a `DEVerbosity` struct of per-toggle verbosities. + @test nameof(typeof(ds.integ.opts.verbose.linear_verbosity)) == :None end diff --git a/test/jacobian.jl b/test/jacobian.jl index 831d6634..7daed445 100644 --- a/test/jacobian.jl +++ b/test/jacobian.jl @@ -48,23 +48,23 @@ end jac = jacobian(ds) @test jac isa GeneratedFunctionWrapper - @test jac([1.0, 1.0], [], 0.0) == [-3 0;0 3] + @test jac([1.0, 1.0], prob.p, 0.0) == [-3 0;0 3] @testset "CoupledSDEs" begin # just to check if MTK @brownian does not give any problems using StochasticDiffEq - @brownian β + @brownians β eqs = [ D(u[1]) ~ 3.0 * u[1] + β, D(u[2]) ~ -3.0 * u[2] + β, ] - @mtkbuild sys = System(eqs, t) + @mtkcompile sys = System(eqs, t) prob = SDEProblem(sys, [1.0, 1.0], (0.0, 1.0), jac = true) sde = CoupledSDEs(prob) jac = jacobian(sde) @test jac isa GeneratedFunctionWrapper - @test jac([1.0, 1.0], [], 0.0) == [-3 0; 0 3] + @test jac([1.0, 1.0], prob.p, 0.0) == [-3 0; 0 3] end end diff --git a/test/stochastic.jl b/test/stochastic.jl index 91c5ea59..00d966b0 100644 --- a/test/stochastic.jl +++ b/test/stochastic.jl @@ -73,7 +73,8 @@ end diffeq = (alg = SRA(), abstol = 1.0e-3, reltol = 1.0e-3, verbose = false) ) @test lorenz_SRA.integ.alg isa SRA - @test lorenz_SRA.integ.opts.verbose == false + # SciML moved from Bool verbose to a `DEVerbosity` struct of per-toggle verbosities. + @test nameof(typeof(lorenz_SRA.integ.opts.verbose.linear_verbosity)) == :None # also test SDEproblem creation prob = lorenz_SRA.integ.sol.prob @@ -81,7 +82,7 @@ end ds = CoupledSDEs(prob, (alg = SRA(), abstol = 0.0, reltol = 1.0e-3, verbose = false)) @test ds.integ.alg isa SRA - @test ds.integ.opts.verbose == false + @test nameof(typeof(ds.integ.opts.verbose.linear_verbosity)) == :None @test_throws ArgumentError CoupledSDEs(prob; diffeq = (alg = SRA(),)) From 89247ebc0131d150953db5594ea358249f301afe Mon Sep 17 00:00:00 2001 From: Orjan Ameye Date: Sat, 2 May 2026 07:20:54 +0200 Subject: [PATCH 4/5] fix: dead callback_functions URL in CoupledODEs docstring Replace defunct `docs.juliadiffeq.org` link with the current SciML DiffEqDocs URL so the docs `linkcheck` build stops failing on it. --- src/core_systems/continuous_time_ode.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_systems/continuous_time_ode.jl b/src/core_systems/continuous_time_ode.jl index be39a445..e216109e 100644 --- a/src/core_systems/continuous_time_ode.jl +++ b/src/core_systems/continuous_time_ode.jl @@ -52,7 +52,7 @@ to access the solvers. The default `diffeq` is: $(DynamicalSystemsBase.DEFAULT_DIFFEQ) `diffeq` keywords can also include `callback` for [event handling -](http://docs.juliadiffeq.org/latest/features/callback_functions.html). +](https://docs.sciml.ai/DiffEqDocs/stable/features/callback_functions/). The convenience constructors `CoupledODEs(prob::ODEProblem [, diffeq])` and `CoupledODEs(ds::CoupledODEs [, diffeq])` are also available. From 272d932fe495e112cb85806892b3b69c94e97d2a Mon Sep 17 00:00:00 2001 From: George Datseris Date: Sat, 2 May 2026 15:00:20 +0100 Subject: [PATCH 5/5] Revise CHANGELOG for main version updates Updated changelog for versioning and example integration. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23806403..e3881573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v3.16 +# main - Support StochasticDiffEq v6.96+, where the diffusion function is no longer reachable via `integrator.g`. The extension now reads it from the `SDEProblem` (`prob.g`), which is a stable SciMLBase accessor that works across both old and new StochasticDiffEq versions. - Run the multiplicative and non-diagonal noise examples on the `CoupledSDEs` docs page so they actually integrate a trajectory.