@@ -83,3 +83,73 @@ function alias_elimination(sys::ODESystem)
83
83
ODESystem (diffeqs′, sys. iv, newstates, parameters (sys), observed= eliminate .~ outputs)
84
84
end
85
85
86
+ function get_α_x (αx)
87
+ if isvar (αx)
88
+ return αx, 1
89
+ elseif αx isa Term && operation (αx) === (* )
90
+ args = arguments (αx)
91
+ nums = filter (! isvar, args)
92
+ syms = filter (isvar, args)
93
+
94
+ if length (syms) == 1
95
+ return syms[1 ], prod (nums)
96
+ end
97
+ else
98
+ return nothing
99
+ end
100
+ end
101
+
102
+ function alias_elimination2 (sys)
103
+ eqs = vcat (equations (sys), observed (sys))
104
+
105
+ subs = Pair[]
106
+ # Case 1: Right hand side is a constant
107
+ ii = findall (eqs) do eq
108
+ (eq. lhs isa Sym || (eq. lhs isa Term && ! (eq. lhs. op isa Differential))) && ! (eq. rhs isa Symbolic)
109
+ end
110
+ for eq in eqs[ii]
111
+ substitution_dict[eq. lhs] = eq. rhs
112
+ push! (subs, eq. lhs => eq. rhs)
113
+ end
114
+ deleteat! (eqs, ii) # remove them
115
+
116
+ # Case 2: One side is a differentiated var, the other is an algebraic var
117
+ # substitute the algebraic var with the diff var
118
+ diff_vars = findall (eqs) do eq
119
+ if eq. lhs isa Term && eq. lhs. op isa Differential
120
+ eq. lhs. args[1 ]
121
+ else
122
+ nothing
123
+ end
124
+ end
125
+
126
+ for eq in eqs
127
+ res_left = get_α_x (eq. lhs)
128
+ if ! isnothing (res)
129
+ res_right = get_α_x (eq. rhs)
130
+ β, y = res
131
+ if y in diff_vars && ! (x in diff_vars)
132
+ multiple = β / α
133
+ push! (subs, x => isone (multiple) ? y : multiple * y)
134
+ elseif x in diff_vars && ! (y in diff_vars)
135
+ multiple = α / β
136
+ push! (subs, y => isone (multiple) ? y : multiple * y)
137
+ end
138
+ end
139
+ end
140
+
141
+ # Case 3: Explicit substitutions
142
+ for eq in eqs
143
+ res_left = get_α_x (eq. lhs)
144
+ if ! isnothing (res)
145
+ res_right = get_α_x (eq. rhs)
146
+ β, y = res
147
+ multiple = β / α
148
+ push! (subs, x => isone (multiple) ? x : multiple * x)
149
+ end
150
+ end
151
+
152
+ diffeqs = filter (eq -> eq. lhs isa Term && eq. lhs. op isa Differential, eqs)
153
+ diffeqs′ = substitute_aliases (diffeqs, Dict (subs))
154
+ ODESystem (diffeqs′, sys. iv, newstates, parameters (sys), observed= first .(subs) .~ last .(subs))
155
+ end
0 commit comments