Skip to content

Commit 336796f

Browse files
committed
Use Bareiss to select the basis vectors
1 parent 0a44f6b commit 336796f

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

src/structural_transformation/partial_state_selection.jl

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,14 @@ function partial_state_selection_graph!(structure::SystemStructure, var_eq_match
140140
var_eq_matching
141141
end
142142

143-
function dummy_derivative_graph!(state::TransformationState)
143+
function dummy_derivative_graph!(state::TransformationState, jac=nothing)
144144
var_eq_matching = complete(pantelides!(state))
145145
complete!(state.structure)
146-
dummy_derivative_graph!(state.structure, var_eq_matching)
146+
# TODO: remove state when done
147+
dummy_derivative_graph!(state.structure, var_eq_matching, jac, state)
147148
end
148149

149-
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching)
150+
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, jac, state)
150151
@unpack eq_to_diff, var_to_diff, graph = structure
151152
diff_to_eq = invview(eq_to_diff)
152153
diff_to_var = invview(var_to_diff)
@@ -182,6 +183,7 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching)
182183
var_sccs = find_var_sccs(graph, var_eq_matching)
183184
eqcolor = falses(neqs)
184185
dummy_derivatives = Int[]
186+
col_order = Int[]
185187
for vars in var_sccs
186188
eqs = [var_eq_matching[var] for var in vars if var_eq_matching[var] !== unassigned]
187189
isempty(eqs) && continue
@@ -195,18 +197,35 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching)
195197
iszero(nrows) && break
196198
eqs_set = BitSet(eqs)
197199

198-
structural_rank = 0
199-
for var in vars
200-
pathfound = construct_augmenting_path!(rank_matching, invgraph, var, eq->eq in eqs_set, eqcolor)
201-
pathfound || continue
202-
push!(dummy_derivatives, var)
203-
structural_rank += 1
204-
structural_rank == nrows && break
200+
# TODO: making the algorithm more robust
201+
# 1. If the Jacobian is a integer matrix, use Bareiss to check
202+
# linear independence. (done)
203+
#
204+
# 2. If the Jacobian is a single row, generate pivots. (Dynamic
205+
# state selection.)
206+
#
207+
# 3. If the Jacobian is a polynomial matrix, use Gröbner basis (?)
208+
if jac !== nothing && (_J = jac(eqs, vars); all(x->unwrap(x) isa Integer, _J))
209+
J = Int.(unwrap.(_J))
210+
N = ModelingToolkit.nullspace(J; col_order) # modifies col_order
211+
rank = length(col_order)-size(N, 2)
212+
for i in 1:rank
213+
push!(dummy_derivatives, vars[col_order[i]])
214+
end
215+
else
216+
rank = 0
217+
for var in vars
218+
pathfound = construct_augmenting_path!(rank_matching, invgraph, var, eq->eq in eqs_set, eqcolor)
219+
pathfound || continue
220+
push!(dummy_derivatives, var)
221+
rank += 1
222+
rank == nrows && break
223+
end
224+
fill!(rank_matching, unassigned)
205225
end
206-
if structural_rank != nrows
226+
if rank != nrows
207227
@warn "The DAE system is structurally singular!"
208228
end
209-
fill!(rank_matching, unassigned)
210229

211230
# prepare the next iteration
212231
eqs = map(eq->diff_to_eq[eq], eqs)

src/structural_transformation/symbolics_tearing.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ the system is balanced.
291291
"""
292292
function dummy_derivative(sys)
293293
state = TearingState(sys)
294-
dds = dummy_derivative_graph!(state)
294+
function jac(eqs, vars)
295+
symeqs = EquationsView(state)[eqs]
296+
Symbolics.jacobian((x->x.rhs).(symeqs), state.fullvars[vars])
297+
end
298+
dds = dummy_derivative_graph!(state, jac)
295299
EquationsView(state), state.fullvars[dds]
296300
end

0 commit comments

Comments
 (0)