35
35
alias_elimination (sys) = alias_elimination! (TearingState (sys; quick_cancel = true ))
36
36
function alias_elimination! (state:: TearingState )
37
37
sys = state. sys
38
+ complete! (state. structure)
38
39
ag, mm, updated_diff_vars = alias_eliminate_graph! (state)
39
40
ag === nothing && return sys
40
41
@@ -52,8 +53,20 @@ function alias_elimination!(state::TearingState)
52
53
end
53
54
54
55
subs = Dict ()
56
+ # If we encounter y = -D(x), then we need to expand the derivative when
57
+ # D(y) appears in the equation, so that D(-D(x)) becomes -D(D(x)).
58
+ to_expand = Int[]
59
+ diff_to_var = invview (var_to_diff)
55
60
for (v, (coeff, alias)) in pairs (ag)
56
61
subs[fullvars[v]] = iszero (coeff) ? 0 : coeff * fullvars[alias]
62
+ if coeff == - 1
63
+ # if `alias` is like -D(x)
64
+ diff_to_var[alias] === nothing && continue
65
+ # if `v` is like y, and D(y) also exists
66
+ (dv = var_to_diff[v]) === nothing && continue
67
+ # all equations that contains D(y) needs to be expanded.
68
+ append! (to_expand, 𝑑neighbors (graph, dv))
69
+ end
57
70
end
58
71
59
72
dels = Int[]
@@ -72,11 +85,29 @@ function alias_elimination!(state::TearingState)
72
85
end
73
86
end
74
87
deleteat! (eqs, sort! (dels))
88
+ old_to_new = Vector {Int} (undef, length (var_to_diff))
89
+ idx = 0
90
+ cursor = 1
91
+ ndels = length (dels)
92
+ for (i, e) in enumerate (old_to_new)
93
+ if cursor <= ndels && i == dels[cursor]
94
+ cursor += 1
95
+ old_to_new[i] = - 1
96
+ continue
97
+ end
98
+ idx += 1
99
+ old_to_new[i] = idx
100
+ end
75
101
76
102
for (ieq, eq) in enumerate (eqs)
77
103
eqs[ieq] = substitute (eq, subs)
78
104
end
79
105
106
+ for old_ieq in to_expand
107
+ ieq = old_to_new[old_ieq]
108
+ eqs[ieq] = expand_derivatives (eqs[ieq])
109
+ end
110
+
80
111
newstates = []
81
112
diff_to_var = invview (var_to_diff)
82
113
for j in eachindex (fullvars)
0 commit comments