Skip to content

Jc/parallel faces polyhedral - #43

Merged
JulienCalbert merged 15 commits into
masterfrom
jc/parallel-faces-polyhedral
Oct 14, 2026
Merged

JulienCalbert merged 15 commits into
masterfrom
jc/parallel-faces-polyhedral

Conversation

@JulienCalbert

Copy link
Copy Markdown
Collaborator

No description provided.

PolyhedralTemplate becomes ParallelFacesPolyhedralTemplate, after the
polytopes with pairs of parallel faces of Athanasopoulos & Jungers, eq. (10).
The templates page gains a classes and solvers table and describes the two
polyhedral templates side by side; test comments say what is tested.
@codecov

codecov Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.98113% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.85%. Comparing base (3192b42) to head (371c3d6).

Files with missing lines Patch % Lines
src/problems/abstract.jl 72.72% 3 Missing ⚠️
src/lifts/abstract.jl 87.50% 2 Missing ⚠️
src/lifts/catalogue/sum.jl 92.00% 2 Missing ⚠️
src/problems/catalogue/stability.jl 91.30% 2 Missing ⚠️
...c/templates/catalogue/parallel_faces_polyhedral.jl 94.28% 2 Missing ⚠️
src/graphs/queries.jl 95.00% 1 Missing ⚠️
src/graphs/simulation.jl 87.50% 1 Missing ⚠️
src/problems/catalogue/safety.jl 95.83% 1 Missing ⚠️
src/problems/certificate.jl 96.42% 1 Missing ⚠️
src/templates/abstract.jl 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #43      +/-   ##
==========================================
- Coverage   96.88%   96.85%   -0.03%     
==========================================
  Files          49       49              
  Lines        1443     1368      -75     
==========================================
- Hits         1398     1325      -73     
+ Misses         45       43       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Every operation on a graph is a lift, as in the papers: the splits and
products move to src/lifts/catalogue as ForwardSplitLift, BackwardSplitLift,
ForwardProductLift, BackwardProductLift, PathDependentLift and ProductLift.
Refined merges into Lifted, DualRefinement into DualLift. The split at a node
is Ninite & Jungers' forward lift, Def. 3, one copy per successor.

src/refinements holds the algorithms: TightNodeSplitting (Ninite & Jungers,
Algorithm 1, started from the dual De Bruijn graph of order 1),
BestTightEdgeLifting (Athanasopoulos & Jungers, Example 2) and Hierarchy,
over one loop through next_graph and initial_graph. The strategy and select
keywords become algorithm. Docs gain a Lifts page; comparison moves after
refinement.
The operations exist to state what a lift requires of a template, so they
live in src/lifts/operations.jl. The generic dual and its docstring move to
src/graphs/dual.jl, the first file that defines a dual.
The combination of node values (minimum, maximum, or minimum over observer
states of maxima) depends on the graph alone and moves to src/graphs/common.jl.
The public common stays unchanged in src/problems/abstract.jl, next to
node_value and the certificate call, and evaluates each node function once.
Only the module file is left at the top of src/.
The edge condition is a decrease condition in the papers (Ninite & Jungers;
Athanasopoulos & Jungers): a Lyapunov function decreasing at rate gamma^p for
stability, a barrier not increasing for safety. domination_slack becomes
decrease_slack accordingly.
common_graph is the De Bruijn graph of order 0: de_bruijn now accepts order 0
and common_graph calls it, in de_bruijn.jl. The combination rule behind common
is the observer theorem's, so it moves to observer.jl. Two files go.
- check_dynamics takes the system, like is_closed_under, and the copositive
  templates use is_positive instead of repeating it.
- tight_edges returns graph transitions, like every edge query.
- simulate calls the length of a run horizon in both methods.
- The mode matrices are checked once, by switched_system in both forms and by
  the problems; dual(system) checks for constrained switching explicitly.
- problems/abstract.jl splits into the interface, certificate.jl (accessors,
  common, what refine reads) and tight_edges.jl, as the tests already were.
