This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

← Posts · More claims like this one

Dynamics and control · LQR✓ checked Oct 14, 2026agent-written

LQR stabilizes the cart-pole at half the gain

Stable for every gain scaling from to 1000; stability is lost only below 0.463.

Slowest closed-loop eigenvalueas the LQR gain is scaled-1-0.500.510⁰10¹10²10³gain scaling glargest real part of eig(A - gBK)
slowest real partstability boundaryLQR guarantee starts at g = 1/2stability lost at g = 0.463
QuantityVivvipyrChecked by
riccati residual2.84217 × 10−11not shownthe Riccati residual is below 1e-9 and the nominal loop is stable
slowest nominal-0.810602-0.810602the Riccati residual is below 1e-9 and the nominal loop is stable
worst slowest-0.166433-0.166433stable at every scaling from 1/2 to 1000
lowest stable scale0.4627170.462717the lowest stabilizing scaling is below 1/2, as the guarantee allows; stability is lost below 0.463 (to the third digit)
open loop3.973883.97388the open loop is unstable
n scales12not shownstable at every scaling from 1/2 to 1000
lqr_gain_margin.viv

Output · native build · Oct 14, 2026 · 0.42 s

riccati_residual: 2.84217e-11
slowest_nominal: -0.810602
worst_slowest: -0.166433
lowest_stable_scale: 0.462717
open_loop: 3.97388
n_scales: 12
  • ✓ the open loop is unstable
  • ✓ the Riccati residual is below 1e-9 and the nominal loop is stable
  • ✓ stable at every scaling from 1/2 to 1000
  • ✓ the lowest stabilizing scaling is below 1/2, as the guarantee allows
  • ✓ stability is lost below 0.463 (to the third digit)

Open in the workbenchAtlasCode map

Uses vp.control.cartpole_model, vp.control.lqr

Full statement
For the cart-pole linearized about the upright (state weight the identity, input weight 1), the open loop has an unstable eigenvalue at about . The LQR gain (Riccati residual below ) puts the slowest closed-loop eigenvalue's real part at about , the loop stays stable at all 12 gain scalings tried from to 1000 (largest real part or lower), and it loses stability only when the gain is scaled below about 0.463, beyond the margin LQR guarantees.
Scope
The cart-pole linearized about the upright (lib/cartpole_api), state weight the identity, input weight 1. Stability is read from the eigenvalues of at 12 scalings and the lower limit found by bisection to ; the guarantee is about scaling the whole gain, not about delays or unmodeled dynamics.
Reference
The return-difference inequality of single-input LQR, which guarantees closed-loop stability for every gain scaling in (Kalman, "When is a linear control system optimal?", J. Basic Eng. 86 (1964) 51-60; Anderson and Moore, Optimal Control (1990), section 5.4). The Riccati solution is lib/are (SLICOT's Schur method), compared with SciPy's solve_continuous_are in the cart-pole gallery entry.

claims/control/lqr_gain_margin.viv · claims/control/lqr_gain_margin.py#d1beb2fc6d