Skip to content

Commit 7b9ec75

Browse files
committed
Add a conservative option in alias elimination
1 parent 5ed420e commit 7b9ec75

File tree

2 files changed

+30
-21
lines changed

2 files changed

+30
-21
lines changed

src/systems/reduction.jl

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ end
3232

3333
# Note that we reduce parameters, too
3434
# i.e. `2param = 3` will be reduced away
35-
isvar(s::Sym) = true
36-
isvar(s::Term) = isvar(operation(s))
37-
isvar(s::Any) = false
35+
isvar(s) = s isa Sym ? true :
36+
istree(s) ? isvar(operation(s)) :
37+
false
3838

3939
function get_α_x(αx)
4040
if isvar(αx)
@@ -55,7 +55,25 @@ function get_α_x(αx)
5555
end
5656
end
5757

58-
function alias_elimination(sys::ODESystem)
58+
function is_sub_candidate(rhs, conservative)
59+
conservative || return true
60+
isvar(rhs) || rhs isa Number
61+
end
62+
63+
function maybe_alias(lhs, rhs, diff_vars, conservative)
64+
is_sub_candidate(rhs, conservative) || return false, nothing
65+
66+
res_left = get_α_x(lhs)
67+
if res_left !== nothing && !(res_left[2] in diff_vars)
68+
α, x = res_left
69+
sub = x => _isone(α) ? rhs : rhs / α
70+
return true, sub
71+
else
72+
return false, nothing
73+
end
74+
end
75+
76+
function alias_elimination(sys::ODESystem; conservative=true)
5977
eqs = vcat(equations(sys), observed(sys))
6078
diff_vars = filter(!isnothing, map(eqs) do eq
6179
if isdiffeq(eq)
@@ -76,24 +94,15 @@ function alias_elimination(sys::ODESystem)
7694
continue
7795
end
7896

79-
maybe_alias = isalias = false
80-
res_left = get_α_x(eq.lhs)
81-
if !isnothing(res_left) && !(res_left[2] in diff_vars)
82-
# `α x = rhs` => `x = rhs / α`
83-
α, x = res_left
84-
sub = x => _isone(α) ? eq.rhs : eq.rhs / α
85-
maybe_alias = true
86-
else
87-
res_right = get_α_x(eq.rhs)
88-
if !isnothing(res_right) && !(res_right[2] in diff_vars)
89-
# `lhs = β y` => `y = lhs / β`
90-
β, y = res_right
91-
sub = y => _isone(β) ? eq.lhs : β * eq.lhs
92-
maybe_alias = true
93-
end
97+
# `α x = rhs` => `x = rhs / α`
98+
ma, sub = maybe_alias(eq.lhs, eq.rhs, diff_vars, conservative)
99+
if !ma
100+
# `lhs = β y` => `y = lhs / β`
101+
ma, sub = maybe_alias(eq.rhs, eq.lhs, diff_vars, conservative)
94102
end
95103

96-
if maybe_alias
104+
isalias = false
105+
if ma
97106
l, r = sub
98107
# alias equations shouldn't introduce cycles
99108
if !(l in deps) && isempty(intersect(deps, vars(r)))

test/reduction.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ connected = ODESystem([s ~ a + lorenz1.x
7575

7676
flattened_system = ModelingToolkit.flatten(connected)
7777

78-
aliased_flattened_system = alias_elimination(flattened_system)
78+
aliased_flattened_system = alias_elimination(flattened_system; conservative=false)
7979

8080
@test setdiff(states(aliased_flattened_system), [
8181
a

0 commit comments

Comments
 (0)