Skip to content

Commit 9dc67b7

Browse files
authored
Merge pull request #2086 from topolarity/pantelides-fix
Pantelides: Fix stem walking for alias-graph check
2 parents f62a3a0 + f51f35c commit 9dc67b7

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

src/structural_transformation/pantelides.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function computed_highest_diff_variables(structure, ag::Union{AliasGraph, Nothin
125125
while isempty(𝑑neighbors(graph, var))
126126
var′ = invview(var_to_diff)[var]
127127
var′ === nothing && break
128-
stem′ = invview(var_to_diff)[var]
128+
stem′ = invview(var_to_diff)[stem]
129129
# Invariant from alias elimination: Stem is chosen to have
130130
# the highest differentiation order.
131131
@assert stem′ !== nothing

test/pantelides.jl

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using Test
2+
using ModelingToolkit.StructuralTransformations: computed_highest_diff_variables
3+
using ModelingToolkit: SystemStructure, AliasGraph, BipartiteGraph, DiffGraph, complete,
4+
𝑑neighbors
5+
6+
### Test `computed_highest_diff_variables`, which is used in the Pantelides algorithm. ###
7+
8+
begin
9+
"""
10+
Vars: x, y
11+
Eqs: 0 = f(x)
12+
Alias: ẋ = ẏ
13+
"""
14+
n_vars = 4
15+
ag = AliasGraph(n_vars)
16+
17+
# Alias: ẋ = 1 * ẏ
18+
ag[4] = 1 => 2
19+
20+
# 0 = f(x)
21+
graph = complete(BipartiteGraph([Int[1]], n_vars))
22+
23+
# [x, ẋ, y, ẏ]
24+
var_to_diff = DiffGraph([2, nothing, 4, nothing], # primal_to_diff
25+
[nothing, 1, nothing, 3]) # diff_to_primal
26+
27+
# [f(x)]
28+
eq_to_diff = DiffGraph([nothing], # primal_to_diff
29+
[nothing]) # diff_to_primal
30+
structure = SystemStructure(var_to_diff, eq_to_diff, graph, nothing, nothing, false)
31+
varwhitelist = computed_highest_diff_variables(structure, ag)
32+
33+
# Correct answer is: ẋ
34+
@assert varwhitelist == Bool[0, 1, 0, 0]
35+
end
36+
37+
begin
38+
"""
39+
Vars: x, y
40+
Eqs: 0 = f(x)
41+
Alias: ẋ = ẏ, ̈x = ̈y
42+
"""
43+
n_vars = 6
44+
ag = AliasGraph(n_vars)
45+
46+
# Alias: ẋ = 1 * ẏ
47+
ag[5] = 1 => 2
48+
# Alias: ẍ = 1 * ̈y
49+
ag[6] = 1 => 3
50+
51+
# 0 = f(x)
52+
graph = complete(BipartiteGraph([Int[1]], n_vars))
53+
54+
# [x, ẋ, ̈x, y, ẏ, ̈x]
55+
var_to_diff = DiffGraph([2, 3, nothing, 5, 6, nothing], # primal_to_diff
56+
[nothing, 1, 2, nothing, 4, 5]) # diff_to_primal
57+
58+
# [f(x)]
59+
eq_to_diff = DiffGraph([nothing], # primal_to_diff
60+
[nothing]) # diff_to_primal
61+
62+
structure = SystemStructure(var_to_diff, eq_to_diff, graph, nothing, nothing, false)
63+
varwhitelist = computed_highest_diff_variables(structure, ag)
64+
65+
# Correct answer is: ẋ
66+
@assert varwhitelist == Bool[0, 1, 0, 0, 0, 0]
67+
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using SafeTestsets, Test
22

33
@safetestset "AliasGraph Test" begin include("alias.jl") end
4+
@safetestset "Pantelides Test" begin include("pantelides.jl") end
45
@safetestset "Linear Algebra Test" begin include("linalg.jl") end
56
@safetestset "AbstractSystem Test" begin include("abstractsystem.jl") end
67
@safetestset "Variable Scope Tests" begin include("variable_scope.jl") end

0 commit comments

Comments
 (0)