- Tests for is_positive, mode_matrix, optimality_gap and the copositive check.
With every default, jsr_bound (rtol 1e-3) and is_jsr_exact (atol 1e-6) left no
edge tight, so Theorem 4 held vacuously and optimality_gap reported 0 for a
loose bound. At the optimum the tight subgraph keeps the rate (Ninite &
Jungers, Prop. 1) and so contains a cycle: is_jsr_exact now answers false
without one. The functions reading tight edges share one default atol, 1e-4,
as refine does.
- Each problem writes its edge condition once, in a private _edge_decrease
  that builds the model and measures the slacks; add_edge_constraint!, called
  by nothing generic, goes.
- One subset construction serves observer_graph and is_path_complete.
- Solves are checked with JuMP.is_solved_and_feasible (JuMP 1.20), so the sum
  lift no longer reads a constant of the problem layer.
- Optimal control checks its input matrices through _check_dimensions.
- Locals no longer hide public functions; unused argument, unread model key
  and node_list copies removed; graphs are built through empty_graph.
- Templates: add_nonnegativity! and the margin keyword of add_decrease! go;
  add_function_variables! makes the node function well defined, and
  is_applicable replaces check_dynamics. Integer node data no longer breaks
  the two polyhedral templates.
- Lifts: is_valid requires an applicable template and has no override; the
  min lift on the linear copositive template is read through its dual. Each
  local lift says whether it changes the graph, and compare accepts a word
  graph whose words are single modes.
- Graphs: two private aliases keep the adapter grep empty, alphabet is
  sorted, adjacency is indexed once, and a graph with no node is not
  path-complete.
- Systems: one gate for constrained switching. simulate promotes once over
  the run, so an integer system takes a real input. The closed loop moves to
  optimal_control.jl and gains a method along given modes.
- Problems: matrices are validated once, at construction; edge slacks are
  written once; refine refuses a problem without objective and edge slacks.
- Imports are declared once in the module file; comments and tests corrected,
  graph tests wrapped in modules.
A feasibility program solved by an interior-point solver such as Clarabel
ends inside the solution set, whose entries no small denominator reads, so
simulation(SumLift(), G3, G1) threw and compare with it. Generic positive
costs make the solution one vertex; rounding goes from coarse to fine in
BigInt, and the first integer matrix that passes the check is returned. Only
a proof of infeasibility means there is no simulation; any other status is
an error. Tests pin the capsule's matrices and run G3 against every capsule
graph with Clarabel.
A node without outgoing edges had neither a survivor nor a copy, so the
forward split deleted it, and the backward split deleted nodes without
incoming edges, at an edge and at a node alike. Athanasopoulos & Jungers'
Defs. 6-7 and Ninite & Jungers' Def. 3 keep them: only a node whose outgoing
edges are all given is replaced by its copies.
The programs are homogeneous, so the lower bound on the weights or on c only
fixes their scale, but at 1e-3 the solver's absolute tolerance showed in the
rate: on random positive systems the one-node graph certified up to 4e-6
below G_4 of the HSCC 2023 capsule, which cannot be. At 1 the gap is solver
precision, for the dual copositive, parallel-faces, conic and sum-of-squares
templates. A test file for the dual copositive template pins the case.
- The T-forward composition lift is Debauche's thesis Def. 7.58; Def. 10 of
  the NAHS paper covers T = 1 only. The backward one cites Def. 7.61.
- Thm. 8.1 states that the min lift decides the order, not that its
  simulation is the greatest relation, which follows from the definition.
  The max lift is the dual by Lemma 7.45 and decides the order by Thm. 8.5.
- The fold error no longer says outgoing for the backward product lift.
- The reference test credits Virginie Debauche and states where her code
  and ours differ outside the paper's assumptions.
@JulienCalbert
JulienCalbert merged commit ef55c0f into master Oct 14, 2026
9 checks passed
@JulienCalbert
JulienCalbert deleted the jc/parallel-faces-polyhedral branch October 14, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant