Skip to content

Commit ec1241f

Browse files
feat: implement DiscreteProblem and DiscreteFunction for System
1 parent 35607bb commit ec1241f

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

src/problems/compatibility.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,20 @@ function check_has_noise(sys::System, T)
9797
"""))
9898
end
9999
end
100+
101+
function check_is_discrete(sys::System, T)
102+
if !is_discrete_system(sys)
103+
throw(SystemCompatibilityError("""
104+
`$T` expects a discrete system. Consider an `ODEProblem` instead. If your system \
105+
is discrete, ensure `structural_simplify` has been run on it.
106+
"""))
107+
end
108+
end
109+
110+
function check_is_explicit(sys::System, T, altT)
111+
if has_alg_equations(sys)
112+
throw(SystemCompatibilityError("""
113+
`$T` expects an explicit system. Consider a `$altT` instead.
114+
"""))
115+
end
116+
end

src/problems/discreteproblem.jl

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@fallback_iip_specialize function SciMLBase.DiscreteFunction{iip, spec}(
2+
sys::System, _d = nothing, u0 = nothing, p = nothing;
3+
t = nothing, eval_expression = false, eval_module = @__MODULE__,
4+
checkbounds = false, analytic = nothing, simplify = false, cse = true,
5+
initialization_data = nothing, check_compatibility = true, kwargs...) where {
6+
iip, spec}
7+
check_complete(sys, DiscreteFunction)
8+
check_compatibility && check_compatible_system(DiscreteFunction, sys)
9+
10+
dvs = unknowns(sys)
11+
ps = parameters(sys)
12+
f = generate_rhs(sys, dvs, ps; expression = Val{false},
13+
eval_expression, eval_module, checkbounds = checkbounds, cse,
14+
kwargs...)
15+
16+
if spec === SciMLBase.FunctionWrapperSpecialize && iip
17+
if u0 === nothing || p === nothing || t === nothing
18+
error("u0, p, and t must be specified for FunctionWrapperSpecialize on DiscreteFunction.")
19+
end
20+
f = SciMLBase.wrapfun_iip(f, (u0, u0, p, t))
21+
end
22+
23+
observedfun = ObservedFunctionCache(
24+
sys; steady_state = false, eval_expression, eval_module, checkbounds, cse)
25+
26+
DiscreteFunction{iip, spec}(f;
27+
sys = sys,
28+
observed = observedfun,
29+
analytic = analytic,
30+
initialization_data)
31+
end
32+
33+
@fallback_iip_specialize function SciMLBase.DiscreteProblem{iip, spec}(
34+
sys::System, u0map, tspan, parammap = SciMLBase.NullParameters();
35+
check_compatibility = true, kwargs...) where {iip, spec}
36+
check_complete(sys, DiscreteProblem)
37+
check_compatibility && check_compatible_system(DiscreteProblem, sys)
38+
39+
dvs = unknowns(sys)
40+
u0map = to_varmap(u0map, dvs)
41+
u0map = shift_u0map_forward(sys, u0map, defaults(sys))
42+
f, u0, p = process_SciMLProblem(DiscreteFunction{iip, spec}, sys, u0map, parammap;
43+
t = tspan !== nothing ? tspan[1] : tspan, check_compatibility, kwargs...)
44+
u0 = f(u0, p, tspan[1])
45+
46+
kwargs = process_kwargs(sys; kwargs...)
47+
# Call `remake` so it runs initialization if it is trivial
48+
return remake(DiscreteProblem{iip}(f, u0, tspan, p; kwargs...))
49+
end
50+
51+
function check_compatible_system(
52+
T::Union{Type{DiscreteFunction}, Type{DiscreteProblem}}, sys::System)
53+
check_time_dependent(sys, T)
54+
check_not_dde(sys)
55+
check_no_cost(sys, T)
56+
check_no_constraints(sys, T)
57+
check_no_jumps(sys, T)
58+
check_no_noise(sys, T)
59+
check_is_discrete(sys, T)
60+
check_is_explicit(sys, T, ImplicitDiscreteProblem)
61+
end

src/systems/codegen.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ function generate_rhs(sys::System, dvs = unknowns(sys),
4141
end
4242
ddvs = map(D, dvs)
4343
else
44-
check_operator_variables(eqs, Differential)
45-
check_lhs(eqs, Differential, Set(dvs))
44+
if !is_discrete_system(sys)
45+
check_operator_variables(eqs, Differential)
46+
check_lhs(eqs, Differential, Set(dvs))
47+
end
4648
rhss = [eq.rhs for eq in eqs]
4749
end
4850

0 commit comments

Comments
 (0)