Skip to content

Commit 3f29080

Browse files
feat: support observed function generation for DDEs
1 parent adfe259 commit 3f29080

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/systems/abstractsystem.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,10 @@ function SymbolicIndexingInterface.observed(
805805
return let _fn = _fn
806806
fn1(u, p, t) = _fn(u, p, t)
807807
fn1(u, p::MTKParameters, t) = _fn(u, p..., t)
808+
809+
# DDEs
810+
fn1(u, histfn, p, t) = _fn(u, histfn, p, t)
811+
fn1(u, histfn, p::MTKParameters, t) = _fn(u, histfn, p..., t)
808812
fn1
809813
end
810814
else

src/systems/diffeqs/odesystem.jl

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,9 @@ function build_explicit_observed_function(sys, ts;
421421
ts = [ts]
422422
end
423423
ts = unwrap.(ts)
424+
if is_dde(sys)
425+
ts = map(x -> delay_to_function(sys, x), ts)
426+
end
424427

425428
vars = Set()
426429
foreach(v -> vars!(vars, v; op), ts)
@@ -493,8 +496,12 @@ function build_explicit_observed_function(sys, ts;
493496
end
494497
ts = map(t -> substitute(t, subs), ts)
495498
obsexprs = []
499+
496500
for i in 1:maxidx
497501
eq = obs[i]
502+
if is_dde(sys)
503+
eq = delay_to_function(sys, eq)
504+
end
498505
lhs = eq.lhs
499506
rhs = eq.rhs
500507
push!(obsexprs, lhs rhs)
@@ -515,12 +522,17 @@ function build_explicit_observed_function(sys, ts;
515522
ps = (DestructuredArgs(unwrap.(ps), inbounds = !checkbounds),)
516523
end
517524
dvs = DestructuredArgs(unknowns(sys), inbounds = !checkbounds)
525+
if is_dde(sys)
526+
dvs = (dvs, DDE_HISTORY_FUN)
527+
else
528+
dvs = (dvs,)
529+
end
518530
if inputs === nothing
519-
args = param_only ? [ps..., ivs...] : [dvs, ps..., ivs...]
531+
args = param_only ? [ps..., ivs...] : [dvs..., ps..., ivs...]
520532
else
521533
inputs = unwrap.(inputs)
522534
ipts = DestructuredArgs(inputs, inbounds = !checkbounds)
523-
args = param_only ? [ipts, ps..., ivs...] : [dvs, ipts, ps..., ivs...]
535+
args = param_only ? [ipts, ps..., ivs...] : [dvs..., ipts, ps..., ivs...]
524536
end
525537
pre = get_postprocess_fbody(sys)
526538

@@ -556,6 +568,20 @@ function build_explicit_observed_function(sys, ts;
556568
end
557569
end
558570

571+
function populate_delays(delays::Set, obsexprs, histfn, sys, sym)
572+
_vars_util = vars(sym)
573+
for v in _vars_util
574+
v in delays && continue
575+
iscall(v) && issym(operation(v)) && (args = arguments(v); length(args) == 1) &&
576+
iscall(only(args)) || continue
577+
578+
idx = variable_index(sys, operation(v)(get_iv(sys)))
579+
idx === nothing && error("Delay term $v is not an unknown in the system")
580+
push!(delays, v)
581+
push!(obsexprs, v histfn(only(args))[idx])
582+
end
583+
end
584+
559585
function _eq_unordered(a, b)
560586
length(a) === length(b) || return false
561587
n = length(a)

0 commit comments

Comments
 (0)