32
32
33
33
# Note that we reduce parameters, too
34
34
# 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
38
38
39
39
function get_α_x (αx)
40
40
if isvar (αx)
@@ -55,7 +55,25 @@ function get_α_x(αx)
55
55
end
56
56
end
57
57
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 )
59
77
eqs = vcat (equations (sys), observed (sys))
60
78
diff_vars = filter (! isnothing, map (eqs) do eq
61
79
if isdiffeq (eq)
@@ -76,24 +94,15 @@ function alias_elimination(sys::ODESystem)
76
94
continue
77
95
end
78
96
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)
94
102
end
95
103
96
- if maybe_alias
104
+ isalias = false
105
+ if ma
97
106
l, r = sub
98
107
# alias equations shouldn't introduce cycles
99
108
if ! (l in deps) && isempty (intersect (deps, vars (r)))
0 commit comments