From f1684ebd2050af1120731b577468f67f7b1e7fcf Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 01:38:12 -0400 Subject: [PATCH 1/9] Better error throwing on ill-formed SDESystems Throws a better error for https://github.com/SciML/ModelingToolkit.jl/issues/2829 --- .github/workflows/Downstream.yml | 2 +- src/systems/diffeqs/sdesystem.jl | 4 ++++ test/sdesystem.jl | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Downstream.yml b/.github/workflows/Downstream.yml index f5ae4b1df3..7a7556efa3 100644 --- a/.github/workflows/Downstream.yml +++ b/.github/workflows/Downstream.yml @@ -32,7 +32,7 @@ jobs: - {user: SciML, repo: NeuralPDE.jl, group: NNPDE} - {user: SciML, repo: DataDrivenDiffEq.jl, group: Downstream} - {user: SciML, repo: StructuralIdentifiability.jl, group: All} - - {user: SciML, repo: ModelingToolkitStandardLibrary.jl} + - {user: SciML, repo: ModelingToolkitStandardLibrary.jl, group: Core} - {user: SciML, repo: ModelOrderReduction.jl, group: All} - {user: SciML, repo: MethodOfLines.jl, group: Interface} - {user: SciML, repo: MethodOfLines.jl, group: 2D_Diffusion} diff --git a/src/systems/diffeqs/sdesystem.jl b/src/systems/diffeqs/sdesystem.jl index 223f1b3c0a..9e5d4224f3 100644 --- a/src/systems/diffeqs/sdesystem.jl +++ b/src/systems/diffeqs/sdesystem.jl @@ -140,6 +140,10 @@ struct SDESystem <: AbstractODESystem check_variables(dvs, iv) check_parameters(ps, iv) check_equations(deqs, iv) + check_equations(neqs, dvs) + if size(neqs,1) != length(dvs) + throw(ArgumentError("Noise equations ill-formed. Number of rows must match number of states. size(neqs,1) = $(size(neqs,1)) != length(dvs) = $(length(dvs))")) + end check_equations(equations(cevents), iv) end if checks == true || (checks & CheckUnits) > 0 diff --git a/test/sdesystem.jl b/test/sdesystem.jl index b18ab648e7..2678b9fb21 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -614,3 +614,15 @@ sys2 = complete(sys2) prob = SDEProblem(sys1, sts .=> [1.0, 0.0, 0.0], (0.0, 100.0), ps .=> (10.0, 26.0)) solve(prob, LambaEulerHeun(), seed = 1) + +# Test ill-formed due to more equations than states in noise equations + +@parameters p d +@variables t X(t) +D = Differential(t) +eqs = [D(X) ~ p - d*X] +noise_eqs = [sqrt(p), -sqrt(d*X)] +@test_throws ArgumentError ssys = SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) + +noise_eqs = reshape([sqrt(p), -sqrt(d*X)],1,2) +ssys = SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) From fc321da33684813a250acbb217d3e7cfc5f55b7c Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 01:46:23 -0400 Subject: [PATCH 2/9] format --- src/systems/diffeqs/sdesystem.jl | 2 +- test/sdesystem.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/systems/diffeqs/sdesystem.jl b/src/systems/diffeqs/sdesystem.jl index 9e5d4224f3..7eab3dcb1c 100644 --- a/src/systems/diffeqs/sdesystem.jl +++ b/src/systems/diffeqs/sdesystem.jl @@ -141,7 +141,7 @@ struct SDESystem <: AbstractODESystem check_parameters(ps, iv) check_equations(deqs, iv) check_equations(neqs, dvs) - if size(neqs,1) != length(dvs) + if size(neqs, 1) != length(dvs) throw(ArgumentError("Noise equations ill-formed. Number of rows must match number of states. size(neqs,1) = $(size(neqs,1)) != length(dvs) = $(length(dvs))")) end check_equations(equations(cevents), iv) diff --git a/test/sdesystem.jl b/test/sdesystem.jl index 2678b9fb21..14bfe4198a 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -620,9 +620,9 @@ solve(prob, LambaEulerHeun(), seed = 1) @parameters p d @variables t X(t) D = Differential(t) -eqs = [D(X) ~ p - d*X] -noise_eqs = [sqrt(p), -sqrt(d*X)] -@test_throws ArgumentError ssys = SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) +eqs = [D(X) ~ p - d * X] +noise_eqs = [sqrt(p), -sqrt(d * X)] +@test_throws ArgumentError ssys=SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) -noise_eqs = reshape([sqrt(p), -sqrt(d*X)],1,2) +noise_eqs = reshape([sqrt(p), -sqrt(d * X)], 1, 2) ssys = SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) From 6ae1c2b476d1372b0b4fe5a5863f634b5c4f5b25 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 04:11:51 -0400 Subject: [PATCH 3/9] fix tests --- test/sdesystem.jl | 3 +-- test/symbolic_events.jl | 16 ++++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/test/sdesystem.jl b/test/sdesystem.jl index 14bfe4198a..30f92e039c 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -619,10 +619,9 @@ solve(prob, LambaEulerHeun(), seed = 1) @parameters p d @variables t X(t) -D = Differential(t) eqs = [D(X) ~ p - d * X] noise_eqs = [sqrt(p), -sqrt(d * X)] -@test_throws ArgumentError ssys=SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) +@test_throws ArgumentError SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) noise_eqs = reshape([sqrt(p), -sqrt(d * X)], 1, 2) ssys = SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys) diff --git a/test/symbolic_events.jl b/test/symbolic_events.jl index b15769e630..88ea88b8b0 100644 --- a/test/symbolic_events.jl +++ b/test/symbolic_events.jl @@ -458,7 +458,7 @@ let ∂ₜ = D eqs = [∂ₜ(A) ~ -k * A] - @named ssys = SDESystem(eqs, Equation[], t, [A], [k, t1, t2], + @named ssys = SDESystem(eqs, Equation[0.0], t, [A], [k, t1, t2], discrete_events = [cb1, cb2]) u0 = [A => 1.0] p = [k => 0.0, t1 => 1.0, t2 => 2.0] @@ -468,7 +468,7 @@ let cond1a = (t == t1) affect1a = [A ~ A + 1, B ~ A] cb1a = cond1a => affect1a - @named ssys1 = SDESystem(eqs, Equation[], t, [A, B], [k, t1, t2], + @named ssys1 = SDESystem(eqs, [0.0], t, [A, B], [k, t1, t2], discrete_events = [cb1a, cb2]) u0′ = [A => 1.0, B => 0.0] sol = testsol( @@ -478,11 +478,11 @@ let # same as above - but with set-time event syntax cb1‵ = [1.0] => affect1 # needs to be a Vector for the event to happen only once cb2‵ = [2.0] => affect2 - @named ssys‵ = SDESystem(eqs, Equation[], t, [A], [k], discrete_events = [cb1‵, cb2‵]) + @named ssys‵ = SDESystem(eqs, [0.0], t, [A], [k], discrete_events = [cb1‵, cb2‵]) testsol(ssys‵, u0, p, tspan; paramtotest = k) # mixing discrete affects - @named ssys3 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2], + @named ssys3 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2], discrete_events = [cb1, cb2‵]) testsol(ssys3, u0, p, tspan; tstops = [1.0], paramtotest = k) @@ -492,16 +492,16 @@ let nothing end cb2‵‵ = [2.0] => (affect!, [], [k], [k], nothing) - @named ssys4 = SDESystem(eqs, Equation[], t, [A], [k, t1], + @named ssys4 = SDESystem(eqs, [0.0], t, [A], [k, t1], discrete_events = [cb1, cb2‵‵]) testsol(ssys4, u0, p, tspan; tstops = [1.0], paramtotest = k) # mixing with symbolic condition in the func affect cb2‵‵‵ = (t == t2) => (affect!, [], [k], [k], nothing) - @named ssys5 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2], + @named ssys5 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2], discrete_events = [cb1, cb2‵‵‵]) testsol(ssys5, u0, p, tspan; tstops = [1.0, 2.0], paramtotest = k) - @named ssys6 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2], + @named ssys6 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2], discrete_events = [cb2‵‵‵, cb1]) testsol(ssys6, u0, p, tspan; tstops = [1.0, 2.0], paramtotest = k) @@ -509,7 +509,7 @@ let cond3 = A ~ 0.1 affect3 = [k ~ 0.0] cb3 = cond3 => affect3 - @named ssys7 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2], + @named ssys7 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2], discrete_events = [cb1, cb2‵‵‵], continuous_events = [cb3]) sol = testsol(ssys7, u0, p, (0.0, 10.0); tstops = [1.0, 2.0]) From aa0558bfa9f76fc605e073ffde9f2fdd78cac1e6 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 08:28:15 -0400 Subject: [PATCH 4/9] fix typo --- test/symbolic_events.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/symbolic_events.jl b/test/symbolic_events.jl index 88ea88b8b0..c9b4946d30 100644 --- a/test/symbolic_events.jl +++ b/test/symbolic_events.jl @@ -458,7 +458,7 @@ let ∂ₜ = D eqs = [∂ₜ(A) ~ -k * A] - @named ssys = SDESystem(eqs, Equation[0.0], t, [A], [k, t1, t2], + @named ssys = SDESystem(eqs, [0.0], t, [A], [k, t1, t2], discrete_events = [cb1, cb2]) u0 = [A => 1.0] p = [k => 0.0, t1 => 1.0, t2 => 2.0] From fe6ba2877cbc5ecac3fe0671f6d8c18041bfd52e Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 09:08:43 -0400 Subject: [PATCH 5/9] simpler test --- src/systems/diffeqs/sdesystem.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/systems/diffeqs/sdesystem.jl b/src/systems/diffeqs/sdesystem.jl index 7eab3dcb1c..0499af86fb 100644 --- a/src/systems/diffeqs/sdesystem.jl +++ b/src/systems/diffeqs/sdesystem.jl @@ -141,8 +141,8 @@ struct SDESystem <: AbstractODESystem check_parameters(ps, iv) check_equations(deqs, iv) check_equations(neqs, dvs) - if size(neqs, 1) != length(dvs) - throw(ArgumentError("Noise equations ill-formed. Number of rows must match number of states. size(neqs,1) = $(size(neqs,1)) != length(dvs) = $(length(dvs))")) + if size(neqs, 1) != length(deqs) + throw(ArgumentError("Noise equations ill-formed. Number of rows must match number of drift equations. size(neqs,1) = $(size(neqs,1)) != length(deqs) = $(length(deqs))")) end check_equations(equations(cevents), iv) end From 70b1a8bde5915b879d20038f77d686e139ea2a07 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 14:52:52 -0400 Subject: [PATCH 6/9] fix ill-formed system --- test/sdesystem.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/sdesystem.jl b/test/sdesystem.jl index 30f92e039c..866dab0f5d 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -462,6 +462,10 @@ fdif!(du, u0, p, t) eqs_short = [D(x) ~ σ * (y - x), D(y) ~ x * (ρ - z) - y ] + noise_eqs = [ + y - x + x - y + ] sys1 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) sys2 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) @test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [], t, [], [], From bbf967a8a52b4559bfbcd1a7237006bcbdd64839 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Mon, 1 Jul 2024 15:31:11 -0400 Subject: [PATCH 7/9] format --- test/sdesystem.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/sdesystem.jl b/test/sdesystem.jl index 866dab0f5d..90dbf6f2dd 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -462,10 +462,8 @@ fdif!(du, u0, p, t) eqs_short = [D(x) ~ σ * (y - x), D(y) ~ x * (ρ - z) - y ] - noise_eqs = [ - y - x - x - y - ] + noise_eqs = [y - x + x - y] sys1 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) sys2 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) @test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [], t, [], [], From 239fe99cdfc5c753f9ad8c928632df45474b8372 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Tue, 2 Jul 2024 04:53:15 -0400 Subject: [PATCH 8/9] Update test/sdesystem.jl --- test/sdesystem.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sdesystem.jl b/test/sdesystem.jl index 90dbf6f2dd..8db14f5aee 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -466,7 +466,7 @@ fdif!(du, u0, p, t) x - y] sys1 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) sys2 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) - @test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [], t, [], [], + @test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [sys2.y], t, [], [], systems = [sys1, sys2], name = :foo) end From 43e38eedab1f2c2f55163f6af0fb5e40a0bf96bd Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Thu, 4 Jul 2024 01:27:37 -0400 Subject: [PATCH 9/9] fix test typo --- test/sdesystem.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sdesystem.jl b/test/sdesystem.jl index 288c2fb3d5..3314b8a89f 100644 --- a/test/sdesystem.jl +++ b/test/sdesystem.jl @@ -464,8 +464,8 @@ fdif!(du, u0, p, t) ] noise_eqs = [y - x x - y] - sys1 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) - sys2 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1) + sys1 = SDESystem(eqs_short, noise_eqs, t, [x, y, z], [σ, ρ, β], name = :sys1) + sys2 = SDESystem(eqs_short, noise_eqs, t, [x, y, z], [σ, ρ, β], name = :sys1) @test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [sys2.y], t, [], [], systems = [sys1, sys2], name = :foo) end