Skip to content

fix: HinfSyn Bk sign + 105 hardening tests from python-control audit#25

Merged
jamestjsp merged 2 commits intomainfrom
fix/hinfsyn-hardening-tests
Apr 5, 2026
Merged

fix: HinfSyn Bk sign + 105 hardening tests from python-control audit#25
jamestjsp merged 2 commits intomainfrom
fix/hinfsyn-hardening-tests

Conversation

@jamestjsp
Copy link
Copy Markdown
Owner

Summary

  • Fix sign error in HinfSyn controller constructionBk was missing negation, producing unstable closed-loop poles for plants with RHP eigenvalues
  • Add 105 hardening tests across 9 files, sourced from systematic audit of python-control's 100+ issues, 40+ PRs, test suites, 14 Jupyter notebooks, and 17 example scripts
  • Add python-control-audit.md documenting all findings with test vectors and MATLAB reference values

Bug fix

hinfsyn.go:156 — The DGKF central controller requires Bk = -Zp*L (observer gain L is stored with negative convention), but code had Bk = Zp*L. This masked itself on stable plants but failed on the Scherer et al. (IEEE TAC 1997) benchmark with open-loop poles at 1.69±2.50j.

New tests by area

File Count Coverage
hardening_test.go 22 Riccati CARE/DARE, LQR/LQE, symmetry, cross-terms, ill-conditioning
hardening_placement_test.go 10 Acker shape/MIMO, Place scipy 4-state, unstable plant, duality
hardening_feedback_test.go 11 Feedback stabilization, Series/Parallel, static gain, MIMO, TF roundtrip
hardening_gramian_test.go 13 MATLAB Gramians/HSV, H2/Hinf norms (MIMO), balanced reduction
hardening_response_test.go 10 Step integrator, DC gain, DT negative poles, non-minimum phase
hardening_lyapcanon_test.go 13 Lyapunov residuals, modal/companion forms, repeated eigenvalues
hardening_margin_test.go 12 GM/PM 3rd-order, phase unwrapping, DT margins, static gain
hardening_synthesis_test.go 5 Scherer H2 (published norm=7.7484), PVTOL 6-state LQR/Kalman
hardening_robust_test.go 9 Disk margins 5th-order, Type 2/3, bandwidth, block algebra

Key reference systems

  • PVTOL aircraft — 6-state, 2-input MIMO (Caltech CDS 110)
  • Scherer et al. — Published H2 norm = 7.748350599360575
  • Coupled spring-mass — 4-state with transmission zero
  • Inverted pendulum — Unstable, Nyquist N=-1

Test plan

  • All 105 new tests pass
  • All existing tests pass (1227 total)
  • HinfSyn Scherer benchmark now stable CL poles
  • No duplicate tests with existing suite (verified per-file)

🤖 Generated with Claude Code

jamestjsp and others added 2 commits April 4, 2026 18:00
The observer gain L is stored with negative sign convention:
L = -(Y*C2' + S2)*R2^{-1}. The DGKF central controller requires
Bk = -Zp*L to get positive observer correction, but the code had
Bk = Zp*L — missing the negation.

This produced controllers with unstable closed-loop poles for plants
with open-loop RHP eigenvalues (e.g., Scherer et al. IEEE TAC 1997
Example 7). Previously tested stable plants masked the sign error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Systematic audit of python-control issues (100+), PRs (40+), test
suites, Jupyter notebooks (14), and example scripts (17) to extract
edge cases, MATLAB-validated vectors, and numerical pitfalls.

Tests organized by functional area:
- hardening_test.go: Riccati, LQR/LQE, symmetry, cross-terms (22)
- hardening_placement_test.go: Acker, Place, Ctrb duality (10)
- hardening_feedback_test.go: Feedback, Series, Parallel, TF (11)
- hardening_gramian_test.go: MATLAB Gramians, HSV, H2/Hinf norms (13)
- hardening_response_test.go: Step, impulse, DC gain, c2d (10)
- hardening_lyapcanon_test.go: Lyapunov, modal/companion forms (13)
- hardening_margin_test.go: GM/PM, phase unwrap, DT margins (12)
- hardening_synthesis_test.go: Scherer H2 (norm=7.7484), PVTOL (5)
- hardening_robust_test.go: Disk margins, Type 2/3, bandwidth (9)

Key reference systems: PVTOL aircraft (6-state MIMO), Scherer et al.
IEEE TAC 1997 (published H2 norm), Skogestad mixed-sensitivity,
coupled spring-mass (transmission zero), inverted pendulum.

python-control-audit.md documents all findings with test vectors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jamestjsp jamestjsp merged commit e8e23de into main Apr 5, 2026
2 checks passed
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