@@ -267,6 +267,7 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
267
267
end
268
268
dummy_derivatives_set = BitSet (dummy_derivatives)
269
269
270
+ irreducible_set = BitSet ()
270
271
if ag != = nothing
271
272
function isreducible (x)
272
273
# `k` is reducible if all lower differentiated variables are.
@@ -277,27 +278,46 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
277
278
end
278
279
x = diff_to_var[x]
279
280
x === nothing && break
281
+ # We deliberately do not check `isempty(𝑑neighbors(graph, x))`
282
+ # because when `D(x)` appears in the alias graph, and `x`
283
+ # doesn't appear in any equations nor in the alias graph, `D(x)`
284
+ # is not reducible. Consider the system `D(x) ~ 0`.
280
285
if ! haskey (ag, x)
281
286
isred = false
282
287
end
283
288
end
284
289
isred
285
290
end
286
- irreducible_set = BitSet ()
287
- for (k, (_, v)) in ag
291
+ for (k, (c, v)) in ag
288
292
isreducible (k) || push! (irreducible_set, k)
289
293
isreducible (k) || push! (irreducible_set, k)
294
+ iszero (c) && continue
290
295
push! (irreducible_set, v)
291
296
end
292
297
end
293
298
294
- is_not_present = v -> isempty (𝑑neighbors (graph, v)) &&
295
- (ag === nothing || (haskey (ag, v) && ! (v in irreducible_set)))
299
+ is_not_present_non_rec = let graph = graph, irreducible_set = irreducible_set
300
+ v -> begin
301
+ not_in_eqs = isempty (𝑑neighbors (graph, v))
302
+ ag === nothing && return not_in_eqs
303
+ isirreducible = v in irreducible_set
304
+ return not_in_eqs && ! isirreducible
305
+ end
306
+ end
307
+
308
+ is_not_present = let var_to_diff = var_to_diff
309
+ v -> while true
310
+ # if a higher derivative is present, then it's present
311
+ is_not_present_non_rec (v) || return false
312
+ v = var_to_diff[v]
313
+ v === nothing && return true
314
+ end
315
+ end
316
+
296
317
# Derivatives that are either in the dummy derivatives set or ended up not
297
318
# participating in the system at all are not considered differential
298
319
is_some_diff = let dummy_derivatives_set = dummy_derivatives_set
299
- v -> ! (v in dummy_derivatives_set) &&
300
- ! (var_to_diff[v] === nothing && is_not_present (v))
320
+ v -> ! (v in dummy_derivatives_set) && ! is_not_present (v)
301
321
end
302
322
303
323
# We don't want tearing to give us `y_t ~ D(y)`, so we skip equations with
@@ -309,7 +329,7 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
309
329
# We can eliminate variables that are not a selected state (differential
310
330
# variables). Selected states are differentiated variables that are not
311
331
# dummy derivatives.
312
- can_eliminate = let var_to_diff = var_to_diff
332
+ can_eliminate = let var_to_diff = var_to_diff, ag = ag
313
333
v -> begin
314
334
if ag != = nothing
315
335
haskey (ag, v) && return false
0 commit comments