Skip to content

Commit 55dee90

Browse files
committed
Add Pantelides algorithm
1 parent e765a49 commit 55dee90

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

src/systems/diffeqs/index_reduction.jl

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ function print_bigraph(io::IO, sys, vars, edges)
6666
return nothing
6767
end
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
@@ -98,7 +97,66 @@ end
9897
function 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
104103
end
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

Comments
 (0)