Skip to content

Commit 644d76c

Browse files
authored
Merge pull request #1829 from Keno/kf/verboseprint
Add verbose REPL printing for SystemStructure
2 parents 6ea9156 + 572aece commit 644d76c

File tree

3 files changed

+128
-5
lines changed

3 files changed

+128
-5
lines changed

src/bipartite_graph.jl

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,49 @@ end
191191
# Matrix whose only purpose is to pretty-print the bipartite graph
192192
struct BipartiteAdjacencyList
193193
u::Union{Vector{Int}, Nothing}
194+
highligh_u::Union{Set{Int}, Nothing}
195+
match::Union{Int, Unassigned}
194196
end
197+
function BipartiteAdjacencyList(u::Union{Vector{Int}, Nothing})
198+
BipartiteAdjacencyList(u, nothing, unassigned)
199+
end
200+
201+
struct HighlightInt
202+
i::Int
203+
highlight::Union{Symbol, Nothing}
204+
end
205+
Base.typeinfo_implicit(::Type{HighlightInt}) = true
206+
207+
function Base.show(io::IO, hi::HighlightInt)
208+
if hi.highlight !== nothing
209+
printstyled(io, hi.i, color = hi.highlight)
210+
else
211+
print(io, hi.i)
212+
end
213+
end
214+
195215
function Base.show(io::IO, l::BipartiteAdjacencyList)
196216
if l.u === nothing
197217
printstyled(io, '', color = :light_black)
198218
elseif isempty(l.u)
199219
printstyled(io, '', color = :light_black)
200-
else
220+
elseif l.highligh_u === nothing
201221
print(io, l.u)
222+
else
223+
function choose_color(i)
224+
i in l.highligh_u ? (i == l.match ? :light_yellow : :green) :
225+
(i == l.match ? :yellow : nothing)
226+
end
227+
if !isempty(setdiff(l.highligh_u, l.u))
228+
# Only for debugging, shouldn't happen in practice
229+
print(io, map(union(l.u, l.highligh_u)) do i
230+
HighlightInt(i, !(i in l.u) ? :light_red : choose_color(i))
231+
end)
232+
else
233+
print(io, map(l.u) do i
234+
HighlightInt(i, choose_color(i))
235+
end)
236+
end
202237
end
203238
end
204239

src/systems/systemstructure.jl

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,93 @@ function linear_subsys_adjmat(state::TransformationState)
403403
linear_equations, eadj, cadj)
404404
end
405405

