Skip to content

Commit e695beb

Browse files
jamestjspclaude
andcommitted
Initial release: Go library for linear state-space control systems
MIMO continuous/discrete LTI models with transport delays, transfer functions, frequency response, discretization, simulation, and model reduction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0 parents  commit e695beb

46 files changed

Lines changed: 22203 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: CI
2+
on: [push, pull_request]
3+
jobs:
4+
test:
5+
runs-on: ubuntu-latest
6+
steps:
7+
- uses: actions/checkout@v4
8+
- uses: actions/setup-go@v5
9+
with:
10+
go-version: '1.25'
11+
- run: go vet ./...
12+
- run: go test -v -count=1 -race ./...

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.test
2+
*.prof
3+
*.patch
4+
.DS_Store
5+
pprof_list.txt
6+
referance/

CLAUDE.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Controlsys
2+
3+
Go library for linear state-space control systems.
4+
5+
## Build & Test
6+
7+
```bash
8+
go test -v -count=1
9+
```
10+
11+
## Key Conventions
12+
13+
- gonum LAPACK uses **row-major** flat arrays (`a[row*n+col]`), not column-major like Fortran
14+
- Always test with non-symmetric A matrices (diagonal A hides transposition bugs)
15+
- No inline comments unless logic is counter-intuitive
16+
17+
## Performance
18+
19+
- Always benchmark before/after with `go test -bench=. -benchmem` and `benchstat`
20+
- Prefer `m.RawMatrix().Data` with stride-aware indexing over `At(i,j)`/`Set(i,j)`
21+
- Use `copy()` on raw slices for submatrix extraction, not element-wise loops
22+
- Pre-allocate buffers outside loops; reuse LAPACK work arrays across calls

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 James Joseph
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# controlsys
2+
3+
Go library for linear state-space control systems.
4+
5+
Supports continuous and discrete LTI models with MIMO capability.
6+
7+
## Install
8+
9+
```bash
10+
go get github.com/jamestjsp/controlsys
11+
```
12+
13+
> **Note:** This package depends on a [gonum fork](https://github.com/jamestjsp/gonum) for additional LAPACK routines. Add this to your `go.mod`:
14+
> ```
15+
> replace gonum.org/v1/gonum => github.com/jamestjsp/gonum v0.17.2-fork
16+
> ```
17+
18+
## Features
19+
20+
- **State-space & transfer function** representations with bidirectional conversion
21+
- **System interconnection:** series, parallel, feedback, append
22+
- **Minimal realization:** controllability/observability staircase reduction
23+
- **Transmission zeros & poles** via staircase decomposition
24+
- **Frequency response:** Bode plots, evaluation at arbitrary complex frequencies
25+
- **Discretization:** bilinear (Tustin) and zero-order hold (ZOH)
26+
- **Simulation:** discrete-time LTI step response
27+
- **Transport delays:** input/output/internal delays, Pade and Thiran approximations, LFT representation
28+
29+
## Quick Start
30+
31+
```go
32+
package main
33+
34+
import (
35+
"fmt"
36+
37+
"github.com/jamestjsp/controlsys"
38+
"gonum.org/v1/gonum/mat"
39+
)
40+
41+
func main() {
42+
// Double integrator: x'' = u
43+
A := mat.NewDense(2, 2, []float64{0, 1, 0, 0})
44+
B := mat.NewDense(2, 1, []float64{0, 1})
45+
C := mat.NewDense(1, 2, []float64{1, 0})
46+
D := mat.NewDense(1, 1, []float64{0})
47+
48+
sys, _ := controlsys.New(A, B, C, D, 0)
49+
50+
poles, _ := sys.Poles()
51+
fmt.Println("Poles:", poles)
52+
stable, _ := sys.IsStable()
53+
fmt.Println("Stable:", stable)
54+
55+
tf, _ := sys.TransferFunction(nil)
56+
fmt.Println("Transfer function:", tf.TF)
57+
}
58+
```
59+
60+
## API Overview
61+
62+
### System Construction
63+
64+
| Function | Description |
65+
|----------|-------------|
66+
| `New` | Create from A, B, C, D matrices |
67+
| `NewWithDelay` | Create with transport delays |
68+
| `NewGain` | Pure feedthrough (D only) |
69+
| `NewFromSlices` | Create from row-major flat arrays |
70+
71+
### Analysis
72+
73+
| Method | Description |
74+
|--------|-------------|
75+
| `Poles` | Eigenvalues of A |
76+
| `Zeros` | Transmission zeros |
77+
| `IsStable` | Stability check |
78+
| `FreqResponse` | H(jw) at given frequencies |
79+
| `Bode` | Magnitude/phase vs frequency |
80+
| `EvalFr` | Evaluate at arbitrary s |
81+
82+
### Transformation
83+
84+
| Function/Method | Description |
85+
|-----------------|-------------|
86+
| `TransferFunction` | State-space to transfer function |
87+
| `StateSpace` | Transfer function to state-space |
88+
| `Discretize` | Bilinear (Tustin) c2d |
89+
| `DiscretizeZOH` | Zero-order hold c2d |
90+
| `Undiscretize` | Bilinear d2c |
91+
| `Reduce` | Remove uncontrollable/unobservable states |
92+
| `MinimalRealization` | Shorthand for full reduction |
93+
| `AbsorbDelay` | Augment state to absorb discrete transport delays |
94+
| `Pade` | Replace delays with Pade rational approximation |
95+
96+
### Interconnection
97+
98+
| Function | Description |
99+
|----------|-------------|
100+
| `Series` | Cascade connection |
101+
| `Parallel` | Sum connection |
102+
| `Feedback` | Closed-loop with feedback |
103+
| `Append` | Block diagonal concatenation |
104+
| `SafeFeedback` | Feedback with automatic delay handling |
105+
106+
### Simulation
107+
108+
| Method | Description |
109+
|--------|-------------|
110+
| `Simulate` | Discrete-time response to input sequence |
111+
112+
## Core Algorithms
113+
114+
| Algorithm | Purpose |
115+
|-----------|---------|
116+
| Staircase decomposition | Transmission zeros via rank-revealing factorization |
117+
| Column-pivoting QR | Rank determination with incremental condition estimation |
118+
| Row-pivoting RQ | Dual rank-revealing factorization |
119+
| Controllability staircase | Subspace decomposition for reduction and transfer functions |
120+
121+
## License
122+
123+
MIT

0 commit comments

Comments
 (0)