Summary
Add classical control theory analysis capabilities across four existing packages, bridging the gap between GDS's structural specification strengths and the numerical/frequency-domain analysis that control engineers expect. Zero new third-party dependencies — everything fits within existing extras.
Motivation
GDS can specify, compose, verify, and simulate control systems structurally. The symbolic subpackage already computes LinearizedSystem (A, B, C, D) via Jacobian linearization. But the framework stops there — it cannot answer "is this system stable?", "what are the gain/phase margins?", "what does the Bode plot look like?", or "what LQR gain matrix should I use?". These are table-stakes questions for any control practitioner.
The key insight is that LinearizedSystem.A/B/C/D (already list[list[float]]) is the exact gateway to the entire classical control stack. Every capability below consumes those matrices.
Architecture
Four layers, matching existing package responsibilities:
┌─────────────────────────────────────┐
│ gds-domains/symbolic │
│ (SymPy — mathematical objects) │
│ │
│ linearize.py [exists] │
│ transfer.py [new — #199] │
│ delay.py [new — #200] │
└──────────┬───────────┬──────────────┘
│ │
list[list[float]]│ │ SymPy exprs
│ │
┌─────────────────────▼──┐ ┌────▼──────────────────┐
│ gds-analysis │ │ gds-proof │
│ (scipy — numerical) │ │ (SymPy — formal) │
│ │ │ │
│ linear.py [#201] │ │ lyapunov.py [#203] │
│ response.py [#202] │ │ │
└──────────┬─────────────┘ └────────────────────────┘
│
plain arrays (freqs, mag, phase)
│
┌──────────▼─────────────┐
│ gds-viz │
│ (matplotlib — plots) │
│ │
│ frequency.py [#204] │
│ response.py [#204] │
└────────────────────────┘
Interface contract: No numpy arrays cross package boundaries. All inter-package data is list[float] / list[list[float]]. Numpy/scipy are internal implementation details.
Child Issues
#
Package
New File
Scope
Deps
Tier
#199
gds-domains
symbolic/transfer.py
Transfer functions, poles/zeros, controllability/observability, sensitivity functions
[symbolic] (existing)
1
#200
gds-domains
symbolic/delay.py
Padé approximation for time delays
[symbolic] (existing)
2
#201
gds-analysis
linear.py
Eigenvalue stability, frequency response, margins, discretization, LQR, Kalman
[continuous] (existing)
1
#202
gds-analysis
response.py
Step/impulse response computation + time-domain metrics
[continuous] (existing)
1
#203
gds-proof
analysis/lyapunov.py
Lyapunov stability proofs, quadratic Lyapunov, passivity certificates
sympy (existing hard dep)
2
#204
gds-viz
frequency.py + response.py
Bode, Nyquist, Nichols, root locus, step/impulse response plots
[control] new extra
1
Dependency Graph Between Issues
#199 (transfer functions)
↑
├── #200 (delay — uses TransferFunction)
├── #201 (linear analysis — uses TF for margins)
│ ↑
│ └── #204 (viz — plots data from #201)
│
└── #204 (viz — root locus uses TF coefficients)
#202 (response metrics) — independent, can start immediately
↑
└── #204 (viz — annotates plots with metrics from #202)
#203 (Lyapunov proofs) — independent, can start immediately
Suggested Implementation Order
gds-domains/symbolic: transfer functions, poles/zeros, and sensitivity functions #199 Transfer functions — foundational; gds-domains/symbolic: Padé approximation for time delay modeling #200 , gds-analysis: numerical linear systems analysis, discretization, and controller synthesis #201 , gds-viz: frequency response and time-domain response plots #204 depend on this
gds-analysis: step and impulse response computation with time-domain metrics #202 Response metrics — independent, trivial, immediately useful for existing examples
gds-analysis: numerical linear systems analysis, discretization, and controller synthesis #201 Numerical linear analysis — eigenvalues + frequency response + discretization + LQR
gds-viz: frequency response and time-domain response plots #204 Control plots — visualize the numbers from gds-analysis: numerical linear systems analysis, discretization, and controller synthesis #201 and gds-analysis: step and impulse response computation with time-domain metrics #202
gds-proof: Lyapunov stability proofs and passivity certificates #203 Lyapunov proofs — independent, extends gds-proof
gds-domains/symbolic: Padé approximation for time delay modeling #200 Time delay — standalone, lower priority
Note: #202 and #203 have no upstream dependencies and can be implemented in parallel with #199 .
End-to-End Workflow (Target State)
from gds_domains .symbolic import SymbolicControlModel
from gds_domains .symbolic .transfer import ss_to_tf , poles
from gds_analysis .linear import frequency_response , lqr , discretize , is_stable
from gds_analysis .response import step_response , step_response_metrics
from gds_viz .frequency import bode_plot , root_locus_plot
# Existing: define + linearize
model = SymbolicControlModel (...)
ls = model .linearize (x0 = [0.0 ], u0 = [0.0 ], param_values = {...})
# New Layer 1: symbolic analysis
tf = ss_to_tf (ls )
print (poles (tf )) # → [(-1+2j), (-1-2j)]
# New Layer 2: numerical analysis
assert is_stable (ls .A )
omega , mag , phase = frequency_response (ls .A , ls .B , ls .C , ls .D )
K , S , E = lqr (ls .A , ls .B , Q = ..., R = ...)
Ad , Bd , Cd , Dd = discretize (ls .A , ls .B , ls .C , ls .D , dt = 0.01 )
t , y = step_response (ls .A , ls .B , ls .C , ls .D , t_span = (0 , 10 ))
metrics = step_response_metrics (t , y , setpoint = 1.0 )
# New Layer 3: visualization
bode_plot (omega , mag , phase )
root_locus_plot (tf .num , tf .den )
MATLAB Tech Talk Concepts Addressed
Video
Concepts Covered
Issues
1 — Everything About Control Theory
Stability analysis, LQR, Kalman filter
#201 , #203
2 — Transfer Functions
S-domain, poles/zeros, root locus
#199 , #204
3 — Step Response
Rise time, overshoot, settling time, steady-state error
#202 , #204
4 — Bode/Nyquist/Nichols
Frequency response, gain/phase margin
#201 , #204
5 — Transfer Function in Code
Discretization (Tustin, ZOH, Euler)
#201
7 — Gang of Six
Sensitivity functions, loop shaping
#199
8 — Passivity
Lyapunov stability, energy-based proofs
#203
9 — Gain Scheduling
Multi-point linearization + LQR
#201
10 — Notch Filters
Transfer function composition
#199 , #204
11 — Time Delay
Padé approximation, phase lag
#200
12 — Padé Approximations
Rational polynomial delay model
#200
13 — Non-Minimum Phase
RHP zero detection
#199 , #204
14 — Z-Transform
Discretization bridge
#201
Out of Scope
MPC — needs QP/NLP solver (cvxpy, casadi); real new dependency
HIL testing — runtime/hardware concern
Auto-code generation — potential future for gds-interchange
Requirements DB / ReqIF — document management
Summary
Add classical control theory analysis capabilities across four existing packages, bridging the gap between GDS's structural specification strengths and the numerical/frequency-domain analysis that control engineers expect. Zero new third-party dependencies — everything fits within existing extras.
Motivation
GDS can specify, compose, verify, and simulate control systems structurally. The
symbolicsubpackage already computesLinearizedSystem(A, B, C, D) via Jacobian linearization. But the framework stops there — it cannot answer "is this system stable?", "what are the gain/phase margins?", "what does the Bode plot look like?", or "what LQR gain matrix should I use?". These are table-stakes questions for any control practitioner.The key insight is that
LinearizedSystem.A/B/C/D(alreadylist[list[float]]) is the exact gateway to the entire classical control stack. Every capability below consumes those matrices.Architecture
Four layers, matching existing package responsibilities:
Interface contract: No numpy arrays cross package boundaries. All inter-package data is
list[float]/list[list[float]]. Numpy/scipy are internal implementation details.Child Issues
gds-domainssymbolic/transfer.py[symbolic](existing)gds-domainssymbolic/delay.py[symbolic](existing)gds-analysislinear.py[continuous](existing)gds-analysisresponse.py[continuous](existing)gds-proofanalysis/lyapunov.pygds-vizfrequency.py+response.py[control]new extraDependency Graph Between Issues
Suggested Implementation Order
Note: #202 and #203 have no upstream dependencies and can be implemented in parallel with #199.
End-to-End Workflow (Target State)
MATLAB Tech Talk Concepts Addressed
Out of Scope