Skip to content

Commit 8273888

Browse files
author
Oscar Smith
authored
fix edge cases in pantiledes (#2137)
Fix edge cases in pantiledes where there are edge cases like self loops in the stem. These occured in systems like x->D(x) or x->y D(x)->D(y) x->D(y) and would lead to the `@assert stem′ !== nothing` failing.
1 parent 46a4733 commit 8273888

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/structural_transformation/pantelides.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,20 @@ function computed_highest_diff_variables(structure, ag::Union{AliasGraph, Nothin
126126
var′ = invview(var_to_diff)[var]
127127
var′ === nothing && break
128128
stem′ = invview(var_to_diff)[stem]
129+
avar′ = haskey(ag, var′) ? ag[var′][2] : nothing
130+
if avar′ == stem || var′ == stem
131+
# If we have a self-loop in the stem, we could have the
132+
# var′ also alias to the original stem. In that case, the
133+
# derivative of the stem is highest differentiated, because of the loop
134+
dstem = var_to_diff[stem]
135+
@assert dstem !== nothing
136+
varwhitelist[dstem] = true
137+
break
138+
end
129139
# Invariant from alias elimination: Stem is chosen to have
130140
# the highest differentiation order.
131141
@assert stem′ !== nothing
132-
if !haskey(ag, var′) || ag[var′][2] != stem′
142+
if avar′ != stem′
133143
varwhitelist[stem] = true
134144
break
135145
end

test/pantelides.jl

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ begin
3131
varwhitelist = computed_highest_diff_variables(structure, ag)
3232

3333
# Correct answer is: ẋ
34-
@assert varwhitelist == Bool[0, 1, 0, 0]
34+
@test varwhitelist == Bool[0, 1, 0, 0]
3535
end
3636

3737
begin
@@ -63,5 +63,36 @@ begin
6363
varwhitelist = computed_highest_diff_variables(structure, ag)
6464

6565
# Correct answer is: ẋ
66-
@assert varwhitelist == Bool[0, 1, 0, 0, 0, 0]
66+
@test varwhitelist == Bool[0, 1, 0, 0, 0, 0]
67+
end
68+
69+
begin
70+
"""
71+
Vars: x, y, z
72+
Eqs: 0 = f(x,y)
73+
Alias: y = -z, ẏ = z
74+
"""
75+
n_vars = 4
76+
ag = AliasGraph(n_vars)
77+
78+
# Alias: z = 1 * ẏ
79+
ag[3] = 1 => 2
80+
# Alias: z = -1 * y
81+
ag[4] = -1 => 2
82+
83+
# 0 = f(x,y)
84+
graph = complete(BipartiteGraph([Int[], Int[], Int[1, 2]], n_vars))
85+
86+
# [x, ẋ, y, ẏ]
87+
var_to_diff = DiffGraph([nothing, 4, nothing, nothing], # primal_to_diff
88+
[nothing, nothing, nothing, 2]) # diff_to_primal
89+
90+
# [f(x)]
91+
eq_to_diff = DiffGraph([nothing, nothing, nothing], # primal_to_diff
92+
[nothing, nothing, nothing]) # diff_to_primal
93+
structure = SystemStructure(var_to_diff, eq_to_diff, graph, nothing, nothing, false)
94+
varwhitelist = computed_highest_diff_variables(structure, ag)
95+
96+
# Correct answer is: ẋ
97+
@test varwhitelist == Bool[1, 0, 0, 1]
6798
end

0 commit comments

Comments
 (0)