406+
using .BipartiteGraphs: Label, BipartiteAdjacencyList
407+
struct SystemStructurePrintMatrix <:
408+
AbstractMatrix{Union{Label, Int, BipartiteAdjacencyList}}
409+
bpg::BipartiteGraph
410+
highlight_graph::BipartiteGraph
411+
var_to_diff::DiffGraph
412+
eq_to_diff::DiffGraph
413+
var_eq_matching::Union{Matching, Nothing}
414+
end
415+
Base.size(bgpm::SystemStructurePrintMatrix) = (max(nsrcs(bgpm.bpg), ndsts(bgpm.bpg)) + 1, 5)
416+
function compute_diff_label(diff_graph, i)
417+
di = i - 1 <= length(diff_graph) ? diff_graph[i - 1] : nothing
418+
ii = i - 1 <= length(invview(diff_graph)) ? invview(diff_graph)[i - 1] : nothing
419+
return Label(string(di === nothing ? "" : string(di, ''),
420+
di !== nothing && ii !== nothing ? " " : "",
421+
ii === nothing ? "" : string(ii, '')))
422+
end
423+
function Base.getindex(bgpm::SystemStructurePrintMatrix, i::Integer, j::Integer)
424+
checkbounds(bgpm, i, j)
425+
if i <= 1
426+
return (Label.(("#", "∂ₜ", "eq", "∂ₜ", "v")))[j]
427+
elseif j == 2
428+
return compute_diff_label(bgpm.eq_to_diff, i)
429+
elseif j == 4
430+
return compute_diff_label(bgpm.var_to_diff, i)
431+
elseif j == 1
432+
return i - 1
433+
elseif j == 3
434+
return BipartiteAdjacencyList(i - 1 <= nsrcs(bgpm.bpg) ?
435+
𝑠neighbors(bgpm.bpg, i - 1) : nothing,
436+
bgpm.highlight_graph !== nothing &&
437+
i - 1 <= nsrcs(bgpm.highlight_graph) ?
438+
Set(𝑠neighbors(bgpm.highlight_graph, i - 1)) :
439+
nothing,
440+
bgpm.var_eq_matching !== nothing &&
441+
(i - 1 <= length(invview(bgpm.var_eq_matching))) ?
442+
invview(bgpm.var_eq_matching)[i - 1] : unassigned)
443+
elseif j == 5
444+
return BipartiteAdjacencyList(i - 1 <= ndsts(bgpm.bpg) ?
445+
𝑑neighbors(bgpm.bpg, i - 1) : nothing,
446+
bgpm.highlight_graph !== nothing &&
447+
i - 1 <= ndsts(bgpm.highlight_graph) ?
448+
Set(𝑑neighbors(bgpm.highlight_graph, i - 1)) :
449+
nothing,
450+
bgpm.var_eq_matching !== nothing &&
451+
(i - 1 <= length(bgpm.var_eq_matching)) ?
452+
bgpm.var_eq_matching[i - 1] : unassigned)
453+
else
454+
@assert false
455+
end
456+
end
457+
406458
function Base.show(io::IO, mime::MIME"text/plain", s::SystemStructure)
407-
@unpack graph = s
408-
S = incidence_matrix(graph, Num(Sym{Real}(:×)))
409-
print(io, "Incidence matrix:")
410-
show(io, mime, S)
459+
@unpack graph, solvable_graph, var_to_diff, eq_to_diff = s
460+
if !get(io, :limit, true) || !get(io, :mtk_limit, true)
461+
print(io, "SystemStructure with ", length(graph.fadjlist), " equations and ",
462+
isa(graph.badjlist, Int) ? graph.badjlist : length(graph.badjlist),
463+
" variables\n")
464+
Base.print_matrix(io,
465+
SystemStructurePrintMatrix(complete(graph),
466+
complete(solvable_graph),
467+
complete(var_to_diff),
468+
complete(eq_to_diff), nothing))
469+
else
470+
S = incidence_matrix(graph, Num(Sym{Real}(:×)))
471+
print(io, "Incidence matrix:")
472+
show(io, mime, S)
473+
end
474+
end
475+
476+
struct MatchedSystemStructure
477+
structure::SystemStructure
478+
var_eq_matching::Matching
479+
end
480+
481+
function Base.show(io::IO, mime::MIME"text/plain", ms::MatchedSystemStructure)
482+
s = ms.structure
483+
@unpack graph, solvable_graph, var_to_diff, eq_to_diff = s
484+
print(io, "Matched SystemStructure with ", length(graph.fadjlist), " equations and ",
485+
isa(graph.badjlist, Int) ? graph.badjlist : length(graph.badjlist),
486+
" variables\n")
487+
Base.print_matrix(io,
488+
SystemStructurePrintMatrix(complete(graph),
489+
complete(solvable_graph),
490+
complete(var_to_diff),
491+
complete(eq_to_diff),
492+
complete(ms.var_eq_matching, nsrcs(graph))))
411493
end
412494

413495
end # module

test/structural_transformation/tearing.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ if VERSION >= v"1.6"
3030
@test occursin("Incidence matrix:", prt)
3131
@test occursin("×", prt)
3232
@test occursin("", prt)
33+
34+
buff = IOBuffer()
35+
io = IOContext(buff, :mtk_limit => false)
36+
show(io, MIME"text/plain"(), state.structure)
37+
prt = String(take!(buff))
38+
@test occursin("SystemStructure", prt)
3339
end
3440

3541
# u1 = f1(u5)

0 commit comments

Comments
 (0)