Select dummy derivatives on merged Mattsson-Söderlind blocks so state_priority can act across matching-SCCs#103
Select dummy derivatives on merged Mattsson-Söderlind blocks so state_priority can act across matching-SCCs#103baggepinnen wants to merge 2 commits into
Conversation
…ching-SCCs The SCCs of the full Pantelides matching can be strictly finer than the blocks of the (differentiated equations) x (highest-derivative candidates) subproblem on which Mattsson-Soderlind selection is posed. A differentiated equation matched in one SCC but incident to candidate variables in another (e.g. a twice-differentiated connection alias) creates a singleton SCC whose candidate is demoted unconditionally, making state_priority silently ineffective and potentially forcing a state realization with singularities. Merge such SCCs with union-find before selection so the priority-sorted greedy demotion sees the full block. Also permute the integer Jacobian's columns when the candidates are priority-sorted, so bareiss col_order indexes the sorted variable list consistently. Fixes #101. Fixes #102. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
NOTE: see correction to this comment in the comment after Tested this on the MultibodyComponents suspension models (stacked with #99 + #100's family grouping):
For calibration: the no-#103 stack takes FullCar further than it has ever been — compiles, initialization residuals all finite, and every runtime linear block consistent (220×220 with rank 216 = the four corners' gauge dimensions, relres 1e-13; 568×568 full-rank, relres 1e-15). The remaining wall is the same integrator-level failure as HalfCar (FBDF: |
|
Correction to my previous comment: the FullCar OOM was not this PR. After adding an equation budget to #100's family grouping (
The two failures I attributed to #103 were (1) the unbudgeted #100 grouping (13.8 GB kernel kill — genuinely reproducible, but #100's bug, now fixed there) and (2) a re-run on a machine that at the time had only ~13 GB available. Classic bisect-under-confounders mistake — apologies for the noise. So: #103 is compile-neutral on both car models, behavior-neutral on HalfCar, and the merged dummy-derivative selection on FullCar produces the same state count (36). No scalability concern from these models. |
|
While this seems reasonable, I'm concerned it's masking a problem in how Pantelides ignore state priorities. I also think this might cause us to blow up the size of some SCCs and make tearing's job that much harder? Is this really the best solution, or can we:
Alias elimination would remove this equation, but both sides have a positive state priority so it doesn't. In such cases, is it valid to unconditionally replace (substitute) the lower priority variable for the higher priority one? I seem to recall doing so ran into issues, but can't recall what those issues were. |
I think this is problematic, I often use varying levels of positive priority to indicate preference and always want the highest one to win and any lower one to be optimally eliminated, even though it has positive priority |
|
Okay, I can make that change. What if we get two with equally high state priority? Arbitrary choice/tiebreaker with the |
|
Yeah if equal then canonical would be good. if we have the concept of |
Problem
Fixes #101. Fixes #102.
dummy_derivative_graph!consultsstate_priorityonly within each SCC offind_var_sccs(graph, var_eq_matching), but the SCC partition of the (priority-blind)Pantelides matching can be strictly finer than the blocks of the Mattsson–Söderlind
selection subproblem (differentiated equations × highest-derivative candidates). When a
differentiated equation matched in one SCC is incident to candidate variables in another
— e.g. a twice-differentiated connection alias
0 ~ D²(x) - D²(y)matched toD²(x)while
D²(y)belongs to a kinematic-loop SCC — the prioritized variable sits in asingleton SCC where demotion is unconditional.
state_priorityis then silentlyineffective, and the resulting state realization can be singular.
Concretely (#101): in a planar 2-link arm with joint coordinates at
state_priority = 10(or 100 — the value cannot matter) and body Cartesian variables at priority 1–2, the
Cartesian variables were selected as states together with an algebraic equation for a
joint angle whose Jacobian
cos(phi)is singular exactly at the example's targetconfiguration; solvers abort with dt → ε as tracking improves.
Fix
merge_dummy_derivative_blocks: afterfind_var_sccs, merge (union-find) SCCsthat are coupled through differentiated equations incident to dummy-derivative
candidates in other SCCs, using the same candidate filter as the selection loop.
The existing priority-sorted greedy demotion with augmenting-path feasibility then
runs per merged block — on a merged block that greedy selects a minimum-priority
basis of the transversal matroid, i.e. it provably keeps the highest-priority states
subject to structural validity. When nothing merges, the input is returned unchanged
(
===), so the common path is unaffected.vars[col_order[i]]indexes mismatched orders #102): when the candidates are priority-sorted, thepreviously-computed integer Jacobian is now column-permuted alongside (
J = J[:, var_perm]); bareiss'col_orderindexes into the sorted candidate list, so the twoorders must agree. This latent mismatch becomes reachable in practice once blocks can
merge (a merged block may have an all-integer Jacobian and non-uniform priorities).
Validation
On the motivating model (
TwoJointPlanarRobotPID, MultibodyComponents.jltwodofbranch; joint priorities 10, body priorities 1–2):
body.phi/w,body.r[2]/v[2]revolute1.phi/w,revolute2.phi/wRodas5PUnstableat t ≈ 2.2 (always)FBDFSweep of 12 PlanarMechanics models (pendula, wheels, slip models, sensors, balancing
robot, parallel kinematic robot): 11 pass with identical or better results.
ParallelKinematicRobotpreviously failed with astable_eachindexMethodError and nowsimulates successfully (the merged-block selection avoids the offending downstream code
path).
TwoTrackModelTestfails identically with and without this patch (pre-existing,unrelated: Infs/NaNs in runtime LU during
solve).New regression tests distill the pattern into 6-variable structural fixtures: the merge
test, end-to-end selections for both priority assignments (the swapped-priority case
passes on the unpatched code precisely because the old selection is priority-blind), and
a Jacobian-path case where the unpermuted
col_orderdemotes the priority-100 variable.Behavioral note
In models with non-uniform priorities (MTK always passes priorities), state selection may
change where SCCs now merge — by design, in favor of higher-priority states. For uniform
priorities the candidate ordering within a merged block is the concatenation of the
former per-SCC orders, so different-but-equally-valid dummy choices are possible in
models that previously had coupled blocks.
🤖 Generated with Claude Code