Skip to content

Commit 900d5f0

Browse files
Merge pull request #2833 from SciML/sde_throws
Better error throwing on ill-formed SDESystems
2 parents 3ff798b + 43e38ee commit 900d5f0

File tree

4 files changed

+29
-12
lines changed

4 files changed

+29
-12
lines changed

.github/workflows/Downstream.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- {user: SciML, repo: NeuralPDE.jl, group: NNPDE}
3333
- {user: SciML, repo: DataDrivenDiffEq.jl, group: Downstream}
3434
- {user: SciML, repo: StructuralIdentifiability.jl, group: All}
35-
- {user: SciML, repo: ModelingToolkitStandardLibrary.jl}
35+
- {user: SciML, repo: ModelingToolkitStandardLibrary.jl, group: Core}
3636
- {user: SciML, repo: ModelOrderReduction.jl, group: All}
3737
- {user: SciML, repo: MethodOfLines.jl, group: Interface}
3838
- {user: SciML, repo: MethodOfLines.jl, group: 2D_Diffusion}

src/systems/diffeqs/sdesystem.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ struct SDESystem <: AbstractODESystem
140140
check_variables(dvs, iv)
141141
check_parameters(ps, iv)
142142
check_equations(deqs, iv)
143+
check_equations(neqs, dvs)
144+
if size(neqs, 1) != length(deqs)
145+
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))"))
146+
end
143147
check_equations(equations(cevents), iv)
144148
end
145149
if checks == true || (checks & CheckUnits) > 0

test/sdesystem.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,11 @@ fdif!(du, u0, p, t)
462462
eqs_short = [D(x) ~ σ * (y - x),
463463
D(y) ~ x *- z) - y
464464
]
465-
sys1 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1)
466-
sys2 = SDESystem(eqs_short, noiseeqs, t, [x, y, z], [σ, ρ, β], name = :sys1)
467-
@test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [], t, [], [],
465+
noise_eqs = [y - x
466+
x - y]
467+
sys1 = SDESystem(eqs_short, noise_eqs, t, [x, y, z], [σ, ρ, β], name = :sys1)
468+
sys2 = SDESystem(eqs_short, noise_eqs, t, [x, y, z], [σ, ρ, β], name = :sys1)
469+
@test_throws ArgumentError SDESystem([sys2.y ~ sys1.z], [sys2.y], t, [], [],
468470
systems = [sys1, sys2], name = :foo)
469471
end
470472

@@ -615,6 +617,17 @@ prob = SDEProblem(sys1, sts .=> [1.0, 0.0, 0.0],
615617
(0.0, 100.0), ps .=> (10.0, 26.0))
616618
solve(prob, LambaEulerHeun(), seed = 1)
617619

620+
# Test ill-formed due to more equations than states in noise equations
621+
622+
@parameters p d
623+
@variables t X(t)
624+
eqs = [D(X) ~ p - d * X]
625+
noise_eqs = [sqrt(p), -sqrt(d * X)]
626+
@test_throws ArgumentError SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys)
627+
628+
noise_eqs = reshape([sqrt(p), -sqrt(d * X)], 1, 2)
629+
ssys = SDESystem(eqs, noise_eqs, t, [X], [p, d]; name = :ssys)
630+
618631
# SDEProblem construction with StaticArrays
619632
# Issue#2814
620633
@parameters p d

test/symbolic_events.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ let
458458

459459
∂ₜ = D
460460
eqs = [∂ₜ(A) ~ -k * A]
461-
@named ssys = SDESystem(eqs, Equation[], t, [A], [k, t1, t2],
461+
@named ssys = SDESystem(eqs, [0.0], t, [A], [k, t1, t2],
462462
discrete_events = [cb1, cb2])
463463
u0 = [A => 1.0]
464464
p = [k => 0.0, t1 => 1.0, t2 => 2.0]
@@ -468,7 +468,7 @@ let
468468
cond1a = (t == t1)
469469
affect1a = [A ~ A + 1, B ~ A]
470470
cb1a = cond1a => affect1a
471-
@named ssys1 = SDESystem(eqs, Equation[], t, [A, B], [k, t1, t2],
471+
@named ssys1 = SDESystem(eqs, [0.0], t, [A, B], [k, t1, t2],
472472
discrete_events = [cb1a, cb2])
473473
u0′ = [A => 1.0, B => 0.0]
474474
sol = testsol(
@@ -478,11 +478,11 @@ let
478478
# same as above - but with set-time event syntax
479479
cb1‵ = [1.0] => affect1 # needs to be a Vector for the event to happen only once
480480
cb2‵ = [2.0] => affect2
481-
@named ssys‵ = SDESystem(eqs, Equation[], t, [A], [k], discrete_events = [cb1‵, cb2‵])
481+
@named ssys‵ = SDESystem(eqs, [0.0], t, [A], [k], discrete_events = [cb1‵, cb2‵])
482482
testsol(ssys‵, u0, p, tspan; paramtotest = k)
483483

484484
# mixing discrete affects
485-
@named ssys3 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2],
485+
@named ssys3 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2],
486486
discrete_events = [cb1, cb2‵])
487487
testsol(ssys3, u0, p, tspan; tstops = [1.0], paramtotest = k)
488488

@@ -492,24 +492,24 @@ let
492492
nothing
493493
end
494494
cb2‵‵ = [2.0] => (affect!, [], [k], [k], nothing)
495-
@named ssys4 = SDESystem(eqs, Equation[], t, [A], [k, t1],
495+
@named ssys4 = SDESystem(eqs, [0.0], t, [A], [k, t1],
496496
discrete_events = [cb1, cb2‵‵])
497497
testsol(ssys4, u0, p, tspan; tstops = [1.0], paramtotest = k)
498498

499499
# mixing with symbolic condition in the func affect
500500
cb2‵‵‵ = (t == t2) => (affect!, [], [k], [k], nothing)
501-
@named ssys5 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2],
501+
@named ssys5 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2],
502502
discrete_events = [cb1, cb2‵‵‵])
503503
testsol(ssys5, u0, p, tspan; tstops = [1.0, 2.0], paramtotest = k)
504-
@named ssys6 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2],
504+
@named ssys6 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2],
505505
discrete_events = [cb2‵‵‵, cb1])
506506
testsol(ssys6, u0, p, tspan; tstops = [1.0, 2.0], paramtotest = k)
507507

508508
# mix a continuous event too
509509
cond3 = A ~ 0.1
510510
affect3 = [k ~ 0.0]
511511
cb3 = cond3 => affect3
512-
@named ssys7 = SDESystem(eqs, Equation[], t, [A], [k, t1, t2],
512+
@named ssys7 = SDESystem(eqs, [0.0], t, [A], [k, t1, t2],
513513
discrete_events = [cb1, cb2‵‵‵],
514514
continuous_events = [cb3])
515515
sol = testsol(ssys7, u0, p, (0.0, 10.0); tstops = [1.0, 2.0])

0 commit comments

Comments
 (0)