1
- """
2
- uneven_invmap(n::Int, list)
3
-
4
- returns an uneven inv map with length `n`.
5
- """
6
- function uneven_invmap (n:: Int , list)
7
- rename = zero (Int, n)
8
- for (i, v) in enumerate (list)
9
- rename[v] = i
10
- end
11
- return rename
12
- end
13
-
14
1
# N.B. assumes `slist` and `dlist` are unique
15
2
function substitution_graph (graph, slist, dlist, var_eq_matching)
16
3
ns = length (slist)
17
4
nd = length (dlist)
18
5
ns == nd || error (" internal error" )
19
6
newgraph = BipartiteGraph (ns, nd)
20
- erename = uneven_invmap (nsrc (graph), slist)
21
- vrename = uneven_invmap (ndst (graph), dlist)
7
+ erename = uneven_invmap (nsrcs (graph), slist)
8
+ vrename = uneven_invmap (ndsts (graph), dlist)
22
9
for e in 𝑠vertices (graph)
23
10
ie = erename[e]
24
11
ie == 0 && continue
@@ -29,8 +16,9 @@ function substitution_graph(graph, slist, dlist, var_eq_matching)
29
16
end
30
17
end
31
18
32
- newmatching = zero (slist )
19
+ newmatching = Matching (ns )
33
20
for (v, e) in enumerate (var_eq_matching)
21
+ e === unassigned && continue
34
22
iv = vrename[v]
35
23
ie = erename[e]
36
24
iv == 0 && continue
@@ -47,8 +35,9 @@ function tearing_sub(expr, dict, s)
47
35
end
48
36
49
37
function tearing_substitution (sys:: AbstractSystem ; simplify= false )
50
- ( has_substitutions ( sys) && ! isnothing ( get_substitutions (sys))) || return sys
38
+ empty_substitutions ( sys) && return sys
51
39
subs = get_substitutions (sys)
40
+ solved = Dict (eq. lhs => eq. rhs for eq in subs)
52
41
neweqs = map (equations (sys)) do eq
53
42
if isdiffeq (eq)
54
43
return eq. lhs ~ tearing_sub (eq. rhs, solved, simplify)
@@ -66,6 +55,7 @@ function tearing_substitution(sys::AbstractSystem; simplify=false)
66
55
eq
67
56
end
68
57
@set! sys. eqs = neweqs
58
+ @set! sys. substitutions = nothing
69
59
end
70
60
71
61
function solve_equation (eq, var, simplify)
@@ -97,13 +87,12 @@ function tearing_reassemble(sys, var_eq_matching; simplify=false)
97
87
98
88
# Solve solvable equations
99
89
for (iv, ieq) in enumerate (var_eq_matching)
100
- # is_solvable(ieq, iv) || continue
101
- is_solvable (ieq, iv) || error (" unreachable reached" )
90
+ is_solvable (ieq, iv) || continue
102
91
push! (solved_equations, ieq); push! (solved_variables, iv)
103
92
end
104
- subgraph, submatching = substitution_graph (graph, slist, dlist , var_eq_matching)
105
- toporder = topological_sort_by_dfs (DiCMOBiGraph {true} (subgraph, submatching))
106
- substitutions = [solve_equation (eqs[solved_equations[i]], fullvars[solved_variables[i]], simplify) for i in toporder]
93
+ subgraph, submatching = substitution_graph (graph, solved_equations, solved_variables , var_eq_matching)
94
+ toporder = topological_sort_by_dfs (DiCMOBiGraph {true} (subgraph, complete ( submatching) ))
95
+ substitutions = Equation [solve_equation (eqs[solved_equations[i]], fullvars[solved_variables[i]], simplify) for i in toporder]
107
96
108
97
# Rewrite remaining equations in terms of solved variables
109
98
@@ -126,6 +115,7 @@ function tearing_reassemble(sys, var_eq_matching; simplify=false)
126
115
@set! sys. structure = s
127
116
@set! sys. eqs = neweqs
128
117
@set! sys. states = [s. fullvars[idx] for idx in 1 : length (s. fullvars) if ! isdervar (s, idx)]
118
+ @set! sys. observed = [observed (sys); substitutions]
129
119
@set! sys. substitutions = substitutions
130
120
return sys
131
121
end
0 commit comments