Skip to content

Commit 8ffa784

Browse files
fix: properly handle aliasing elements of unscalarized array variables
1 parent 88261c4 commit 8ffa784

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

src/systems/alias_elimination.jl

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ function find_perfect_aliases!(
145145
c1 == c2 && push!(eqs_to_rm, ieq)
146146
end
147147

148+
eqs_to_substitute = Int[]
148149
for (root, group_vars) in alias_sets
149150
target = group_target[root]
150151
state.always_present[target] = true
@@ -165,8 +166,7 @@ function find_perfect_aliases!(
165166
dnbors = copy(𝑑neighbors(graph, v))
166167
for e in dnbors
167168
snbors = 𝑠neighbors(graph, e)
168-
eqs[e] = substitute(eqs[e], subs)
169-
original_eqs[e] = substitute(original_eqs[e], subs)
169+
push!(eqs_to_substitute, e)
170170
Graphs.rem_edge!(graph, e, v)
171171
Graphs.add_edge!(graph, e, target)
172172
end
@@ -185,8 +185,7 @@ function find_perfect_aliases!(
185185
dnbors = copy(𝑑neighbors(graph, dv))
186186
for e in dnbors
187187
snbors = 𝑠neighbors(graph, e)
188-
eqs[e] = substitute(eqs[e], subs)
189-
original_eqs[e] = substitute(original_eqs[e], subs)
188+
push!(eqs_to_substitute, e)
190189
Graphs.rem_edge!(graph, e, dv)
191190
Graphs.add_edge!(graph, e, dtarget)
192191
end
@@ -197,6 +196,23 @@ function find_perfect_aliases!(
197196
end
198197
end
199198

199+
# We need to handle unscalarized array variables
200+
for k in keys(subs)
201+
k, isarr = split_indexed_var(k)
202+
isarr || continue
203+
haskey(subs, k) && continue
204+
subs[k] = Symbolics.SConst(collect(k))
205+
end
206+
207+
ir = get_irstructure(sys)
208+
subber = SU.IRSubstituter{false}(ir, subs)
209+
for e in eqs_to_substitute
210+
# Double substitute to handle unscalarized array variables. First one
211+
# substitutes `x` to `[x[1], x[2]]`. The second substitutes `x[1]` and `x[2]`.
212+
eqs[e] = subber(subber(eqs[e]))
213+
original_eqs[e] = subber(subber(original_eqs[e]))
214+
end
215+
200216
# After substitution, alias equations that connected a sticky non-target
201217
# variable to a zero-priority variable become structurally identical to the
202218
# direct alias between the sticky variable and the target (since the

test/reduction.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ModelingToolkit, OrdinaryDiffEq, Test, NonlinearSolve, LinearAlgebra
2+
using Symbolics
23
using OrdinaryDiffEqRosenbrock
34
using ModelingToolkit: topsort_equations, t_nounits as t, D_nounits as D, unwrap
45

@@ -374,3 +375,12 @@ end
374375

375376
@test Set(unknowns(sys)) == Set([e, c, d])
376377
end
378+
379+
@testset "`eliminate_perfect_aliases!` correctly handles unscalarized arrays" begin
380+
@variables x(t)[1:2] y(t)[1:2]
381+
@mtkcompile sys = System([D(x) ~ x, y[1] ~ y[2], dot(x, y) ~ 1], t)
382+
@test any(equations(sys)) do eq
383+
isequal(eq, 0 ~ 1 - dot(x, Symbolics.SConst([y[2], y[2]]))) ||
384+
isequal(eq, 0 ~ 1 - dot(x, Symbolics.SConst([y[1], y[1]])))
385+
end
386+
end

0 commit comments

Comments
 (0)