@@ -66,8 +66,7 @@ function print_bigraph(io::IO, sys, vars, edges)
6666 return nothing
6767end
6868
69-
70- function matching_equation! (edges, i, assign, active, vcolor= falses (length (active)), ecolor= falses (length (edges)))
69+ function match_equation! (edges, i, assign, active, vcolor= falses (length (active)), ecolor= falses (length (edges)))
7170 # `edge[active]` are active edges
7271 # i: equations
7372 # j: variables
@@ -88,7 +87,7 @@ function matching_equation!(edges, i, assign, active, vcolor=falses(length(activ
8887 # color the variable
8988 vcolor[j] = true
9089 if match_equation! (edges, assign[j], assign, active, vcolor, ecolor)
91- assign[v ] = i
90+ assign[j ] = i
9291 return true
9392 end
9493 end
9897function matching (edges, nvars, active= trues (nvars))
9998 assign = zeros (Int, nvars)
10099 for i in 1 : length (edges)
101- matching_equation ! (edges, i, assign, active)
100+ match_equation ! (edges, i, assign, active)
102101 end
103102 return assign
104103end
104+
105+ function pantelides (sys:: ODESystem )
106+ edges, fullvars, vars_asso = sys2bigraph (sys)
107+ return pantelides! (edges, fullvars, vars_asso)
108+ end
109+
110+ function pantelides! (edges, vars, vars_asso)
111+ neqs = length (edges)
112+ nvars = length (vars)
113+ assign = zeros (Int, nvars)
114+ eqs_asso = fill (0 , neqs)
115+ neqs′ = neqs
116+ for k in 1 : neqs′
117+ i = k
118+ pathfound = false
119+ iter = 0
120+ while ! pathfound && iter < 3
121+ iter += 1
122+ # run matching on (dx, y) variables
123+ active = vars_asso .== 0
124+ vcolor = falses (nvars)
125+ ecolor = falses (neqs)
126+ pathfound = match_equation! (edges, i, assign, active, vcolor, ecolor)
127+ if ! pathfound
128+ # for every colored V-node j
129+ for j in eachindex (vcolor); vcolor[j] || continue
130+ # introduce a new variable
131+ nvars += 1
132+ push! (vars_asso, 0 )
133+ vars_asso[j] = nvars
134+ push! (assign, 0 )
135+ end
136+
137+ # for every colored E-node l
138+ for l in eachindex (ecolor); ecolor[l] || continue
139+ neqs += 1
140+ # create new E-node
141+ push! (edges, copy (edges[l]))
142+ # create edges from E-node `neqs` to all V-nodes `j` and
143+ # `vars_asso[j]` s.t. edge `(l-j)` exists
144+ for j in edges[l]
145+ if ! (vars_asso[j] in edges[neqs])
146+ push! (edges[neqs], vars_asso[j])
147+ end
148+ end
149+ push! (eqs_asso, 0 )
150+ eqs_asso[l] = neqs
151+ end
152+
153+ # for every colored V-node j
154+ for j in eachindex (vcolor); vcolor[j] || continue
155+ assign[vars_asso[j]] = eqs_asso[assign[j]]
156+ end
157+ i = eqs_asso[i]
158+ end # if !pathfound
159+ end # while !pathfound
160+ end # for k in 1:neqs′
161+ return assign, vars_asso, eqs_asso
162+ end
0 commit comments