Block library
Notes on imported neural models (ONNX / ONNXJax / PyTorch / TensorFlow):
- x64 at import.
import jaxonomyenables JAX 64-bit mode (jax_enable_x64) process-wide, so float32 artifacts see float64 inputs and silently compute in different arithmetic than they were trained and validated in. Cast explicitly at block boundaries:cast_outputs_to_dtype="float32"on the block,x.astype(jnp.float32)on upstream signals. - Discrete-time policies need a
ZeroOrderHold. A sample-and-hold controller exported from a discrete-time training loop (torch/NEUROMANCER-style) is otherwise re-evaluated at every ODE solver stage, silently destroying step-for-step parity with the exporting framework. Follow the policy block withZeroOrderHold(dt=ts)and pin the step grid withSimulatorOptions(max_major_step_length=ts, max_minor_step_size=ts)— with that, closed-loop parity is ~4e-8 over 400 steps on the two-tank benchmark.
jaxonomy.library
Saturate = _inject_saturate_limit_kwarg(Saturate)
module-attribute
Clip the input signal to a specified range.
Given an input signal u and upper and lower limits ulim and llim,
the output signal is:
y = max(llim, min(ulim, u))
where max and min are the element-wise maximum and minimum functions.
This is equivalent to y = clip(u, llim, ulim).
Optionally, the block can also be configured with "dynamic" limits, which will add input ports for time-varying upper and lower limits.
Input ports
(0) The input signal. (1) The upper limit, if dynamic limits are enabled. (2) The lower limit, if dynamic limits are enabled. (Will be indexed as 1 if dynamic upper limits are not enabled.)
Output ports
(0) The clipped output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
upper_limit
|
The upper limit of the input signal. Default is |
required | |
enable_dynamic_upper_limit
|
If True, then the upper limit can be set by an external signal. Default is False. |
required | |
lower_limit
|
The lower limit of the input signal. Default is |
required | |
enable_dynamic_lower_limit
|
If True, then the lower limit can be set by an external signal. Default is False. |
required | |
limit
|
T-115-followup-saturate-symmetric-kwarg: shorthand for the
symmetric case. |
required |
Events
The block will trigger an event when the input signal crosses either the upper or lower limit. For example, if the block is configured with static upper and lower limits and the input signal crosses the upper limit, then a zero-crossing event will be triggered.
T-115-followup-mode-flag
The mode kwarg unifies the smooth (differentiable) variant
previously exposed as :class:SoftSaturate. mode="hard"
(default) is byte-equivalent to the legacy behavior, including
zero-crossing event declaration. mode="smooth" dispatches to
:func:soft_saturate and does not declare zero-crossing events
(the smooth output has no discontinuity for the solver to catch).
The smooth path requires finite upper_limit / lower_limit
and a sharpness > 0 (defaults to 10.0).
Abs
Bases: FeedthroughBlock
Output the absolute value of the input signal.
Input ports
None
Output ports
(0) The absolute value of the input signal.
Events
An event is triggered when the output changes from positive to negative or vice versa.
Source code in jaxonomy/library/math_ops.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | |
Adder
Bases: ReduceBlock
Computes the sum/difference of the input.
The add/subtract operation can be switched by setting the operators parameter.
For example, a 3-input block specified as Adder(3, operators="+-+") would add
the first and third inputs and subtract the second input.
Input ports
(0..n_in-1) The input signals to add/subtract.
Output ports
(0) The sum/difference of the input signals.
Source code in jaxonomy/library/math_ops.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
Arithmetic
Bases: ReduceBlock
Performs addition, subtraction, multiplication, and division on the input.
The arithmetic operation is determined by setting the operators parameter.
For example, a 4-input block specified as Arithmetic(4, operators="+-*/") would:
- Add the first input,
- Subtract the second input,
- Multiply the third input,
- Divide by the fourth input.
Input ports
(0..n_in-1) The input signals for the specified arithmetic operations.
Output ports
(0) The result of the specified arithmetic operations on the input signals.
Source code in jaxonomy/library/math_ops.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | |
AugmentedStateEKF
Bases: LeafSystem
Extended Kalman Filter with augmented state for joint state and parameter estimation.
The block estimates both the plant state x and unknown parameters θ online by augmenting the state vector:
.. code-block:: text
z = [x; θ] (shape: nx + n_params)
with augmented dynamics and observation:
.. code-block:: text
z[n+1] = f_aug(z[n], u[n]) + noise
= [f(x[n], u[n], θ[n]); θ[n]] + [G_x w_x; w_θ]
y[n] = h(x[n], u[n], θ[n]) + v[n]
E(w_x) = E(w_θ) = E(v) = 0
Cov(w_x) = Q_x, Cov(w_θ) = Q_θ, Cov(v) = R
Parameters θ follow a random-walk model (θ[n+1] = θ[n] + w_θ).
Setting Q_theta small makes parameters quasi-constant; increasing it allows
tracking of slowly time-varying parameters.
All Jacobians are computed automatically via jax.jacfwd.
+--------------------+
--- u[n] ------>| |----> x_hat[n]
| AugmentedStateEKF |
--- y[n] ------>| |----> theta_hat[n]
+--------------------+
Input ports
(0) u : control vector at timestep n, shape (nu,) or scalar
(1) y : measurement vector at timestep n, shape (ny,) or scalar
Output ports
(0) x_hat : state estimate, shape (nx,)
(1) theta_hat : parameter estimate, shape (n_params,)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Sampling period. |
required | |
nx
|
int Dimension of the plant state x. |
required | |
n_params
|
int Dimension of the parameter vector θ. |
required | |
forward
|
Callable
Discrete-time state transition: |
required | |
observation
|
Callable
Observation function: |
required | |
G_x_func
|
Callable
Process-noise input matrix for states: |
required | |
Q_x_func
|
Callable
Process-noise covariance for states: |
required | |
Q_theta
|
array_like
Constant parameter diffusion covariance matrix |
required | |
R_func
|
Callable
Measurement noise covariance: |
required | |
x_hat_0
|
array_like
Initial state estimate, shape |
required | |
P_hat_0_x
|
array_like
Initial state covariance, shape |
required | |
theta_hat_0
|
array_like
Initial parameter estimate, shape |
required | |
P_hat_0_theta
|
array_like
Initial parameter covariance, shape |
required |
Example::
import jax.numpy as jnp
from jaxonomy import library
# Simple first-order system: x[n+1] = a*x[n] + b*u[n]
# where 'a' (decay rate) is unknown and must be estimated.
def forward(x, u, theta):
a = theta[0]
return jnp.array([a * x[0] + u[0]])
def observation(x, u, theta):
return jnp.array([x[0]])
aekf = library.AugmentedStateEKF(
dt=0.1,
nx=1,
n_params=1,
forward=forward,
observation=observation,
G_x_func=lambda t: jnp.eye(1),
Q_x_func=lambda t, x, u, th: jnp.array([[0.01]]),
Q_theta=jnp.array([[1e-4]]),
R_func=lambda t: jnp.array([[0.1]]),
x_hat_0=jnp.zeros(1),
P_hat_0_x=jnp.eye(1),
theta_hat_0=jnp.zeros(1),
P_hat_0_theta=jnp.eye(1),
)
Source code in jaxonomy/library/state_estimators/augmented_ekf.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
DiscreteStateType
Bases: NamedTuple
Internal filter state (both minus=predicted and plus=corrected estimates).
Source code in jaxonomy/library/state_estimators/augmented_ekf.py
124 125 126 127 128 129 130 | |
initialize(dt, nx, n_params, forward, observation, G_x_func, Q_x_func, Q_theta, R_func, x_hat_0, P_hat_0_x, theta_hat_0, P_hat_0_theta)
Called at context-creation time to store resolved parameters.
Source code in jaxonomy/library/state_estimators/augmented_ekf.py
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
Backlash
Bases: LeafSystem
Hysteretic nonlinearity modelling mechanical slack / backlash.
A Backlash(width) block has a single discrete state last_output
that tracks the most recent output value. At each sample tick the
update rule is::
delta = u - last_output
if delta > width/2: new_output = u - width/2
elif delta < -width/2: new_output = u + width/2
else: new_output = last_output
Equivalently, the output "follows" the input only after the input has
moved by more than width/2 from the last output; within that band
the output sticks. This is the standard model for gearbox slack /
actuator hysteresis: the input must take up the slack before the
output moves.
Differentiability: the per-step update is expressed via npa.where
on delta; the output is a continuous (piecewise-linear) function
of both u and width, so jax.grad w.r.t. width is
finite. The non-smooth "knee" at |delta| = width/2 has subgradient
0 (inside the band) or -sign(delta)/2 (outside) w.r.t.
width -- both finite, as required.
Input ports
(0) The driving input signal.
Output ports
(0) The hysteretic output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
Positive scalar; total hysteresis band width. |
1.0
|
|
dt
|
Periodic update sample time. Required: this is a discrete block. |
0.01
|
|
initial_output
|
Initial value of the output / discrete state.
Default |
0.0
|
Notes
For an exact match against a canonical discrete-time "Backlash" block
the discrete sample time must match. For a continuous hysteresis
approximation, choose dt much smaller than the dominant input
timescale; the block then tracks the input modulo the
width/2 slack with single-step latency.
Source code in jaxonomy/library/nonlinearities.py
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 | |
BatteryCell
Bases: LeafSystem
Dynamic electro-checmical Li-ion cell model.
Based on Tremblay and Dessaint (2009).
By using appropriate parameters, the cell model can be used to model a battery pack with the assumption that the cells of the pack behave as a single unit.
Parameters E0, K, A, below are abstract parameters used in the model presented in the reference paper. As described in the reference paper, these parameters can be extracted from typical cell manufacturer datasheets; see section 3. Section 3 also provides a table of example values for these parameters.
Input ports
(0) The current (A) flowing through the cell. Positive is discharge.
Output ports
(0) The voltage across the cell terminals (V) (1) The state of charge of the cell (normalized between 0 and 1)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
E0
|
float
|
described as "battery constant voltage (V)" by the reference paper. |
3.366
|
K
|
float
|
described as "polarization constant (V/Ah)" by the reference paper. |
0.0076
|
Q
|
float
|
battery capacity in Ah |
2.3
|
R
|
float
|
internal resistance (Ohms) |
0.01
|
A
|
float
|
described as "exponential zone amplitude (V)" by the reference paper. |
0.26422
|
B
|
float
|
described as "exponential zone time constant inverse (1/Ah)" by the reference paper. |
26.5487
|
initial_SOC
|
float
|
initial state of charge, normalized between 0 and 1. |
1.0
|
Source code in jaxonomy/library/battery_cell.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
BusCreator
Bases: LeafSystem
Pack n = len(field_names) signals into a single named-bus output.
The output is a collections.namedtuple (named "Bus") whose
fields are exactly field_names in declaration order. NamedTuples
are first-class JAX pytrees, so the bus signal flows through
jax.jit, vmap, and grad without any extra registration.
Pair with :class:BusSelector to pull individual fields back out
downstream. Use this when signals share a logical group identity
(e.g. ("position", "velocity", "acceleration") for a vehicle
state bus) and you would rather refer to them by name than by
positional Mux/Demux index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field_names
|
Tuple/list of strings — one name per input port, in declaration order. Must be unique, valid Python identifiers (NamedTuple constraint). |
required | |
field_units
|
Optional mapping from field name to :class: |
None
|
|
field_shapes
|
Optional mapping from field name to a JAX-style
shape tuple (T-117-followup-bus-array). When supplied, the
named field carries an array of the declared shape rather
than a scalar — useful for grouping e.g. an 8-element
thermocouple readout under a single |
None
|
Input ports
(0..n-1) — one port per field name; values are packed into
the corresponding slot of the output NamedTuple.
Output ports
(0) — the bus, a NamedTuple with fields field_names.
Source code in jaxonomy/library/routing.py
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | |
bus_type
property
The underlying NamedTuple class for this bus.
bus_unit
property
The compound :class:BusUnit for this bus, or None if
field_units was not supplied at construction time.
field_names
property
The tuple of field names in declaration / port order.
field_shapes
property
Mapping from field name to declared array shape tuple
(T-117-followup-bus-array). Fields default to scalar ()
when field_shapes is omitted at construction time.
BusMerge
Bases: LeafSystem
Merge two bus signals by union of fields (LeafSystem wrapper).
Wraps :func:merge_buses as a block for use inside a Diagram. The
two upstream bus signals are read from input ports 0 and 1; the
merged bus is produced on output port 0.
The merged-bus schema is fixed at construction time from
bus_spec_a and bus_spec_b so the output port can be declared
with a known NamedTuple type (and so the framework's pytree handling
sees a consistent type across context-build and trace time, matching
the T-117-fu-bus-namedtuple design for :class:BusCreator).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bus_spec_a
|
Schema of the first bus. Accepts a
:class: |
required | |
bus_spec_b
|
Schema of the second bus. Same forms as
|
required | |
on_collision
|
str
|
Policy for fields that appear in both schemas:
|
'error'
|
Input ports
(0) — bus_a (NamedTuple-shaped).
(1) — bus_b (NamedTuple-shaped).
Output ports
(0) — the merged bus, a NamedTuple whose fields are the
union of the two input schemas.
Source code in jaxonomy/library/routing.py
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | |
bus_type
property
The underlying NamedTuple class for the merged bus.
collisions
property
The tuple of field names that collided between the two
input schemas. Empty unless on_collision is "prefer_a"
or "prefer_b".
field_names
property
The tuple of merged field names, in output / declaration order.
on_collision
property
The collision-resolution policy in effect for this block.
BusPassthrough
Bases: LeafSystem
Identity copy of a bus signal — single input port, single output port.
The output is the input value, returned as-is. Pass-through semantics:
NamedTuple-shaped buses (as produced by :class:BusCreator /
:class:BusMerge) flow through unchanged, scalar/array signals
likewise. This block exists to give Diagrams an explicit "junction"
node for rewiring, debugging, or scheduler-boundary purposes; it
has no parameters and does no computation beyond forwarding.
Differentiable: jax.grad flows from the output back to the input
leaf-by-leaf (identity has Jacobian = identity), and the block is
JIT-traceable since the underlying op is a no-op closure return.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bus_unit
|
Optional :class: |
None
|
Input ports
(0) — the bus (or any) signal to forward.
Output ports
(0) — the same value, returned as-is.
Source code in jaxonomy/library/routing.py
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 | |
bus_unit
property
The :class:BusUnit propagated through this passthrough, or
None if no unit metadata was supplied at construction.
BusSelector
Bases: LeafSystem
Pull one named field out of a bus signal.
The bus input is expected to be a NamedTuple-shaped value (typically
produced by :class:BusCreator). The selected field is read with
plain getattr, so this block is the inverse of BusCreator
when wired correctly: BusSelector("a")(BusCreator(["a","b","c"])
(a, b, c)) == a.
Both getattr and the NamedTuple constructor are transparent to
JAX autodiff, so gradients flow cleanly from the selector output
back to the upstream input that filled the corresponding bus slot.
T-117-followup-bus-dot-path: field_name may contain dots to
descend into nested bus signals — e.g.
BusSelector("chassis.suspension.spring_force") extracts the
leaf in one block instead of three cascaded selectors. The path is
resolved via :func:operator.attrgetter, so each segment must
name a valid NamedTuple field at its level. Each segment is
validated as a Python identifier at construction time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
field_name
|
Name (or dot-separated path) of the bus field to
extract. Raises |
required | |
bus_unit
|
Optional :class: When |
None
|
Input ports
(0) — the bus signal (NamedTuple-shaped).
Output ports
(0) — the value of bus.<field_name>, optionally sliced
at slice_idx.
Source code in jaxonomy/library/routing.py
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | |
bus_unit
property
The :class:BusUnit describing the upstream bus, or
None if no unit metadata was supplied.
field_name
property
The name of the bus field this block selects.
slice_idx
property
The integer index into an array-valued bus field, or
None if the selector returns the field value as-is
(T-117-followup-bus-array).
BusUnit
dataclass
Compound unit carrying one :class:Unit per named bus field.
Attached to the output port of a :class:BusCreator (and the
matching input port of a :class:BusSelector) so that the
connect-time consistency check can verify each field's unit
individually.
Attributes:
| Name | Type | Description |
|---|---|---|
fields |
Mapping[str, Unit]
|
Mapping from bus field name to its :class: |
Source code in jaxonomy/framework/units.py
940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | |
field_unit(name)
Return the :class:Unit for name, or None if absent.
Used by :class:BusSelector to look up its output-port unit
when wired downstream of a unit-tagged bus.
Source code in jaxonomy/framework/units.py
987 988 989 990 991 992 993 | |
BusUpdate
Bases: LeafSystem
Replace one field of a bus signal with a new value.
Two-input / one-output LeafSystem. Input port 0 carries the upstream
bus (a NamedTuple-shaped value, typically produced by
:class:BusCreator). Input port 1 carries the new value for the
field named field_name. The output port is a fresh bus identical
to the input except that the field_name slot is replaced by the
new value. Field order is preserved exactly; all other fields are
forwarded unchanged.
Use this instead of the BusSelector-modify-BusCreator triplet when you only need to edit one field of a wide bus -- the block makes the intent explicit and avoids manually wiring N-1 passthrough edges.
Differentiable: the underlying op is NamedTuple construction over
getattr lookups on the input bus plus the new_value leaf, all
of which are transparent to jax.grad and jax.jit (same as
:class:BusCreator and :func:merge_buses).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bus_spec
|
Schema of the bus. Accepts a :class: |
required | |
field_name
|
The name of the field to replace. Must be one of the
names declared in |
required | |
bus_unit
|
Optional :class: |
None
|
Input ports
(0) — bus_in, the upstream bus signal (NamedTuple-shaped).
(1) — new_value, the value to put into the field_name
slot of the output bus.
Output ports
(0) — bus_out, a NamedTuple of the same shape as
bus_in with field_name replaced by new_value.
Source code in jaxonomy/library/routing.py
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | |
bus_type
property
The underlying NamedTuple class for the output bus.
bus_unit
property
The :class:BusUnit propagated through this update, or
None if no unit metadata was supplied at construction
(T-117-followup-bus-update-units-prop).
field_name
property
The name of the field this block replaces on each tick.
field_names
property
The tuple of bus field names, in declaration / output order.
Chirp
Bases: SourceBlock
Produces a linear chirp signal — matches :func:scipy.signal.chirp.
The output signal is cos(2π·f(t)·t + phi) with the linearly
swept frequency f(t) = f0 + (f1 − f0)·t/(2·stop_time). At
t=0 the instantaneous frequency is f0 Hz; at
t=stop_time it is f1 Hz.
See https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.chirp.html
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
f0
|
float
|
Frequency (Hz) at time t=0. |
required |
f1
|
float
|
Frequency (Hz) at time t=stop_time. |
required |
stop_time
|
float
|
Time to end the signal (seconds). |
required |
phi
|
float
|
Phase offset (radians). |
0.0
|
units
|
str | None
|
T-122-followup-chirp-hz-convention
— frequency-unit convention for |
'hz'
|
Input ports
None
Output ports
(0) The chirp signal.
Source code in jaxonomy/library/sources.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | |
Clock
Bases: SourceBlock
Source block returning simulation time.
Input ports
None
Output ports
(0) The simulation time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dtype
|
The data type of the output signal. The default is "None", which will default to the current default floating point precision |
None
|
Source code in jaxonomy/library/sources.py
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | |
Comparator
Bases: LeafSystem
Compare two signals using typical relational operators.
When using == and != operators, the block uses tolerances to determine if the expression is true or false.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operator
|
one of ("==", "!=", ">=", ">", ">=", "<") |
None
|
|
atol
|
the absolute tolerance value used with "==" or "!=" |
1e-05
|
|
rtol
|
the relative tolerance value used with "==" or "!=" |
1e-08
|
Input Ports
(0) The left side operand (1) The right side operand
Output Ports
(0) The result of the comparison (boolean signal)
Events
An event is triggered when the output changes from true to false or vice versa.
Source code in jaxonomy/library/logic.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
Conditional
Bases: LeafSystem
Container block that enables/disables a submodel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submodel
|
Callable
|
Callable taking |
required |
n_inputs
|
int
|
Number of non-enable inputs the submodel takes. Input port 0 is always the enable signal; ports 1..n_inputs carry the submodel's inputs in order. |
1
|
when_disabled
|
str
|
|
RESET
|
initial_value
|
Output value when disabled (reset or hold mode's initial state). Also used to infer output shape/dtype when the submodel has not been evaluated yet. |
0.0
|
|
name
|
Optional block name. |
required |
Source code in jaxonomy/library/conditional.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | |
Constant
Bases: LeafSystem
A source block that emits a constant value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
The constant value of the block. |
required | |
dtype
|
optional, T-038a-followup-other-blocks
|
If set, the constant value is cast to this dtype on output.
See |
None
|
units
|
(optional, T - 104 - followup - units - on - source - blocks)
|
If set, the output port advertises this :class: |
None
|
Input ports
None
Output ports
(0) The constant value.
Source code in jaxonomy/library/sources.py
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | |
ContinuousTimeInfiniteHorizonKalmanFilter
Bases: LeafSystem
Continuous-time Infinite Horizon Kalman Filter for the following system:
dot_x = A x + B u + G w
y = C x + D u + v
E(w) = E(v) = 0
E(ww') = Q
E(vv') = R
E(wv') = N = 0
Input ports
(0) u : continuous-time control vector (1) y : continuous-time measurement vector
Output ports
(1) x_hat : continuous-time state vector estimate
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
A
|
ndarray State transition matrix |
required | |
B
|
ndarray Input matrix |
required | |
C
|
ndarray Output matrix |
required | |
D
|
ndarray Feedthrough matrix |
required | |
G
|
ndarray Process noise matrix |
required | |
Q
|
ndarray Process noise covariance matrix |
required | |
R
|
ndarray Measurement noise covariance matrix |
required | |
x_hat_0
|
ndarray Initial state estimate |
required |
Source code in jaxonomy/library/state_estimators/continuous_time_infinite_horizon_kalman_filter.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
for_continuous_plant(plant, x_eq, u_eq, Q, R, G=None, x_hat_bar_0=None, name=None)
staticmethod
Obtain a continuous-time Infinite Horizon Kalman Filter system for a continuous-time plant after linearization at equilibrium point (x_eq, u_eq)
The input plant contains the deterministic forms of the forward and observation operators:
dx/dt = f(x,u)
y = g(x,u)
Note: Only plants with one vector-valued input and one vector-valued output are currently supported. Furthermore, the plant LeafSystem/Diagram should have only one vector-valued integrator.
A plant with disturbances of the following form is then considered following form:
dx/dt = f(x,u) + G w
y = g(x,u) + v
where:
`w` represents the process noise,
`v` represents the measurement noise,
and
E(w) = E(v) = 0
E(ww') = Q
E(vv') = R
E(wv') = N = 0
This plant with disturbances is linearized (only f and q) around the
equilibrium point to obtain:
d/dt (x_bar) = A x_bar + B u_bar + G w --- (C1)
y_bar = C x_bar + D u_bar + v --- (C2)
where,
x_bar = x - x_eq
u_bar = u - u_eq
y_bar = y - y_bar
y_eq = g(x_eq, u_eq)
A continuous-time Kalman Filter estimator for the system of equations (C1) and
(C2) is returned. This filter is in the x_bar, u_bar, and y_bar
states.
The returned system will have
Input ports
(0) u_bar : continuous-time control vector relative to equilibrium point (1) y_bar : continuous-time measurement vector relative to equilibrium point
Output ports
(1) x_hat_bar : continuous-time state vector estimate relative to equilibrium point
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
a |
required | |
x_eq
|
ndarray Equilibrium state vector for discretization |
required | |
u_eq
|
ndarray Equilibrium control vector for discretization |
required | |
Q
|
ndarray Process noise covariance matrix. |
required | |
R
|
ndarray Measurement noise covariance matrix. |
required | |
G
|
ndarray
Process noise matrix. If |
None
|
|
x_hat_bar_0
|
ndarray Initial state estimate relative to equilibrium point. If None, an identity matrix is assumed. |
None
|
Source code in jaxonomy/library/state_estimators/continuous_time_infinite_horizon_kalman_filter.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
CoordinateRotation
Bases: LeafSystem
Computes the rotation of a 3D vector between coordinate systems.
Given sufficient information to construct a rotation matrix C_AB from orthogonal
coordinate system B to orthogonal coordinate system A, along with an input
vector x_B expressed in B-axes, this block will compute the matrix-vector
product x_A = C_AB @ x_B.
Note that depending on the type of rotation representation, this matrix may not be explicitly computed. The types of rotations supported are Quaternion, Euler Angles, and Direction Cosine Matrix (DCM).
By default, the rotations have the following convention:
-
Quaternion: The rotation is represented by a 4-component quaternion
q. The rotation is carried out by the productp_A = q⁻¹ * p_B * q, whereq⁻¹is the quaternion inverse ofq,*is the quaternion product, andp_Aandp_Bare the quaternion extensions of the vectorsx_Aandx_B, i.e.p_A = [0, x_A]andp_B = [0, x_B]. -
Roll-Pitch-Yaw (Euler Angles): The rotation is represented by the set of Euler angles ϕ (roll), θ (pitch), and ψ (yaw), in the "1-2-3" convention for intrinsic rotations. The resulting rotation matrix
C_AB(ϕ, θ, ψ)is the same as the product of the three single-axis rotation matricesC_AB = Cz(ψ) * Cy(θ) * Cx(ϕ).For example, if
Brepresents a fixed "world" frame with axesxyzandAis a body-fixed frame with axesXYZ, thenC_ABrepresents a rotation from the world frame to the body frame, in the following sequence:- Right-hand rotation about the world frame
x-axis byϕ(roll), resulting in the intermediate framex'y'z'withx' = x. - Right-hand rotation about the intermediate frame
y'-axis byθ(pitch), resulting in the intermediate framex''y''z''withy'' = y'. - Right-hand rotation about the intermediate frame
z''-axis byψ(yaw), resulting in the body frameXYZwithz = z''.
- Right-hand rotation about the world frame
-
Direction Cosine Matrix: The rotation is directly represented as a 3x3 matrix
C_AB. The rotation is carried out by the matrix-vector productx_A = C_AB @ x_B.
Input ports
(0): The input vector x_B expressed in the B-axes.
(1): (if enable_external_rotation_definition=True) The rotation
representation (quaternion, Euler angles, or cosine matrix) that defines
the rotation from B to A (or A to B if inverse=True).
Output ports
(0): The output vector x_A expressed in the A-axes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rotation_type
|
str
|
The type of rotation representation to use. Must be one of ("quaternion", "roll_pitch_yaw", "dcm"). |
required |
enable_external_rotation_definition
|
If |
True
|
|
inverse
|
If |
False
|
|
quaternion
|
Array
|
The quaternion representation of the rotation
if |
None
|
roll_pitch_yaw
|
Array
|
The Euler angles representation of the
rotation if |
None
|
direction_cosine_matrix
|
Array
|
The direction cosine matrix
representation of the rotation if |
None
|
Source code in jaxonomy/library/rotations.py
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
CoordinateRotationConversion
Bases: LeafSystem
Converts between different representations of rotations.
See CoordinateRotation block documentation for descriptions of the different rotation representations supported. This block supports conversion between quaternion, roll-pitch-yaw (Euler angles), and direction cosine matrix (DCM).
Note that conversions are reversible in terms of the abstract rotation, although creating a quaternion from a direction cosine matrix (and therefore creating a quaternion from roll-pitch-yaw sequence) results in an arbitrary sign assignment.
Input ports
(0): The input rotation representation.
Output ports
(1): The output rotation representation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversion_type
|
str
|
The type of rotation conversion to perform. Must be one of ("quaternion_to_euler", "quaternion_to_dcm", "euler_to_quaternion", "euler_to_dcm", "dcm_to_quaternion", "dcm_to_euler") |
required |
Source code in jaxonomy/library/rotations.py
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 | |
Counter
Bases: LeafSystem
Discrete counter that increments on rising edges of its trigger input.
The block samples a boolean/binary trigger signal every dt seconds.
On each rising edge (prev_trigger == False and current_trigger ==
True) the internal count advances by increment. When max_count
is set, the counter either saturates (clamps at max_count) or
wraps to 0 after the increment that hits / exceeds max_count,
according to reset_on_max.
Input ports
(0) Trigger signal — boolean / binary-valued.
Output ports
(0) Current count (integer, stored as int32).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_count
|
Starting count value at |
0
|
|
dt
|
Sample period (seconds) of the discrete update. |
required | |
increment
|
Amount to add to the count on each rising edge. Default |
1
|
|
max_count
|
Optional cap on the count. If |
None
|
|
reset_on_max
|
When |
False
|
Notes
Edge detection is the same simple "previous-sample-was-False,
current-sample-is-True" rule used by :class:EdgeDetection —
adequate for boolean triggers driven at the block's own sample
rate. For sub-sample-period precision use
ZeroCrossingTriggeredSubsystem together with this block.
The output is integer-typed and therefore non-differentiable in the strict sense; gradient-flow tests should not expect gradients with respect to the count itself.
Source code in jaxonomy/library/sources.py
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 | |
CrossProduct
Bases: ReduceBlock
Compute the cross product between the inputs.
See NumPy docs for details: https://numpy.org/doc/stable/reference/generated/numpy.cross.html
Input ports
(0) The first input vector. (1) The second input vector.
Output ports
(0) The cross product of the inputs.
Source code in jaxonomy/library/math_ops.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | |
CustomJaxBlock
Bases: LeafSystem
JAX implementation of the PythonScript block.
A few important notes and changes/limitations to this JAX implementation:
- For this block all code must be written using the JAX-supported subset of Python:
* Numerical operations should use jax.numpy = jnp instead of numpy = np
* Standard control flow is not supported (if/else, for, while, etc.). Instead
use lax.cond, lax.fori_loop, lax.while_loop, etc.
https://jax.readthedocs.io/en/latest/notebooks/Common_Gotchas_in_JAX.html#structured-control-flow-primitives
Where possible, NumPy-style operations like jnp.where or jnp.select should
be preferred to lax control flow primitives.
* Functions must be pure and arrays treated as immutable.
https://jax.readthedocs.io/en/latest/notebooks/Common_Gotchas_in_JAX.html#in-place-updates
Provided these assumptions hold, the code can be JIT compiled, differentiated,
run on GPU, etc.
- Variable scoping: the init_code and step_code are executed in the same scope,
so variables declared in the init_code will be available in the step_code
and can be modified in that scope. Internally, everything declared in
init_code is treated as a single state-like cache entry.
However, variables declared in the step_code will NOT persist between
evaluations. Users should think of step_code as a normal Python function
where locally declared variables will disappear on leaving the scope.
- Persistent variables (outputs and anything declared in init_code) must have
static shapes and dtypes. This means that you cannot declare x = 0.0 in
init_code and then later assign x = jnp.zeros(4) in step_code.
These changes mean that many older PythonScript blocks may not be backwards compatible.
Input ports
Variable number of input ports, one for each input variable declared in inputs.
The order of the input ports is the same as the order of the input variables.
Output ports
Variable number of output ports, one for each output variable declared in outputs.
The order of the output ports is the same as the order of the output variables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float
|
The discrete time step of the block, or None if the block is in agnostic time mode. |
None
|
init_script
|
str
|
A string containing Python code that will be executed
once when the block is initialized. This code can be used to declare
persistent variables that will be available in the |
''
|
user_statements
|
str
|
A string containing Python code that will be executed
once per time step (or per output port evaluation, in agnostic mode).
This code can use the persistent variables declared in |
''
|
finalize_script
|
str
|
A string containing Python code that will be executed
once when the simulation completes (or is otherwise torn down). This code
can use the persistent variables declared in |
''
|
accelerate_with_jax
|
bool
|
If True, the block will be JIT compiled. If False, the block will be executed in pure Python. This parameter exists for compatibility with UI options; when creating pure Python blocks from code (e.g. for testing), explicitly create the CustomPythonBlock class. |
True
|
time_mode
|
str
|
One of "discrete" or "agnostic". If "discrete", the block step code will be evaluated at peridodic intervals specified by "dt". If "agnostic", the block step code will be evaluated once per output port evaluation, and the block will not have a discrete time step. |
'discrete'
|
inputs
|
List[str]
|
A list of input variable names. The order of the input ports is the same as the order of the input variables. |
None
|
outputs
|
Mapping[str, Tuple[DTypeLike, ShapeLike]]
|
A dictionary mapping output variable names to a tuple of dtype and shape. The order of the output ports is the same as the order of the output variables. |
None
|
static_parameters
|
Mapping[str, Array]
|
A dictionary mapping parameter names to values. Parameters are treated as immutable and cannot be modified in the step code. Static parameters can't be used in ensemble simulations or optimization workflows. |
None
|
dynamic_parameters
|
Mapping[str, Array]
|
A dictionary mapping parameter names to values. Parameters are treated as immutable and cannot be modified in the step code. Dynamic parameters can be arrays or scalars, but must have static shapes and dtypes in order to support JIT compilation. |
None
|
Source code in jaxonomy/library/custom.py
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 | |
check_types(context, error_collector=None)
Test-compile the init and step code to check for errors.
Source code in jaxonomy/library/custom.py
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 | |
CustomPythonBlock
Bases: CustomJaxBlock
Container for arbitrary user-defined Python code.
Implemented to support legacy PythonScript blocks.
Not traceable (no JIT compilation or autodiff). The internal implementation and behavior of this block differs vastly from the JAX-compatible block as this block stores state directly within the Python instance. Objects and modules can be kept as discrete state.
Note that in "agnostic" mode, the step code will be evaluated once per output port evaluation. Because locally defined environment variables (in the init script) are preserved between evaluations, any mutation of these variables will be preserved. This can lead to unexpected behavior and should be avoided. Stateful behavior should be implemented using discrete state variables instead.
Warning: The finalize_script parameter is currently accepted but not executed. This is a known limitation. Do not rely on finalize_script for cleanup operations.
Source code in jaxonomy/library/custom.py
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 | |
exec_finalize()
Execute the finalize_script using the current persistent environment.
Called once at the end of the simulation via :meth:post_simulation_finalize.
The script runs in the same environment that was maintained throughout the
simulation, so all variables declared in init_script (and updated by
user_statements) are available.
Has no effect if finalize_script is empty.
Source code in jaxonomy/library/custom.py
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 | |
post_simulation_finalize()
Run finalize_script and then call the base-class hook.
Source code in jaxonomy/library/custom.py
1829 1830 1831 1832 | |
DMDForecaster
Bases: LeafSystem
Discrete-time predictor for a fitted (reduced) linear operator.
Propagates x[k+1] = A x[k] (+ B u[k]) and outputs y[k] = C x[k]
(C defaults to the identity, so the state itself is the output). This is
the online counterpart of :func:dmd / :func:dmdc: fit A (and B)
from snapshots offline, then drop the operator into a Jaxonomy diagram as a
jax-traceable discrete block that runs inside :func:jaxonomy.simulate.
An input port (and use of B) is created only when B is provided.
Input ports
(0) u[k]: control input, present iff B is given.
Output ports
(0) y[k] = C x[k].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
A
|
State operator |
required | |
B
|
Optional input operator |
None
|
|
C
|
Optional output operator |
None
|
|
dt
|
Sampling period of the discrete update. |
1.0
|
|
initial_state
|
Initial state |
None
|
Source code in jaxonomy/library/rom/dmd.py
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | |
DMDResult
dataclass
Exact-DMD spectral decomposition (Tu et al. 2014).
Attributes:
| Name | Type | Description |
|---|---|---|
modes |
Any
|
DMD modes |
eigenvalues |
Any
|
Discrete-time DMD eigenvalues |
amplitudes |
Any
|
Mode amplitudes |
A_tilde |
Any
|
Reduced |
Source code in jaxonomy/library/rom/dmd.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | |
DMDcResult
dataclass
DMD-with-control operators (Proctor, Brunton & Kutz 2016).
Attributes:
| Name | Type | Description |
|---|---|---|
A |
Any
|
Full |
B |
Any
|
Full |
A_tilde |
Any
|
Reduced |
B_tilde |
Any
|
Reduced |
basis |
Any
|
POD basis |
eigenvalues |
Any
|
Eigenvalues of |
Source code in jaxonomy/library/rom/dmd.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | |
DataSource
Bases: SourceBlock
Produces outputs from an imported data file (.csv, .npy, .npz).
CSV files are read with pandas when installed; otherwise NumPy is used.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Path to |
required |
column
|
Optional[str]
|
Optional. When set, selects the signal column(s) by name or index
string and overrides |
None
|
time_column
|
str
|
For CSV with |
'0'
|
data_columns
|
str
|
Column index, name, slice (e.g. |
'1'
|
Source code in jaxonomy/library/data_source.py
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | |
DeadZone
Bases: FeedthroughBlock
Generates zero output within a specified range.
Applies the following function:
[ input, input < -half_range
output = | 0, -half_range <= input <= half_range
[ input input > half_range
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
half_range
|
The range of the dead zone. Must be > 0. |
1.0
|
|
mode
|
|
'hard'
|
|
sharpness
|
Positive scalar; default |
10.0
|
|
output_shifted
|
|
False
|
Input ports
(0) The input signal.
Output ports
(0) The input signal modified by the dead zone.
Events
An event is triggered when the signal enters or exits the dead zone in either direction (hard mode only).
T-115-followup-deadzone-backlash
The mode kwarg unifies a smooth (differentiable) variant.
mode="hard" (default) is byte-equivalent to the legacy
behavior, including zero-crossing event declaration.
mode="smooth" dispatches to a sigmoid-blended formula
(see :func:soft_dead_zone) and does not declare zero-crossing
events.
T-115-followup-deadzone-bilinear
The output_shifted kwarg toggles between the legacy
Coulomb-style hard dead-zone (default, output jumps at the band
boundary) and the shifted-output variant
(continuous across the band boundary). Default False keeps
the block byte-equivalent to phase 1.
Source code in jaxonomy/library/nonlinearities.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | |
Decimator
Bases: LeafSystem
Fast-to-slow rate transition: subsample-and-hold at output_dt.
Implements a discrete-time decimator that samples its input on a
periodic clock at output_dt (the slow rate) and holds the value
until the next slow tick. The input is assumed to be running at
input_dt (the fast rate); the block is agnostic to the actual
upstream sampling, but the rate-mismatch detector uses this declared
pair to recognise the bridge.
Difference equation, with input u and output y::
x[k+1] = u[k * (output_dt / input_dt)]
y(t) = x[k], t in (t_k, t_k + output_dt)
Equivalent to a "Rate Transition (fast to slow)" block in its default ZOH-with-decimation mode.
Input ports
(0) The fast-rate input signal.
Output ports
(0) The slow-rate held signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_dt
|
Sample period of the upstream (fast) source. Used for documentation / the rate-mismatch detector; the block does not actually read the upstream clock. |
required | |
output_dt
|
Sample period of this block's output (slow rate).
Must satisfy |
required | |
initial_state
|
Initial output value held until the first slow tick fires. Default 0.0. |
0.0
|
|
mode
|
How to combine the input samples within each
|
'pick_last'
|
Notes (mode="mean" / mode="peak"):
The block declares a second periodic update at input_dt that
accumulates samples into a running buffer. At each slow tick
the emit-and-reset update fires first (declared before the
accumulator in __init__), reads the buffer, computes the
window result, and zeroes the buffer for the next window. At
simultaneous slow+fast ticks the emit therefore sees the full
window from the previous interval; the fast tick at the same
t then starts the next window with the current input as its
first sample.
Source code in jaxonomy/library/dynamics.py
1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 | |
Demultiplexer
Bases: LeafSystem
Split a vector signal into its components.
Input ports
(0) The vector signal to split.
Output ports
(0..n_out-1) The components of the input signal.
Source code in jaxonomy/library/routing.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
Demux
Bases: LeafSystem
Unstack a single array input into n_outputs separate signals.
This is the standard Demux block and the inverse of :class:Mux:
given a 1-D input [a, b, c] it produces three scalar outputs
a, b, c; given a 2-D input of shape (n_outputs, k)
it produces n_outputs outputs of shape (k,).
Internally this is index-based slicing along axis 0, which is fully differentiable through every output port (each output picks one slice of the input vector).
Input ports
(0) The vector or array signal to split. Its leading axis must
have length n_outputs.
Output ports
(0..n_outputs-1) The components of the input signal.
Source code in jaxonomy/library/routing.py
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
Derivative
Bases: LTISystem
Causal estimate of the derivative of a signal in continuous time.
This is implemented as a state-space system with matrices (A, B, C, D), which are then used to create a (first-order) LTISystem. Note that this only supports single-input, single-output derivative blocks.
The derivative is implemented as a filter with a filter coefficient of N,
which is used to construct the following proper transfer function:
H(s) = Ns / (s + N)
As N -> ∞, the transfer function approaches a pure differentiator. However, this system becomes increasingly stiff and difficult to integrate, so it is recommended to select a value of N based on the time scales of the system.
From the transfer function, scipy.signal.tf2ss is used to convert to
state-space form and create an LTISystem.
Input ports
(0) u: Input (scalar)
Output ports
(0) y: Output (scalar), estimating the time derivative du/dt
Source code in jaxonomy/library/linear_system.py
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | |
DerivativeDiscrete
Bases: LeafSystem
Discrete approximation to the derivative of the input signal w.r.t. time.'
By default the block uses a simple backward difference approximation:
y[k] = (u[k] - u[k-1]) / dt
However, the block can also be configured to use a recursive filter for a
better approximation. In this case the filter coefficients are determined
by the filter_type and filter_coefficient parameters. The filter is
a pair of two-element arrays a and b and the filter equation is:
a0*y[k] + a1*y[k-1] = b0*u[k] + b1*u[k-1]
Denoting the filter_coefficient parameter by N, the following filters are
available:
- "none": The default, a simple finite difference approximation.
- "forward": A filtered forward Euler discretization. The filter is:
a = [1, (N*dt - 1)] and b = [N, -N].
- "backward": A filtered backward Euler discretization. The filter is:
a = [(1 + N*dt), -1] and b = [N, -N].
- "bilinear": A filtered bilinear transform discretization. The filter is:
a = [(2 + N*dt), (-2 + N*dt)] and b = [2*N, -2*N].
Input ports
(0) The input signal.
Output ports
(0) The approximate derivative of the input signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
The time step of the discrete approximation. |
required | |
filter_type
|
One of "none", "forward", "backward", or "bilinear". This determines the type of filter used to approximate the derivative. The default is "none", corresponding to a simple backward difference approximation. |
'none'
|
|
filter_coefficient
|
The coefficient in the filter ( |
1.0
|
Source code in jaxonomy/library/dynamics.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
initialize_static_data(context)
Infer the size and dtype of the internal states
Source code in jaxonomy/library/dynamics.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
DirectShootingNMPC
Bases: NonlinearMPCIpopt
Implementation of nonlinear MPC with a direct shooting transcription and IPOPT as the NLP solver.
Input ports
(0) x_0 : current state vector. (1) x_ref : reference state trajectory for the nonlinear MPC. (2) u_ref : reference input trajectory for the nonlinear MPC.
Output ports
(1) u_opt : the optimal control input to be applied at the current time step as determined by the nonlinear MPC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
LeafSystem or Diagram The plant to be controlled. |
required | |
Q
|
Array State weighting matrix in the cost function. |
required | |
QN
|
Array Terminal state weighting matrix in the cost function. |
required | |
R
|
Array Control input weighting matrix in the cost function. |
required | |
N
|
int The prediction horizon, an integer specifying the number of steps to predict. Note: prediction and control horizons are identical for now. |
required | |
nh
|
int Number of minor steps to take within an RK4 major step. |
required | |
dt
|
float: Major time step, a scalar indicating the increment in time for each step in the prediction and control horizons. |
required | |
lb_u
|
Array Lower bound on the control input vector. |
None
|
|
ub_u
|
Array Upper bound on the control input vector. |
None
|
|
u_optvars_0
|
Array Initial guess for the control vector optimization variables in the NLP. |
None
|
Source code in jaxonomy/library/nmpc/direct_shooting_ipopt_nmpc.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
DirectTranscriptionNMPC
Bases: NonlinearMPCIpopt
Implementation of nonlinear MPC with direct transcription and IPOPT as the NLP solver.
Input ports
(0) x_0 : current state vector. (1) x_ref : reference state trajectory for the nonlinear MPC. (2) u_ref : reference input trajectory for the nonlinear MPC.
Output ports
(1) u_opt : the optimal control input to be applied at the current time step as determined by the nonlinear MPC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
LeafSystem or Diagram The plant to be controlled. |
required | |
Q
|
Array State weighting matrix in the cost function. |
required | |
QN
|
Array Terminal state weighting matrix in the cost function. |
required | |
R
|
Array Control input weighting matrix in the cost function. |
required | |
N
|
int The prediction horizon, an integer specifying the number of steps to predict. Note: prediction and control horizons are identical for now. |
required | |
nh
|
int Number of minor steps to take within an RK4 major step. |
required | |
dt
|
float: Major time step, a scalar indicating the increment in time for each step in the prediction and control horizons. |
required | |
lb_x
|
Array Lower bound on the state vector. |
None
|
|
ub_x
|
Array Upper bound on the state vector. |
None
|
|
lb_u
|
Array Lower bound on the control input vector. |
None
|
|
ub_u
|
Array Upper bound on the control input vector. |
None
|
|
x_optvars_0
|
Array Initial guess for the state vector optimization variables in the NLP. |
None
|
|
u_optvars_0
|
Array Initial guess for the control vector optimization variables in the NLP. |
None
|
Source code in jaxonomy/library/nmpc/direct_transcription_ipopt_nmpc.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | |
DiscreteClock
Bases: LeafSystem
Source block that produces the time sampled at a fixed rate.
The block maintains the most recently sampled time as a discrete state, provided to the output port during the following interval. Graphically, a discrete clock sampled at 100 Hz would have the following time series:
x(t) ●━
| ┆
.03 | ●━━━━○
| ┆
.02 | ●━━━━○
| ┆
.01 | ●━━━━○
| ┆
0 ●━━━━○----+----+----+-- t
0 .01 .02 .03 .04
The recorded states are the closed circles, which should be interpreted at index
n as the value seen by all other blocks on the interval (t[n], t[n+1]).
Input ports
None
Output ports
(0) The sampled time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
The sampling period of the clock. |
required | |
start_time
|
The simulation time at which the clock starts. Defaults to 0. |
0
|
Source code in jaxonomy/library/sources.py
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | |
DiscreteInitializer
Bases: LeafSystem
Discrete Initializer.
Outputs True for first discrete step, then outputs False there after. Or, outputs False for first discrete step, then outputs True there after. Practical for cases where it is necessary to have some signal fed initially by some initialization, but then after from else in the model.
Input ports
None
Output ports
(0) The dot product of the inputs.
Source code in jaxonomy/library/dynamics.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | |
DiscreteTimeLinearQuadraticRegulator
Bases: LeafSystem
Linear Quadratic Regulator (LQR) for a discrete-time system: x[k+1] = A x[k] + B u[k]. Computes the optimal control input: u[k] = -K x[k], where u minimises the cost function over [0, ∞)]: J = ∑(x[k].T Q x[k] + u[k].T R u[k]).
Input ports
(0) x[k]: state vector of the system.
Output ports
(0) u[k]: optimal control vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
A
|
Array State matrix of the system. |
required | |
B
|
Array Input matrix of the system. |
required | |
Q
|
Array State cost matrix. |
required | |
R
|
Array Input cost matrix. |
required | |
dt
|
float Sampling period of the system. |
required |
Source code in jaxonomy/library/lqr.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | |
DotProduct
Bases: ReduceBlock
Compute the dot product between the inputs.
This block dispatches to jax.numpy.dot, so the semantics, broadcasting rules,
etc. are the same. See the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.dot.html
Input ports
(0) The first input vector. (1) The second input vector.
Output ports
(0) The dot product of the inputs.
Source code in jaxonomy/library/math_ops.py
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | |
EDMDResult
dataclass
Fitted Koopman model (Williams, Kevrekidis & Rowley 2015).
Attributes:
| Name | Type | Description |
|---|---|---|
K |
Any
|
Koopman operator on lifted observables, shape |
B |
Any
|
Input operator on the lifted space, shape |
C |
Any
|
De-lift matrix mapping lifted → physical state, shape |
dictionary |
Callable
|
The observable dictionary |
Source code in jaxonomy/library/rom/koopman.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
ERAResult
dataclass
Minimal state-space realization from Markov parameters (Juang & Pappa 1985).
Attributes:
| Name | Type | Description |
|---|---|---|
A |
Any
|
Realized |
B |
Any
|
Realized |
C |
Any
|
Realized |
D |
Any
|
Feedthrough |
singular_values |
Any
|
Hankel singular values (from the block-Hankel SVD). |
Source code in jaxonomy/library/rom/dmd.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
EdgeDetection
Bases: LeafSystem
Output is true only when the input signal changes in a specified way.
The block updates at a discrete rate, checking the boolean- or binary-valued input signal for changes. Available edge detection modes are: - "rising": Output is true when the input changes from False (0) to True (1). - "falling": Output is true when the input changes from True (1) to False (0). - "either": Output is true when the input changes in either direction
Input ports
(0) The input signal. Must be boolean or binary-valued.
Output ports
(0) The edge detection output signal. Boolean-valued.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
The sampling period of the block. |
required | |
edge_detection
|
One of "rising", "falling", or "either". Determines the type of edge detection performed by the block. |
required | |
initial_state
|
The initial value of the output signal. |
False
|
Source code in jaxonomy/library/dynamics.py
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
EnabledMode
Allowed string values for EnabledSubsystem.mode.
Source code in jaxonomy/framework/containers.py
103 104 105 106 107 108 109 110 111 112 | |
EnabledStateMode
Allowed string values for EnabledSubsystem.state_mode.
Controls how the continuous state (declared via state_dynamics)
evolves while the enable signal is false:
HOLD(default): freeze the state at its current value (xdot = 0while disabled). Resumes integration on re-enable.RESET: snap the state back toinitial_stateon every disable→enable transition (so each enable window starts from the configured initial value). While disabled, the state is held.FREE: the state evolves according tostate_dynamicsregardless of enable. Only the output is masked permode=.
Source code in jaxonomy/framework/containers.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |
EnabledSubsystem
Bases: LeafSystem
Container block: run a submodel only while an enable signal is true.
This is the subsystem-framing wrapper around the existing
:class:jaxonomy.library.Conditional primitive (T-009). It exists
as a separate class so that:
- The block-diagram-vocabulary name
EnabledSubsystemis discoverable next to the rest of the container family. - We can later extend the
mode="hold"path with subsystem-state semantics (per-block discrete-state binding) without disturbing the lighterConditionalprimitive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submodel
|
Callable
|
Callable |
required |
n_inputs
|
int
|
Number of submodel inputs (does NOT include the enable port). Input port 0 is always the enable signal; ports 1..n_inputs carry the submodel inputs. |
1
|
mode
|
Literal['reset', 'passthrough', 'hold']
|
One of
|
RESET
|
initial_value
|
Output value when disabled in reset mode, and the seed for the held discrete state in hold mode. Used to infer output shape/dtype. |
0.0
|
|
hold_period
|
float | None
|
Sample period (seconds) for the held snapshot in
hold mode. Required iff |
None
|
state_mode
|
Literal['hold', 'reset', 'free']
|
One of |
HOLD
|
state_dynamics
|
Callable | None
|
Optional callable
|
None
|
initial_state
|
Initial value of the continuous state. Required
when |
None
|
|
name
|
Optional block name. |
required |
Source code in jaxonomy/framework/containers.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | |
Exponent
Bases: FeedthroughBlock
Compute the exponential of the input signal.
Input ports
(0) The input signal.
Output ports
(0) The exponential of the input signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base
|
One of "exp" or "2". Determines the base of the exponential function. |
required |
Source code in jaxonomy/library/math_ops.py
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | |
ExtendedKalmanFilter
Bases: KalmanFilterBase
Extended Kalman Filter (EKF) for the following system:
```
x[n+1] = f(x[n], u[n]) + G(t[n]) w[n]
y[n] = g(x[n], u[n]) + v[n]
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Q(t[n], x[n], u[n])
E(v[n]v'[n] = R(t[n])
E(w[n]v'[n] = N(t[n]) = 0
```
f and g are discrete-time functions of state x[n] and control u[n],
while RandGare discrete-time functions of timet[n].Qis a discrete-time
function oft[n], x[n], u[n]`. This last aspect is included for zero-order-hold
discretization of a continuous-time system
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Time step of the discrete-time system |
required | |
forward
|
Callable
A function with signature f(x[n], u[n]) -> x[n+1] that represents |
required | |
observation
|
Callable
A function with signature g(x[n], u[n]) -> y[n] that represents |
required | |
G_func
|
Callable
A function with signature G(t[n]) -> G[n] that represents |
required | |
Q_func
|
Callable
A function with signature Q(t[n], x[n], u[n]) -> Q[n] that represents |
required | |
R_func
|
Callable
A function with signature R(t[n]) -> R[n] that represents |
required | |
x_hat_0
|
ndarray Initial state estimate |
required | |
P_hat_0
|
ndarray Initial state covariance matrix estimate |
required |
Source code in jaxonomy/library/state_estimators/extended_kalman_filter.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
for_continuous_plant(plant, dt, G_func, Q_func, R_func, x_hat_0, P_hat_0, discretization_method='euler', discretized_noise=False, name=None, ui_id=None)
staticmethod
Extended Kalman Filter system for a continuous-time plant.
The input plant contains the deterministic forms of the forward and observation operators:
dx/dt = f(x,u)
y = g(x,u)
Note: (i) Only plants with one vector-valued input and one vector-valued output are currently supported. Furthermore, the plant LeafSystem/Diagram should have only one vector-valued integrator; (ii) the user may pass a plant with disturbances (not recommended) as the input plant. In this case, the forward and observation evaluations will be corrupted by noise.
A plant with disturbances of the following form is then considered:
dx/dt = f(x,u) + G(t) w -- (C1)
y = g(x,u) + v -- (C2)
where:
`w` represents the process noise,
`v` represents the measurement noise,
and
E(w) = E(v) = 0
E(ww') = Q(t)
E(vv') = R(t)
E(wv') = N(t) = 0
This plant is discretized to obtain the following form:
x[n+1] = fd(x[n], u[n]) + Gd w[n] -- (D1)
y[n] = gd(x[n], u[n]) + v[n] -- (D2)
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Qd
E(v[n]v'[n] = Rd
E(w[n]v'[n] = Nd = 0
The above discretization is performed either via the euler or the zoh
method, and an Extended Kalman Filter estimator for the system of equations
(D1) and (D2) is returned.
Note: If discretized_noise is True, then it is assumed that the user is
directly providing Gd, Qd and Rd. If False, then Qd and Rd are computed from
continuous-time Q, R, and G, and Gd is set to an Identity matrix.
The returned system will have:
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
a |
required | |
dt
|
float Time step for the discretization. |
required | |
G_func
|
Callable
A function with signature G(t) -> G that represents |
required | |
Q_func
|
Callable
A function with signature Q(t) -> Q that represents |
required | |
R_func
|
Callable
A function with signature R(t) -> R that represents |
required | |
x_hat_0
|
ndarray Initial state estimate |
required | |
P_hat_0
|
ndarray
Initial state covariance matrix estimate. If |
required | |
discretization_method
|
str ("euler" or "zoh") Method to discretize the continuous-time plant. Default is "euler". |
'euler'
|
|
discretized_noise
|
bool
Whether the user is directly providing Gd, Qd and Rd. Default is False.
If True, |
False
|
Source code in jaxonomy/library/state_estimators/extended_kalman_filter.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | |
from_operators(dt, forward, observation, G_func, Q_func, R_func, x_hat_0, P_hat_0, name=None, ui_id=None)
staticmethod
Extended Kalman Filter (UKF) for the following system:
x[n+1] = f(x[n], u[n]) + G(t[n]) w[n]
y[n] = g(x[n], u[n]) + v[n]
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Q(t[n], x[n], u[n])
E(v[n]v'[n] = R(t[n])
E(w[n]v'[n] = N(t[n]) = 0
f and g are discrete-time functions of state x[n] and control u[n],
while Q and R and G are discrete-time functions of time t[n].
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Time step of the discrete-time system |
required | |
forward
|
Callable
A function with signature f(x[n], u[n]) -> x[n+1] that represents |
required | |
observation
|
Callable
A function with signature g(x[n], u[n]) -> y[n] that represents |
required | |
G_func
|
Callable
A function with signature G(t[n]) -> G[n] that represents |
required | |
Q_func
|
Callable
A function with signature Q(t[n]) -> Q[n] that represents
|
required | |
R_func
|
Callable
A function with signature R(t[n]) -> R[n] that represents |
required | |
x_hat_0
|
ndarray Initial state estimate |
required | |
P_hat_0
|
ndarray Initial state covariance matrix estimate |
required |
Source code in jaxonomy/library/state_estimators/extended_kalman_filter.py
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
FeedthroughBlock
Bases: LeafSystem
Simple feedthrough blocks with a function of a single input
Source code in jaxonomy/library/generic.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
FilterDiscrete
Bases: LeafSystem
Finite Impulse Response (FIR) filter.
Similar to https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.lfilter.html Note: does not implement the IIR filter.
Input ports
(0) The input signal.
Output ports
(0) The filtered signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
b_coefficients
|
Array of filter coefficients. |
required |
Source code in jaxonomy/library/dynamics.py
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | |
FiniteHorizonLinearQuadraticRegulator
Bases: LeafSystem
Finite Horizon Linear Quadratic Regulator (LQR) for a continuous-time system. Solves the Riccati Differential Equation (RDE) to compute the optimal control for the following finitie horizon cost function over [t0, tf]:
Minimise cost J:
J = [x(tf) - xd(tf)].T Qf [x(tf) - xd(tf)]
+ ∫[(x(t) - xd(t)].T Q [(x(t) - xd(t)] dt
+ ∫[(u(t) - ud(t)].T R [(u(t) - ud(t)] dt
+ 2 ∫[(x(t) - xd(t)].T N [(u(t) - ud(t)] dt
subject to the constraints:
dx(t)/dt - dx0(t)/dt = A [x(t)-x0(t)] + B [u(t)-u0(t)] - c(t),
where, x(t) is the state vector, u(t) is the control vector, xd(t) is the desired state vector, ud(t) is the desired control vector, x0(t) is the nominal state vector, u0(t) is the nominal control vector, Q, R, and N are the state, input, and cross cost matrices, Qf is the final state cost matrix,
and A, B, and c are computed from linearisation of the plant df/dx = f(x, u)
around the nominal trajectory (x0(t), u0(t)).
A = df/dx(x0(t), u0(t), t)
B = df/du(x0(t), u0(t), t)
c = f(x0(t), u0(t), t) - dx0(t)/dt
The optimal control u obtained by the solution of the above problem is output.
See Section 8.5.1 of https://underactuated.csail.mit.edu/lqr.html#finite_horizon
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t0
|
float Initial time of the finite horizon. |
required | |
tf
|
float Final time of the finite horizon. |
required | |
plant
|
a |
required | |
Qf
|
Array Final state cost matrix. |
required | |
func_Q
|
Callable
A function that returns the state cost matrix Q at time |
required | |
func_R
|
Callable
A function that returns the input cost matrix R at time |
required | |
func_N
|
Callable
A function that returns the cross cost matrix N at time |
required | |
func_x_0
|
Callable
A function that returns the nominal state vector |
required | |
func_u_0
|
Callable
A function that returns the nominal control vector |
required | |
func_x_d
|
Callable
A function that returns the desired state vector |
required | |
func_u_d
|
Callable
A function that returns the desired control vector |
required |
Source code in jaxonomy/library/lqr.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | |
FrequencyResponse
dataclass
Result of a frequency-response evaluation.
Attributes:
| Name | Type | Description |
|---|---|---|
omegas |
Any
|
Angular frequency vector |
response |
Any
|
Complex frequency response |
magnitudes |
Any
|
|
phases |
Any
|
Phase |
Source code in jaxonomy/library/linearization_workflow.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
GPModel
Fitted Gaussian-process regressor (kriging).
Stores the training inputs, the pre-solved weight vector alpha = K^-1 y,
and the Cholesky factor of the (noisy) covariance matrix for variance
prediction. See Rasmussen & Williams 2006, Algorithm 2.1.
Source code in jaxonomy/library/rom/surrogates.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
predict(Xstar)
Posterior (mean, variance) at query points Xstar.
jax-traceable. Xstar may be 1-D (single point / single feature) or
2-D (m, d). Returns arrays of shape (m,).
Source code in jaxonomy/library/rom/surrogates.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
Gain
Bases: FeedthroughBlock
Multiply the input signal by a constant value.
Input ports
(0) The input signal.
Output ports
(0) The input signal multiplied by the gain: y = gain * u.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gain
|
The value to scale the input signal by. |
required | |
dtype
|
optional, T-038a-followup-other-blocks
|
If set, the block's output is cast to this dtype. See
|
None
|
Source code in jaxonomy/library/math_ops.py
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | |
GaussianProcess
Bases: LeafSystem
Gaussian-process (kriging) surrogate as a feedthrough block.
Input port 0 is the feature vector u; output port 0 is the predictive
mean and output port 1 the predictive variance. Training data and the
Cholesky factor are stored statically on the block; the weight vector
alpha and the kernel hyperparameters are dynamic parameters so the
surrogate is differentiable in them (Rasmussen & Williams 2006).
Source code in jaxonomy/library/rom/surrogates.py
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | |
HermiteSimpsonNMPC
Bases: NonlinearMPCIpopt
Implementation of nonlinear MPC with Hermite-Simpson collocation and IPOPT as the NLP solver.
Input ports
(0) x_0 : current state vector. (1) x_ref : reference state trajectory for the nonlinear MPC. (2) u_ref : reference input trajectory for the nonlinear MPC.
Output ports
(1) u_opt : the optimal control input to be applied at the current time step as determined by the nonlinear MPC.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
LeafSystem or Diagram The plant to be controlled. |
required | |
Q
|
Array State weighting matrix in the cost function. |
required | |
QN
|
Array Terminal state weighting matrix in the cost function. |
required | |
R
|
Array Control input weighting matrix in the cost function. |
required | |
N
|
int The prediction horizon, an integer specifying the number of steps to predict. Note: prediction and control horizons are identical for now. |
required | |
dt
|
float: Major time step, a scalar indicating the increment in time for each step in the prediction and control horizons. |
required | |
lb_x
|
Array Lower bound on the state vector. |
None
|
|
ub_x
|
Array Upper bound on the state vector. |
None
|
|
lb_u
|
Array Lower bound on the control input vector. |
None
|
|
ub_u
|
Array Upper bound on the control input vector. |
None
|
|
include_terminal_x_as_constraint
|
bool If True, the terminal state is included as a constraint in the NLP. |
False
|
|
include_terminal_u_as_constraint
|
bool If True, the terminal control input is included as a constraint in the NLP. |
False
|
|
x_optvars_0
|
Array Initial guess for the state vector optimization variables in the NLP. |
None
|
|
u_optvars_0
|
Array Initial guess for the control vector optimization variables in the NLP. |
None
|
Source code in jaxonomy/library/nmpc/hermite_simpson_ipopt_nmpc.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
IOPort
Bases: FeedthroughBlock
Simple class for organizing input/output ports for groups/submodels.
Since these are treated as standalone blocks in the UI rather than specific input/output ports exported to the parent model, it is more straightforward to represent them that way here as well.
This class represents a simple one-input, one-output feedthrough block where the feedthrough function is an identity. The input (resp. output) port can then be exported to the parent model to create an Inport (resp. Outport).
Source code in jaxonomy/library/routing.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | |
IfThenElse
Bases: LeafSystem
Applies a conditional expression to the input signals.
Given inputs pred, true_val, and false_val, the block computes:
y = true_val if pred else false_val
The true and false values may be any arrays, but must have the same shape and dtype.
Input ports
(0) The boolean predicate. (1) The true value. (2) The false value.
Output ports
(0) The result of the conditional expression. Shape and dtype will match the true and false values.
Events
An event is triggered when the output changes from true to false or vice versa.
Source code in jaxonomy/library/logic.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
InfiniteHorizonKalmanFilter
Bases: KalmanFilterBase
Infinite Horizon Kalman Filter for the following system:
x[n+1] = A x[n] + B u[n] + G w[n]
y[n] = C x[n] + D u[n] + v[n]
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Q
E(v[n]v'[n]) = R
E(w[n]v'[n]) = N = 0
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Time step of the discrete-time system |
required | |
A
|
ndarray State transition matrix |
required | |
B
|
ndarray Input matrix |
required | |
C
|
ndarray
Output matrix. If |
None
|
|
D
|
ndarray
Feedthrough matrix. If |
None
|
|
G
|
ndarray
Process noise matrix. If |
None
|
|
Q
|
ndarray
Process noise covariance matrix. If |
None
|
|
R
|
ndarray
Measurement noise covariance matrix. If |
None
|
|
x_hat_0
|
ndarray
Initial state estimate. If |
None
|
Source code in jaxonomy/library/state_estimators/infinite_horizon_kalman_filter.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | |
for_continuous_plant(plant, x_eq, u_eq, dt, Q=None, R=None, G=None, x_hat_bar_0=None, discretization_method='zoh', discretized_noise=False, name=None, ui_id=None)
staticmethod
Obtain an Infinite Horizon Kalman Filter system for a continuous-time plant after linearization at equilibrium point (x_eq, u_eq)
The input plant contains the deterministic forms of the forward and observation operators:
dx/dt = f(x,u)
y = g(x,u)
Note: (i) Only plants with one vector-valued input and one vector-valued output
are currently supported. Furthermore, the plant LeafSystem/Diagram should have
only one vector-valued integrator. (ii) the user may pass a plant with
disturbances as the input plant. However, computation of y_eq will be fraught
with disturbances.
A plant with disturbances of the following form is then considered following form:
dx/dt = f(x,u) + G w --- (C1)
y = g(x,u) + v --- (C2)
where:
`w` represents the process noise,
`v` represents the measurement noise,
and
E(w) = E(v) = 0
E(ww') = Q
E(vv') = R
E(wv') = N = 0
This plant with disturbances is linearized (only f and g) around the
equilibrium point to obtain:
d/dt (x_bar) = A x_bar + B u_bar + G w
y_bar = C x_bar + D u_bar + v
where,
x_bar = x - x_eq
u_bar = u - u_eq
y_bar = y - y_bar
y_eq = g(x_eq, u_eq)
The linearized plant is then discretized via euler or zoh method to obtain:
x_bar[n] = Ad x_bar[n] + Bd u_bar[n] + Gd w[n] --- (L1)
y_bar[n] = Cd x_bar[n] + Dd u_bar[n] + v[n] --- (L2)
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Qd
E(v[n]v'[n]) = Rd
E(w[n]v'[n]) = Nd = 0
Note: If discretized_noise is True, then it is assumed that the user is
providing Gd, Qd and Rd. If False, then Qd and Rd are computed from
continuous-time Q, R, and G, and Gd is set to Identity matrix.
An Infinite Horizon Kalman Filter estimator for the system of equations (L1)
and (L2) is returned. This filter is in the x_bar, u_bar, and y_bar
states.
This returned system will have
Input ports
(0) u_bar[n] : control vector at timestep n, relative to equilibrium (1) y_bar[n] : measurement vector at timestep n, relative to equilibrium
Output ports
(1) x_hat_bar[n] : state vector estimate at timestep n, relative to equilibrium
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
a |
required | |
x_eq
|
ndarray Equilibrium state vector for discretization |
required | |
u_eq
|
ndarray Equilibrium control vector for discretization |
required | |
dt
|
float Time step for the discretization. |
required | |
Q
|
ndarray
Process noise covariance matrix. If |
None
|
|
R
|
ndarray
Measurement noise covariance matrix. If |
None
|
|
G
|
ndarray
Process noise matrix. If |
None
|
|
x_hat_bar_0
|
ndarray Initial state estimate relative to equilibrium. If None, an identity matrix is assumed. |
None
|
|
discretization_method
|
str ("euler" or "zoh") Method to discretize the continuous-time plant. Default is "euler". |
'zoh'
|
|
discretized_noise
|
bool
Whether the user is directly providing Gd, Qd and Rd. Default is False.
If True, |
False
|
Source code in jaxonomy/library/state_estimators/infinite_horizon_kalman_filter.py
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | |
global_filter_for_continuous_plant(plant, x_eq, u_eq, dt, Q=None, R=None, G=None, x_hat_0=None, discretization_method='euler', discretized_noise=False, name=None, ui_id=None)
staticmethod
See docs for for_continuous_plant, which returns the local infinite horizon
Kalman Filter. This method additionally converts the local Kalman Filter to a
global estimator. See docs for make_global_estimator_from_local for details.
Source code in jaxonomy/library/state_estimators/infinite_horizon_kalman_filter.py
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | |
Integrator
Bases: LeafSystem
Integrate the input signal in time.
The Integrator block is the main primitive for building continuous-time
models. It is a first-order integrator, implementing the following linear
time-invariant ordinary differential equation for input values u and output
values y:
ẋ = u
y = x
where x is the state of the integrator. The integrator is initialized
with the value of the initial_state parameter.
The Integrator block is also designed to detect "Zeno" behavior, where the reset events happen asymptotically closer together. This is a pathological case that can cause numerical issues in the simulation and should typically be avoided by introducing some physically realistic hysteresis into the model. However, in the event that Zeno behavior is unavoidable, the integrator will enter a "Zeno" state where the output is held constant until the trigger changes value to False. See the "bouncing ball" demo for a Zeno example.
Input ports
(0) The input signal. Must match the shape and dtype of the initial
continuous state.
(1) The reset trigger. Optional, only if enable_reset is True.
(2) The reset value. Optional, only if enable_external_reset is True.
(3) The hold trigger. Optional, only if 'enable_hold' is True.
Output ports
(0) The continuous state of the integrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
The initial value of the integrator state. Can be any array, or even a nested structure of arrays, but the data type should be floating-point. |
required | |
enable_reset
|
If True, the integrator will reset its state to the initial value when the reset trigger is True. Adds an additional input port for the reset trigger. This signal should be boolean- or binary-valued. |
False
|
|
enable_external_reset
|
If True, the integrator will reset its state to the value provided by the reset value input port when the reset trigger is True. Otherwise, the integrator will reset to the initial value. Adds an additional input port for the reset value. This signal should match the shape and dtype of the initial continuous state. |
False
|
|
enable_limits
|
If True, the integrator will constrain its state and output to within the upper and lower limits. Either limit may be disbale by setting its value to None. |
False
|
|
enable_hold
|
If True, the integrator will hold integration when the hold trigger is True. |
False
|
|
reset_on_enter_zeno
|
If True, the integrator will reset its state to the initial value
when the integrator enters the Zeno state. This option is ignored unless
|
False
|
|
zeno_tolerance
|
The tolerance used to determine if the integrator is in the Zeno state.
If the time between events is less than this tolerance, then the
integrator is in the Zeno state. This option is ignored unless
|
1e-06
|
Events
An event is triggered when the "reset" port changes.
An event is triggered when the state hit one of the limits.
An event is triggered when the "hold" port changes.
Another guard is conditionally active when the integrator is in the Zeno state, and is triggered when the "reset" port changes from True to False. This event is used to exit the Zeno state and resume normal integration.
Source code in jaxonomy/library/dynamics.py
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 | |
IntegratorDiscrete
Bases: LeafSystem
Discrete first-order integrator.
This block is a discrete-time approximation to the behavior of the Integrator
block. It implements the following linear time-invariant difference equation
for input values u and output values y:
x[k+1] = x[k] + dt * u[k]
y[k] = x[k]
where x is the state of the integrator. The integrator is initialized with
the value of the initial_state parameter.
Unlike the continuous-time integrator, the discrete integrator does not detect Zeno behavior, since this is not a concern in discrete-time systems.
Input ports
(0) The input signal. Must match the shape and dtype of the initial
state.
(1) The reset trigger. Optional, only if enable_reset is True.
(2) The reset value. Optional, only if enable_external_reset is True.
(3) The hold trigger. Optional, only if 'enable_hold' is True.
Output ports
(0) The current state of the integrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
The initial value of the integrator state. Can be any array, or even a nested structure of arrays, but the data type should be floating-point. |
required | |
enable_reset
|
If True, the integrator will reset its state to the initial value when the reset trigger is True. Adds an additional input port for the reset trigger. This signal should be boolean- or binary-valued. |
False
|
|
enable_external_reset
|
If True, the integrator will reset its state to the value provided by the reset value input port when the reset trigger is True. Otherwise, the integrator will reset to the initial value. Adds an additional input port for the reset value. This signal should match the shape and dtype of the initial continuous state. |
False
|
|
enable_limits
|
If True, the integrator will constrain its state and output to within the upper and lower limits. Either limit may be disbale by setting its value to None. |
False
|
|
enable_hold
|
If True, the integrator will hold integration when the hold trigger is True. |
False
|
Source code in jaxonomy/library/dynamics.py
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | |
InterpolationUsingPrelookup
Bases: LeafSystem
Interpolate a static output_array using a precomputed
(index, fraction) tuple from :class:Prelookup.
This is the downstream half of the standard
Prelookup/InterpolationUsingPrelookup pair. Plug as many of
these as you like into a single :class:Prelookup's output port --
each one interpolates its OWN output_array against the shared
(index, fraction) signal, avoiding the redundant binary searches you
would do with N independent :class:LookupTable1d blocks.
Input ports
(0) -- the (index, fraction) NamedTuple produced by an
upstream :class:Prelookup block.
Output ports
(0) -- the linearly-interpolated value
(1 - alpha) * output_array[i] + alpha * output_array[i + 1].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_array
|
1-D table values, shape |
required | |
dtype
|
optional
|
If set (e.g. |
None
|
extrapolation
|
(optional, T - 114 - fu - prelookup - extrap)
|
Out-of-range policy. Must match the upstream
:class: |
'clip'
|
Notes
Differentiable through output_array (every time-step the
interpolation is a convex combination of two of its entries; the
gradient w.r.t. the picked entries is exact). The fraction-side
gradient flows through the upstream :class:Prelookup's
alpha computation; the discrete index is piecewise
constant (expected -- same as every searchsorted-based block
in the library).
Today only linear interpolation is
supported -- PCHIP/Akima downstream interpolation is a deeper
followup (T-114-followup-prelookup-cubic).
Source code in jaxonomy/library/tables.py
979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 | |
extrapolation
property
The declared OOB policy (must match the upstream Prelookup).
output_array
property
The 1-D table being interpolated.
KalmanFilter
Bases: KalmanFilterBase
Kalman Filter for the following system:
x[n+1] = A x[n] + B u[n] + G w[n]
y[n] = C x[n] + D u[n] + v[n]
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Q
E(v[n]v'[n] = R
E(w[n]v'[n] = N = 0
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Time step of the discrete-time system |
required | |
A
|
ndarray State transition matrix |
required | |
B
|
ndarray Input matrix |
required | |
C
|
ndarray
Output matrix. If |
None
|
|
D
|
ndarray
Feedthrough matrix. If |
None
|
|
G
|
ndarray
Process noise matrix. If |
None
|
|
Q
|
ndarray
Process noise covariance matrix. If |
None
|
|
R
|
ndarray
Measurement noise covariance matrix. If |
None
|
|
x_hat_0
|
ndarray
Initial state estimate. If |
None
|
|
P_hat_0
|
ndarray
Initial state covariance matrix estimate. If |
None
|
Source code in jaxonomy/library/state_estimators/kalman_filter.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | |
for_continuous_plant(plant, x_eq, u_eq, dt, Q=None, R=None, G=None, x_hat_bar_0=None, P_hat_bar_0=None, discretization_method='euler', discretized_noise=False, name=None, ui_id=None)
staticmethod
Obtain a Kalman Filter system for a continuous-time plant after linearization at equilibrium point (x_eq, u_eq)
The input plant contains the deterministic forms of the forward and observation operators:
dx/dt = f(x,u)
y = g(x,u)
Note: (i) Only plants with one vector-valued input and one vector-valued output are currently supported. Furthermore, the plant LeafSystem/Diagram should have only one vector-valued integrator.
A plant with disturbances of the following form is then considered following form:
dx/dt = f(x,u) + G w --- (C1)
y = g(x,u) + v --- (C2)
where:
`w` represents the process noise,
`v` represents the measurement noise,
and
E(w) = E(v) = 0
E(ww') = Q
E(vv') = R
E(wv') = N = 0
This plant with disturbances is linearized (only f and g) around the
equilibrium point to obtain:
d/dt (x_bar) = A x_bar + B u_bar + G w
y_bar = C x_bar + D u_bar + v
where,
x_bar = x - x_eq
u_bar = u - u_eq
y_bar = y - y_bar
y_eq = g(x_eq, u_eq)
The linearized plant is then discretized via euler or zoh method to obtain:
x_bar[n] = Ad x_bar[n] + Bd u_bar[n] + Gd w[n] --- (L1)
y_bar[n] = Cd x_bar[n] + Dd u_bar[n] + v[n] --- (L2)
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Qd
E(v[n]v'[n]) = Rd
E(w[n]v'[n]) = Nd = 0
Note: If discretized_noise is True, then it is assumed that the user is
providing Gd, Qd and Rd. If False, then Qd and Rd are computed from
continuous-time Q, R, and G, and Gd is set to Identity matrix.
A Kalman Filter estimator for the system of equations (L1) and (L2) is
created and returned. This filter is in the x_bar, u_bar, and y_bar
states.
This returned system will have
Input ports
(0) u_bar[n] : control vector at timestep n, relative to equilibrium (1) y_bar[n] : measurement vector at timestep n, relative to equilibrium
Output ports
(1) x_hat_bar[n] : state vector estimate at timestep n, relative to equilibrium
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
a |
required | |
x_eq
|
ndarray Equilibrium state vector for discretization |
required | |
u_eq
|
ndarray Equilibrium control vector for discretization |
required | |
dt
|
float Time step for the discretization. |
required | |
Q
|
ndarray
Process noise covariance matrix. If |
None
|
|
R
|
ndarray
Measurement noise covariance matrix. If |
None
|
|
G
|
ndarray
Process noise matrix. If |
None
|
|
x_hat_bar_0
|
ndarray Initial state estimate, relative to equilirium. If None, an identity matrix is assumed. |
None
|
|
P_hat_bar_0
|
ndarray
Initial covariance matrix estimate for state, relative to equilibrium.
If |
None
|
|
discretization_method
|
str ("euler" or "zoh") Method to discretize the continuous-time plant. Default is "euler". |
'euler'
|
|
discretized_noise
|
bool
Whether the user is directly providing Gd, Qd and Rd. Default is False.
If True, |
False
|
Source code in jaxonomy/library/state_estimators/kalman_filter.py
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | |
global_filter_for_continuous_plant(plant, x_eq, u_eq, dt, Q=None, R=None, G=None, x_hat_0=None, P_hat_0=None, discretization_method='euler', discretized_noise=False, name=None, ui_id=None)
staticmethod
See docs for for_continuous_plant, which returns the local Kalman
Filter. This method additionally converts the local Kalman Filter to a
global estimator. See docs for make_global_estimator_from_local for details.
Source code in jaxonomy/library/state_estimators/kalman_filter.py
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | |
KoopmanPredictor
Bases: LeafSystem
Discrete-time Koopman predictor for a nonlinear system.
Each step: lift the stored physical state z = g(x), advance the lifted
linear dynamics z[k+1] = K z[k] (+ B u[k]), then de-lift
x[k+1] = C z[k+1]. The physical state is the block output.
Because the lifted model is linear in z, (K, B) is a discrete
linear model you can use for linear MPC / LQR-style control — design in
lifted coordinates and de-lift with C (the Koopman→linear-MPC framing;
Korda & Mezić 2018). Note a lifted model generally has no state that both
satisfies z = g(x) and a hard terminal-equality constraint, so a
terminal-cost MPC is the right fit; the current
:class:~jaxonomy.library.mpc.LinearDiscreteTimeMPC block (hard terminal
equality, continuous-time model input) does not compose directly — see the
rom_dmdc_koopman_mpc example, which uses a compact terminal-cost MPC.
An input port (and use of B) is created only when B is provided.
Input ports
(0) u[k]: control input, present iff B is given.
Output ports
(0) x[k]: de-lifted physical state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
Koopman operator |
required | |
C
|
De-lift matrix |
required | |
dictionary
|
Observable dictionary |
required | |
B
|
Optional lifted input operator |
None
|
|
dt
|
Sampling period of the discrete update. |
1.0
|
|
initial_state
|
Initial physical state |
None
|
Source code in jaxonomy/library/rom/koopman.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
LTISystem
Bases: LTISystemBase
Continuous-time linear time-invariant system.
Implements the following system of ODEs:
ẋ = Ax + Bu
y = Cx + Du
Input ports
(0) u: Input vector of size m
Output ports
(0) y: Output vector of size p. Note that this is feedthrough from the input port if and only if D is nonzero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
A
|
State matrix of size n x n |
required | |
B
|
Input matrix of size n x m |
required | |
C
|
Output matrix of size p x n |
required | |
D
|
Feedthrough matrix of size p x m |
required | |
initialize_states
|
Initial state vector of size n (default: 0) |
None
|
Source code in jaxonomy/library/linear_system.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
ss
property
State-space representation of the system.
LTISystemDiscrete
Bases: LTISystemBase
Discrete-time linear time-invariant system.
Implements the following system of ODEs:
x[k+1] = A x[k] + B u[k]
y[k] = C x[k] + D u[k]
Input ports
(0) u[k]: Input vector of size m
Output ports
(0) y[k]: Output vector of size p. Note that this is feedthrough from the input port if and only if D is nonzero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
A
|
State matrix of size n x n |
required | |
B
|
Input matrix of size n x m |
required | |
C
|
Output matrix of size p x n |
required | |
D
|
Feedthrough matrix of size p x m |
required | |
dt
|
Sampling period |
required | |
initialize_states
|
Initial state vector of size n (default: 0) |
None
|
Source code in jaxonomy/library/linear_system.py
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | |
ss
property
State-space representation of the system.
LeadLag
Bases: LeafSystem
Discrete first-order lead-lag compensator.
Discretisation of the continuous compensator
G(s) = K * (1 + T_lead * s) / (1 + T_lag * s)
via the Tustin (bilinear) transform with s = (2/dt)*(z-1)/(z+1).
The resulting difference equation is::
c = 2 / dt
den = 1 + T_lag * c
b0 = K * (1 + T_lead * c) / den
b1 = K * (1 - T_lead * c) / den
a1 = (1 - T_lag * c) / den
y[k] = b0 * x[k] + b1 * x[k-1] - a1 * y[k-1]
With T_lead = T_lag the s-domain pole and zero cancel and the
block reduces to a pure gain K (used as an identity check in
the corpus).
Input ports
(0) The input signal x.
Output ports
(0) The compensated signal y.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Sampling period of the block (s). |
required | |
K
|
Compensator gain. Differentiable. |
1.0
|
|
T_lead
|
Lead time constant (s). Differentiable. |
1.0
|
|
T_lag
|
Lag time constant (s). Must be > 0. Differentiable. |
1.0
|
|
initial_state
|
Initial value of |
0.0
|
Notes
Differentiability: K, T_lead and T_lag flow into the
biquad coefficients via smooth arithmetic, so jax.grad is
finite through them.
The block is feedthrough on its input port (b0 != 0 whenever
K != 0), so y[k] depends on x[k] directly.
Source code in jaxonomy/library/dynamics.py
4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 | |
LinearDiscreteTimeMPC
Bases: LeafSystem
Model predictive control for a linear discrete-time system.
Solves a constrained quadratic program at each time step using OSQP
via jax.pure_callback, making it compatible with JAX's JIT compiler.
Notes
This block is feedthrough: the QP solver runs every time the output port is evaluated. Pair with a zero-order hold so the solver is invoked only once per MPC step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lin_sys
|
Linearized system (continuous-time A, B matrices). |
required | |
Q
|
State cost matrix (n×n). |
required | |
R
|
Input cost matrix (m×m). |
required | |
N
|
Prediction horizon (number of steps). |
required | |
dt
|
Sampling period for Euler discretization. |
required | |
x_ref
|
Terminal state reference (length-n array). |
required | |
lbu
|
Lower bound on control input (scalar or length-m array). |
-inf
|
|
ubu
|
Upper bound on control input (scalar or length-m array). |
inf
|
|
warm_start
|
Whether to warm-start the OSQP solver between solves. |
False
|
Source code in jaxonomy/library/mpc.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
LinearDiscreteTimeMPC_OSQP
Bases: LinearDiscreteTimeMPC
Deprecated alias for :class:LinearDiscreteTimeMPC.
Both classes now use OSQP via jax.pure_callback.
Use :class:LinearDiscreteTimeMPC directly.
Source code in jaxonomy/library/mpc.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
LinearQuadraticGaussian
Bases: LeafSystem
Continuous-time infinite-horizon LQG controller (separation principle).
The observer uses the algebraic Riccati solution for the Kalman gain
L given (A, G, C, Qn, Rn); the regulator uses the algebraic
Riccati solution for the feedback gain K given (A, B, Qc, Rc).
Both use the control library's lqe / lqr helpers.
Input / output shapes follow the plant: y is (ny,), u is
(nu,), and the observer's internal state is (nx,).
Source code in jaxonomy/library/lqg.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
LinearQuadraticRegulator
Bases: FeedthroughBlock
Linear Quadratic Regulator (LQR) for a continuous-time system: dx/dt = A x + B u. Computes the optimal control input: u = -K x, where u minimises the cost function over [0, ∞)]: J = ∫(x.T Q x + u.T R u) dt.
Input ports
(0) x: state vector of the system.
Output ports
(0) u: optimal control vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
A
|
Array State matrix of the system. |
required | |
B
|
Array Input matrix of the system. |
required | |
Q
|
Array State cost matrix. |
required | |
R
|
Array Input cost matrix. |
required |
Source code in jaxonomy/library/lqr.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
LinearizedSystem
dataclass
State-space linearization result.
For a continuous-time linsys (dt is None):
dx/dt = Ax + Bu, y = Cx + Du
For a discrete-time linsys (dt is a positive float — produced by
:func:jaxonomy.library.linearization_workflow.discretize):
x[k+1] = Ax[k] + Bu[k], y[k] = Cx[k] + Du[k]
Attributes:
| Name | Type | Description |
|---|---|---|
A |
Any
|
State matrix (n_states, n_states) |
B |
Any
|
Input matrix (n_states, n_inputs) |
C |
Any
|
Output matrix (n_outputs, n_states) |
D |
Any
|
Feedthrough matrix (n_outputs, n_inputs) |
operating_point |
dict
|
dict with state and input values used for linearization |
dt |
Optional[float]
|
Sampling period in seconds when the linsys is discrete-time;
|
Source code in jaxonomy/library/linear_system.py
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | |
eigenvalues()
Compute eigenvalues of A matrix. Returns complex array of shape (n_states,).
Source code in jaxonomy/library/linear_system.py
461 462 463 464 465 466 467 | |
is_discrete()
True if this LinearizedSystem carries a sampling period.
Source code in jaxonomy/library/linear_system.py
451 452 453 | |
is_stable()
True if the system is stable. For continuous-time linsys
(dt is None) the criterion is Re(eig(A)) < 0; for a
discrete-time linsys (dt is not None) it is
|eig(A)| < 1.
Source code in jaxonomy/library/linear_system.py
469 470 471 472 473 474 475 476 477 478 479 480 | |
to_lti()
Convert to Jaxonomy LTISystem block.
Source code in jaxonomy/library/linear_system.py
455 456 457 458 459 | |
to_scipy_lti()
Convert to :class:scipy.signal.StateSpace for frequency-domain analysis.
Returns a scipy.signal.StateSpace object, which supports MIMO systems
(multiple inputs and/or multiple outputs) as well as SISO systems. Use this
for Bode plots, Nyquist diagrams, step/impulse responses, etc.
Note
scipy.signal.lti is SISO-only and is not used here.
scipy.signal.StateSpace (a subclass of lti) is the correct target
for state-space (A, B, C, D) representations with any number of I/Os.
Requires scipy to be installed.
Source code in jaxonomy/library/linear_system.py
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | |
Logarithm
Bases: FeedthroughBlock
Compute the logarithm of the input signal.
This block dispatches to jax.numpy.log, jax.numpy.log2, or jax.numpy.log10,
so the semantics, broadcasting rules, etc. are the same. See the JAX docs for
details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.log.html
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.log2.html
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.log10.html
Input ports
(0) The input signal.
Output ports
(0) The logarithm of the input signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base
|
One of "natural", "2", or "10". Determines the base of the logarithm. The default is "natural". |
'natural'
|
Source code in jaxonomy/library/math_ops.py
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | |
LogicalOperator
Bases: LeafSystem
Apply a boolean function elementwise to the input signals.
This block implements the following boolean functions
- "or": same as np.logical_or
- "and": same as np.logical_and
- "not": same as np.logical_not
- "nor": equivalent to np.logical_not(np.logical_or(in_0,in_1))
- "nand": equivalent to np.logical_not(np.logical_and(in_0,in_1))
- "xor": same as np.logical_xor
Input ports
(0,1) The input signals. If numeric, they are interpreted as boolean types (so 0 is False and any other value is True).
Output ports
(0) The result of the logical operation, a boolean-valued signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
The boolean function to apply. One of "or", "and", "not", "nor", "nand", or "xor". |
required |
Events
An event is triggered when the output changes from True to False or vice versa.
Source code in jaxonomy/library/logic.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | |
LogicalReduce
Bases: FeedthroughBlock
Apply a boolean reduce function to the elements of the input signal.
This block implements the following boolean functions
- "any": Output is True if any input element is True.
- "all": Output is True if all input elements are True.
Input ports
(0) The input signal. If numeric, they are interpreted as boolean types (so 0 is False and any other value is True).
Output ports
(0) The result of the logical operation, a boolean-valued signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
The boolean function to apply. One of "any", "all". |
required | |
axis
|
Axis or axes along which a logical OR/AND reduction is performed. |
None
|
Events
An event is triggered when the output changes from True to False or vice versa.
Source code in jaxonomy/library/logic.py
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | |
LookupTable1d
Bases: FeedthroughBlock
Interpolate the input signal into a static lookup table.
If a function y = f(x) is sampled at a set of points (x_i, y_i), then this
block will interpolate the input signal x to compute the output signal y.
The behavior is modeled after scipy.interpolate.interp1d but is implemented
in JAX. Available interpolation modes are:
- "linear": Linear interpolation using jax.interp.
- "pchip": Monotone cubic Hermite (Hyman/Fritsch-Carlson). T-106
phase 1 — smooth gradients everywhere, monotone on monotone data.
- "akima": Akima 1970 cubic spline (T-114 phase 2). Smoother than
PCHIP on non-monotone data, less prone to overshoot than
natural cubic splines. Matches
scipy.interpolate.Akima1DInterpolator.
- "cubic": Natural cubic spline (T-114-followup-natural-cubic-
spline). C^2-continuous, second derivative zero at the
boundaries — the smoothest possible C^2 interpolant. Requires
at least 4 breakpoints. Matches
scipy.interpolate.CubicSpline(bc_type='natural').
- "nearest": Nearest-neighbor interpolation.
- "flat": Flat interpolation.
Input ports
(0) The input signal, which is used as the interpolation coordinate.
Output ports
(0) The interpolated output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_array
|
The array of input values at which the output values are provided. |
required | |
output_array
|
The array of output values. |
required | |
interpolation
|
One of "linear", "pchip", "nearest", or "flat". Determines the type of interpolation performed by the block. |
required | |
extrapolation
|
optional, T-114 phase 1
|
One of "clip" (default — standard lookup-table behaviour, holds
the boundary value), "linear" (extends the boundary slope past the breakpoints),
or "nan" (returns NaN outside |
'clip'
|
dtype
|
optional, T-038a
|
If set (e.g. T-038a-followup-mixed-precision-cascade: when Best-effort: this enforces dtype on the block's internal arrays
and on the output of |
None
|
Notes
Currently restricted to 1D input and output data. This may be expanded to support multi-dimensional output arrays in the future.
Source code in jaxonomy/library/tables.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | |
fit_from_data(xp, x_data, y_data, *, weights=None, smoothness=0.0, **block_kwargs)
classmethod
Build a LookupTable1d whose output values are fitted by
least squares to (x_data, y_data) at the fixed grid xp.
Ergonomic wrapper around :func:jaxonomy.library.fit_lookup_table_1d
so the fitting entry point is discoverable from the block class
itself.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xp
|
Fixed grid of breakpoints (1-D, strictly increasing). |
required | |
x_data
|
Measured input cloud, shape |
required | |
y_data
|
Measured output cloud, shape |
required | |
weights
|
Optional per-sample weights for weighted least
squares. |
None
|
|
smoothness
|
float
|
Non-negative discrete first-difference penalty. Use small values (1e-3 .. 1.0) on noisy / sparse data. |
0.0
|
**block_kwargs
|
Forwarded to
:func: |
{}
|
Returns:
| Type | Description |
|---|---|
|
A |
|
|
|
Source code in jaxonomy/library/tables.py
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | |
LookupTable2d
Bases: LeafSystem
Interpolate the input signals into a static lookup table.
The behavior is modeled on scipy.interpolate.interp2d but is implemented
in JAX. "linear" (bilinear, default) and "bicubic" (Catmull-Rom)
interpolation are supported. The input arrays must be 1D and the output
array must be 2D.
Input ports
(0) The first input signal, used as the first interpolation coordinate. (1) The second input signal, used as the second interpolation coordinate.
Output ports
(0) The interpolated output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_x_array
|
The array of input values at which the output values are provided, corresponding to the first input signal. Must be 1D |
required | |
input_y_array
|
The array of input values at which the output values are provided, corresponding to the second input signal. Must be 1D |
required | |
output_table_array
|
The array of output values. Must be 2D with shape |
required | |
interpolation
|
|
'linear'
|
|
extrapolation
|
optional, T-114 phase 2
|
One of "clip" (default — standard lookup-table behaviour, holds
the boundary value), "linear" (bilinear extension past the grid
via edge-slope continuation), or "nan" (returns NaN outside
the grid). The default |
'clip'
|
Source code in jaxonomy/library/tables.py
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | |
fit_from_data(xp, yp, x_data, y_data, z_data, *, weights=None, smoothness=0.0, **block_kwargs)
classmethod
Build a LookupTable2d whose table values are fitted by
bilinear least squares to (x_data, y_data, z_data) at the
fixed grid (xp, yp).
Ergonomic classmethod mirror of
:func:jaxonomy.library.fit_lookup_table_2d so the 2-D fitting
entry point is discoverable from the block class itself.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xp
|
Fixed grid along the first axis (1-D, strictly increasing). |
required | |
yp
|
Fixed grid along the second axis (1-D, strictly increasing). |
required | |
x_data, y_data, z_data
|
Measurement cloud, all shape
|
required | |
weights
|
Optional per-sample weights for weighted least
squares. |
None
|
|
smoothness
|
float
|
Non-negative 5-point Laplacian penalty on the
fitted table. |
0.0
|
**block_kwargs
|
Forwarded to
:func: |
{}
|
Returns:
| Type | Description |
|---|---|
|
A |
|
|
|
|
|
LS-fit table of shape |
Source code in jaxonomy/library/tables.py
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | |
LookupTableND
Bases: LeafSystem
Interpolate the input signal into a static N-D lookup table.
Generalises :class:LookupTable1d and :class:LookupTable2d to an
arbitrary number of axes. The block takes a single input port whose
value is a length-N query vector [q_1, ..., q_N] and returns
the multilinearly interpolated table value at that point.
Implementation: delegates to
:func:jaxonomy.library.lookup_table.interp_nd, which performs
N successive 1-D linear interpolations along each axis (no
jnp.interpn exists today — see the deeper-followup note in
that function's docstring).
Input ports
(0) — the query vector, shape (N,) where N is the
number of grid axes.
Output ports
(0) — the multilinearly interpolated table value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_axes
|
Tuple of |
required | |
output_array
|
Sample values, shape |
required | |
interpolation
|
Currently only |
'linear'
|
|
extrapolation
|
optional
|
One of |
'clip'
|
dtype
|
optional
|
If set (e.g. |
None
|
Notes
Differentiable through both the query vector and the table
values (modulo the discrete bucket-index searchsorted,
whose gradient is piecewise constant — within a cell the
gradient is exact).
Source code in jaxonomy/library/tables.py
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | |
LowPassDiscrete
Bases: LeafSystem
Discrete first-order (single-pole RC) low-pass filter.
Implements the difference equation::
tau = 1 / (2*pi*cutoff_hz)
alpha = dt / (dt + tau)
y[k] = alpha * x[k] + (1 - alpha) * y[k-1]
The continuous-time analogue is H(s) = 1 / (1 + tau*s), with -3 dB
crossover at f = cutoff_hz in the small-dt limit.
Input ports
(0) The input signal x.
Output ports
(0) The filtered signal y.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Sampling period of the block (s). |
required | |
cutoff_hz
|
Design cutoff frequency (Hz). Differentiable. |
1.0
|
|
initial_state
|
Initial value of |
0.0
|
Notes
Differentiability: cutoff_hz enters the recursive update via
smooth arithmetic (alpha = dt/(dt + 1/(2*pi*cutoff_hz))), so
jax.grad is finite through it.
Source code in jaxonomy/library/dynamics.py
4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 | |
Luenberger
Bases: LeafSystem
Discrete-time Luenberger observer with user-supplied gain L.
State-update equation:
.. code-block:: text
x_hat[k+1] = A·x_hat[k] + B·u[k] + L·(y[k] - C·x_hat[k] - D·u[k])
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Discrete sample period (seconds). Must match the plant's sample period (or, for continuous plants, the discretisation period chosen for the design). |
required | |
A, B, C, D
|
Plant state-space matrices (typically the output of
|
required | |
L
|
Observer gain matrix, shape |
required | |
x_hat_0
|
Initial state estimate. Defaults to zeros. |
None
|
Input ports
(0) u: control input vector, shape (n_inputs,).
(1) y: noisy measurement vector, shape (n_outputs,).
Output ports
(0) x_hat: state estimate vector, shape (n_states,).
Notes
This block is the simpler half of the Kalman pair — the design
cost (computing L) is paid offline, leaving only the cheap
runtime update. If you want online Riccati-based gain updates
instead, use :class:KalmanFilter. If you have a continuous
plant and want the steady-state infinite-horizon Kalman gain,
use :class:InfiniteHorizonKalmanFilter.
Source code in jaxonomy/library/state_estimators/luenberger.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
MJX
Bases: MuJoCoBase
A system that wraps a MuJoCo model and provides a continuous-time ODE LeafSystem. Currently only supports a single body system.
Input ports
(0) The control input vector control.
Output ports
(0) The generalized position coordinates qpos.
(1) The generalized velocity coordinates qvel.
(2) The actuator coordinates act.
(3) The sensor data sensor_data (if enabled).
(4) The video output video as RGB frames of shape (H,W,3) (if enabled).
(5) A fake output port, present only if vHIL=True and outputs Array(0.0).
(6+) Custom output ports, defined with user-specified python scripts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
The path to the MuJoCo XML model file. |
required |
dt
|
float
|
If None, jaxonomy's internal solver will be used and this block can
be considered as a continuous block. If set, the model will be run in
a discrete mode with the specified timestep, using MJX's solver, more like
Co-Simulation. In that case, it might be favorable to set |
None
|
key_frame_0
|
int | str
|
The keyframe to initialize the model from. |
None
|
qpos_0
|
Array
|
The initial generalized position coordinates. |
None
|
qvel_0
|
Array
|
The initial generalized velocity coordinates. |
None
|
act_0
|
Array
|
The initial actuator coordinates. |
None
|
enable_sensor_data
|
bool
|
Whether to output the sensor data to an optional port named 'sensor_data'. |
False
|
enable_video_output
|
bool
|
Whether to output the rendered video frames to an optional port named 'video'. |
False
|
video_size
|
tuple[int, int]
|
The size of the video output frames as a (H,W) tuple. |
None
|
enable_mocap_pos
|
bool
|
Whether to enable the mocap_pos input port for motion capture tracking. |
False
|
vHIL
|
bool
|
Whether to run in virtual hardware-in-the-loop mode. |
False
|
vHIL_dt
|
float
|
The timestep for the virtual hardware-in-the-loop mode. |
0.01
|
Notes:
(i) _model and _data refer to MuJoCo's mjModel and mjData objects
respectively. model and data are the corresponding MJX objects.
(ii) While sensordata output is supported as a pure callback to MuJoCo since MJX
has not yet implemented this aspect. This can be expensive.
Source code in jaxonomy/library/mujoco.py
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 | |
normalize_qpos_quat(qpos)
Normalize the quaternion components of the generalized position coordinates.
Source code in jaxonomy/library/mujoco.py
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | |
MLP
Bases: FeedthroughBlock
A feedforward neural network block representing an Equinox multi-layer
perceptron (MLP). The output y of the MLP is computed as
y = MLP(x, theta)
where theta are the parameters of the MLP, and x is the input to the MLP.
This block is differentialble w.r.t. the MLP parameters theta. Note that theta,
does not include the hyperparameters representing the architecture of the MLP.
Input ports
(0) The input to the MLP.
Output ports
(0) The output of the MLP.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_size
|
int
|
The dimension of the input to the MLP. |
None
|
out_size
|
int
|
The dimension of the output of the MLP. |
None
|
width_size
|
int
|
The width of every hidden layers of the MLP. |
None
|
depth
|
int
|
The depth of the MLP. This represents the number of hidden layers, including the output layer. |
None
|
seed
|
int
|
The seed for the random number generator for initialization of the MLP parameters (weights and biases of every layer). If None, a random 32-bit seed will be generated. |
None
|
activation_str
|
str
|
The activation function to use after each internal layer of the MLP.
Possible values are |
'relu'
|
final_activation_str
|
str
|
The activation function to use for the output layer of the MLP.
Same choices as |
'identity'
|
use_bias
|
bool
|
Whether to add a bias to the internal layers of the MLP. Default is True. |
True
|
use_final_bias
|
bool
|
Wheter to add a bias to the output layer of the MLP. Default is True. |
True
|
file_name
|
str
|
Optional file name containing the serialized parameters of the MLP. If provided, the parameters are loaded from the file, and set as the parameters of the MLP. Default is None. |
None
|
Source code in jaxonomy/library/nn.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | |
mlp
property
The underlying Equinox eqx.nn.MLP object.
Built lazily in :meth:initialize, which runs the first time
create_context() is called on a diagram containing this block.
Accessing it before then raises a clear error pointing at
create_context() (T-B4-followup-mlp-pre-context).
__init__(in_size=None, out_size=None, width_size=None, depth=None, seed=None, activation_str='relu', final_activation_str='identity', use_bias=True, use_final_bias=True, file_name=None, **kwargs)
see https://docs.kidger.site/equinox/examples/serialisation/ for rationale of implementation here. We can't serialize the activation function, so we serialize a string representing a selection for activation function amongst a finite set of options.
Source code in jaxonomy/library/nn.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | |
serialize(file_name, mlp_params=None)
Serialize only the parameters of the MLP. Note that the hyperparameters
representing the architecture of the MLP are not serialized. This is because
of the following use-cases imagined:
(i) The user may train the Equinox MLP outside of Jaxonomy. In this case,
it seems unnecessary to force the user to serialize the hyperparameters of the
MLP in the strict form chosen by Jaxonomy. It would seem much easier
for the user to just input these hyperparameters when creating the MLP block
in Jaxonomy UI, and upload the naturally produced serialized parameters file
by Equinox.
(ii) The user may want to train the Equinox MLP within Jaxonomy in a notebook,
and then use the block within Colimator UI. In this case, while serialization of
the hyperparameters of the MLP would be a litte more convenient compared
to manually inputting the hyperparameters in the UI, it seems like a small
convenience relative to disadvantages of (i). Ideally the user should be
able to use the API to push the learnt parameters.
(iii) When we support training in the UI, the hyperparameters are naturally
serialzed with declare_configuraton_parameters, and thus, in this case too,
only serializatio of the MLP parameters is necessary.
The choice of an optional mlp_params is to enable training of the
models in a notebook and easily seralizing them for use in the UI.
Source code in jaxonomy/library/nn.py
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | |
MaskedDelayBuffer
Bases: LeafSystem
Delay buffer where the delay length can be set at runtime (up to max_steps).
Like ShiftRegister, but allows the delay to be specified as an input signal. Uses masking (not dynamic indexing) for JAX compatibility.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_steps
|
int
|
Maximum possible delay. STATIC. |
required |
signal_shape
|
tuple
|
Shape of each signal frame. |
()
|
dt
|
float
|
Discrete update interval. |
0.01
|
Ports
Input[0] "u": signal to delay Input[1] "delay_steps": integer scalar, 0 < delay_steps <= max_steps Output[0] "y": delayed signal
Source code in jaxonomy/library/delay.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | |
MatrixConcatenation
Bases: ReduceBlock
Concatenate two matrices along a given axis.
Dispatches to jax.numpy.concatenate, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.concatenate.html
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
The axis along which the matrices are concatenated. 0 for vertical and 1 for horizontal. Default is 0. |
0
|
Input ports
(0, 1) The input matrices A and B
Output ports
(0) The concatenation input matrices: e.g. [A,B].
Source code in jaxonomy/library/math_ops.py
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | |
MatrixInversion
Bases: FeedthroughBlock
Compute the matrix inverse of the input signal.
Dispatches to jax.numpy.inv, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.linalg.inv.html
Input ports
(0) The input matrix.
Output ports
(0) The inverse of the input matrix.
Source code in jaxonomy/library/math_ops.py
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | |
MatrixMultiplication
Bases: ReduceBlock
Compute the matrix product of the input signals.
Dispatches to jax.numpy.matmul, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.matmul.html
Input ports
(0, 1) The input matrices A and B
Output ports
(0) The matrix product of the input matrices: A @ B.
Source code in jaxonomy/library/math_ops.py
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | |
MatrixTransposition
Bases: FeedthroughBlock
Compute the matrix transpose of the input signal.
Dispatches to jax.numpy.transpose, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.transpose.html
Input ports
(0) The input matrix.
Output ports
(0) The transpose of the input matrix.
Source code in jaxonomy/library/math_ops.py
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | |
MinMax
Bases: ReduceBlock
Return the extremum of the input signals.
Input ports
(0..n_in-1) The input signals.
Output ports
(0) The minimum or maximum of the input signals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
operator
|
One of "min" or "max". Determines whether the block returns the minimum or maximum of the input signals. |
required |
Events
An event is triggered when the extreme input signal changes. For example, if the block is configured as a "max" block with two inputs and the second signal becomes greater than the first, a zero-crossing event will be triggered.
Source code in jaxonomy/library/math_ops.py
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 | |
ModelicaFMU
Bases: LeafSystem
Source code in jaxonomy/library/fmu_import.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 | |
__init__(file_name, dt, name=None, input_names=None, output_names=None, parameters=None, start_time=0.0, first_step_at_zero=False, **kwargs)
Load and execute an FMU for Co-Simulation.
.. warning:: One instance per FMU per process for FMUs built
with pythonfmu (e.g. via :func:jaxonomy.library.build_fmu).
The embedded-Python wrapper holds a process-wide
Py_Initialize singleton, so instantiating the same
.fmu dylib twice in one Python process fails. For
multi-start or batched co-simulation, isolate each instance
in its own process (multiprocessing /
concurrent.futures.ProcessPoolExecutor with the spawn
start method, or a subprocess running a small driver
script) and aggregate results afterwards. This is an
upstream pythonfmu limitation, not a Jaxonomy one; FMUs from
other exporters (OpenModelica, Dymola, Reference-FMUs) do
not carry it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
path to FMU file |
required |
dt
|
float
|
stepsize for FMU simulation |
required |
name
|
str
|
name of block |
None
|
input_names
|
list[str]
|
if set, only expose these inputs |
None
|
output_names
|
list[str]
|
if set, only expose these outputs |
None
|
parameters
|
dict
|
dictionary of parameter overrides |
None
|
start_time
|
float
|
FMU experiment start time. |
0.0
|
first_step_at_zero
|
bool
|
Default |
False
|
kwargs
|
ignored |
{}
|
Source code in jaxonomy/library/fmu_import.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
MuJoCo
Bases: MuJoCoBase
MuJoCo implementation without MJX.
Refer to MJX for the main docs.
Unlike the MJX variant of the block, this version uses the solver provided by mujoco itself and the physics are fully handled by mujoco. This behaves like a Co-Simulation environment.
This variant may be used to speed up compilation times or in situations where full JAX is not available or practical.
Source code in jaxonomy/library/mujoco.py
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 | |
MultiPortSwitch
Bases: LeafSystem
Route one of N data signals based on an integer selector input.
Inputs are (selector, data_0, data_1, ..., data_{n-1}) and the
output is data_{clip(round(selector), 0, n-1)}.
Implementation strategy: stack the data inputs along a new leading
axis and pick out the selected slice with integer indexing. This is
fully differentiable through the selected data input (zero
gradient on the others), which is the standard documented
semantics for this block. The selector is rounded and clipped to [0, n-1]
so floating-point inputs are tolerated; the selector itself is
non-differentiable (round/clip zero out the gradient).
All data inputs must share the same shape and dtype (the stack
requires it). Mixed shapes are rejected by npa.stack at trace
time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_data_inputs
|
number of data input ports. Must be |
required | |
choice_names
|
optional tuple of unique non-empty string labels,
one per data input, used for self-documenting diagrams.
When supplied its length MUST equal |
None
|
Input ports
(0) selector — scalar integer-valued signal in [0, n-1].
Floating values are rounded and clipped.
(1..n_data_inputs) data inputs.
Output ports
(0) The data input at index selector.
Notes
The original T-118 spec includes indexing="one-based" and
mode="smooth" (softmax-blend across data inputs). Both are
deferred — see T-118-followup-modes. Zero-based indexing is the
only mode supported in phase 1, matching Python conventions.
Named choices (T-118-followup-multi-port-string-keys, 2026-05-13):
choice_names=("low", "medium", "high") lets a diagram
document which port means what. The selector port itself still
expects an integer at runtime — JAX cannot trace strings, so
this is the build-time-only interpretation the followup spec
calls out. Look up the integer for a name on the Python side:
.. code-block:: python
mps = MultiPortSwitch(3, choice_names=("low", "med", "high"))
sel = library.Constant(mps.index_of("med")) # → 1
Passing a string to ``index_of`` returns the matching integer;
passing an int returns it unchanged after a range check, so
callers can mix the two without branching. Unknown strings and
out-of-range ints raise ``BlockParameterError`` at construction
(build) time, not at trace time. The runtime _compute_output
path is unchanged when ``choice_names`` is ``None`` — the
default-off byte-equivalence guarantee.
Source code in jaxonomy/library/logic.py
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | |
choice_names
property
Tuple of channel labels, or None if unlabeled.
index_of(selector)
Resolve a string or int selector to its integer index.
selector may be a string (looked up in choice_names)
or any object convertible via int(). Strings only resolve
when choice_names was supplied at construction.
Out-of-range ints and unknown strings raise
BlockParameterError at build time; runtime selectors
flowing through the input port are still clipped silently by
_compute_output (no change to the runtime path).
Source code in jaxonomy/library/logic.py
930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | |
Multiplexer
Bases: ReduceBlock
Stack the input signals into a single output signal.
Dispatches to jax.numpy.hstack, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.hstack.html
Input ports
(0..n_in-1) The input signals.
Output ports
(0) The stacked output signal.
Source code in jaxonomy/library/routing.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
Mux
Bases: ReduceBlock
Stack n_inputs homogeneous signals into a single output signal.
This is the standard Mux block. It dispatches to npa.stack
along axis 0, so:
Mux(3)([1.0, 2.0, 3.0]) -> array([1.0, 2.0, 3.0])(shape(3,)).Mux(2)([(1.0, 2.0), (3.0, 4.0)]) -> array([[1.0, 2.0], [3.0, 4.0]])(shape(2, 2)).
All inputs must be the same shape and dtype; this matches the
conventional Mux semantics and npa.stack's broadcasting rules.
For the older flatten-by-concatenation behavior (hstack), use
:class:Multiplexer instead.
Input ports
(0..n_inputs-1) The input signals (must share shape and dtype).
Output ports
(0) The stacked output signal, with one extra leading axis.
Source code in jaxonomy/library/routing.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
Notch
Bases: LeafSystem
Discrete biquad band-stop ("notch") filter.
Implements the textbook biquad notch::
omega0 = 2*pi * frequency_hz * dt
r = 1 - pi * bandwidth_hz * dt (pole radius)
rho2 = r*r + depth * (1 - r*r) (zero radius**2)
b0, b1, b2 = 1, -2*sqrt(rho2)*cos(omega0), rho2
a1, a2 = -2*r*cos(omega0), r*r
y[k] = b0*x[k] + b1*x[k-1] + b2*x[k-2]
- a1*y[k-1] - a2*y[k-2]
With depth = 1 the zeros sit on the unit circle and the notch is
infinitely deep. With depth = 0 the numerator collapses to the
denominator and the block becomes a unit-gain pass-through (useful
as an identity check).
Input ports
(0) The input signal x.
Output ports
(0) The filtered signal y.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Sampling period of the block (s). |
required | |
frequency_hz
|
Notch centre frequency (Hz). Differentiable. |
1.0
|
|
bandwidth_hz
|
Approximate -3 dB bandwidth of the notch (Hz). Differentiable.
Must satisfy |
0.1
|
|
depth
|
Notch depth in |
0.99
|
|
initial_state
|
Initial value of |
0.0
|
Notes
Differentiability: frequency_hz, bandwidth_hz, and
depth enter the biquad coefficients via smooth arithmetic
(cos, sqrt), so jax.grad is finite through them.
The block is feedthrough on its input port (b0 = 1), so
y[k] depends on x[k] directly.
Source code in jaxonomy/library/dynamics.py
4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 | |
ONNX
Bases: LeafSystem
ONNX inference block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Path to the |
required |
num_inputs
|
int
|
Number of input tensors the model expects. |
1
|
num_outputs
|
int
|
Number of output tensors the model produces. |
1
|
cast_outputs_to_dtype
|
Optional |
None
|
|
providers
|
|
('CPUExecutionProvider',)
|
|
name
|
Optional block name. |
required |
Notes
Differentiability is best-effort — jax.pure_callback does
not define a VJP, so reverse-mode autodiff through the block
raises. For end-to-end gradients, look at the T-023a follow-up
on a JAX-traceable conversion (onnx2jax or similar).
.. note:: float32 artifacts under jaxonomy's global x64.
import jaxonomy enables jax_enable_x64 process-wide, so a
float32 ONNX model receives float64 inputs unless you cast at the
block boundary — a silent arithmetic change relative to the
framework the model was exported and validated in. One-line
idiom: pass cast_outputs_to_dtype="float32" and feed the
block x.astype(jnp.float32) inputs.
Source code in jaxonomy/library/onnx_block.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
ONNXJax
Bases: LeafSystem
JAX-traceable ONNX inference (T-023a).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Path to the |
required |
num_inputs
|
int
|
Number of input tensors the model expects. |
1
|
num_outputs
|
int
|
Number of output tensors the model produces. |
1
|
cast_outputs_to_dtype
|
Optional |
None
|
|
name
|
Optional block name. |
required |
Differentiability: end-to-end via jaxonnxruntime's JAX
primitive implementations. Op coverage failure shows up at
initialize() time as a clear RuntimeError from
jaxonnxruntime.
For models that use ops outside jaxonnxruntime's coverage,
fall back to :class:ONNX — same constructor signature, runs via
onnxruntime host callback (no autodiff).
.. note:: float32 artifacts under jaxonomy's global x64.
import jaxonomy enables jax_enable_x64 process-wide, so a
float32 model here computes against float64 inputs unless you
cast at the block boundary. One-line idiom: pass
cast_outputs_to_dtype="float32" and feed the block
x.astype(jnp.float32) inputs.
.. note:: Imported discrete-time policies need a ZeroOrderHold.
A sample-and-hold controller exported from a discrete-time
training loop (torch / NEUROMANCER-style: compute :math:u_k
once per sample, hold for ts) is re-evaluated at every ODE
solver stage (e.g. all four RK4 stages) when wired directly into
a continuous plant — continuous-feedback semantics. Both loops
"work", but step-for-step parity with the exporting framework is
silently destroyed. Follow the block with
ZeroOrderHold(dt=ts) and pin the step grid with
SimulatorOptions(max_major_step_length=ts,
max_minor_step_size=ts); with that, closed-loop parity is
~4e-8 over 400 steps on the two-tank benchmark.
Source code in jaxonomy/library/onnx_jax_block.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
Offset
Bases: FeedthroughBlock
Add a constant offset or bias to the input signal.
Given an input signal u and offset value b, this will return y = u + b.
Input ports
(0) The input signal.
Output ports
(0) The input signal plus the offset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
offset
|
The constant offset to add to the input signal. |
required |
Source code in jaxonomy/library/math_ops.py
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 | |
OperatingPoint
dataclass
Result of :func:findop.
Attributes:
| Name | Type | Description |
|---|---|---|
x |
Any
|
Equilibrium continuous state. |
u |
Any
|
Input value held fixed during the search (taken from
|
residual_norm |
float
|
Final |
converged |
bool
|
True if |
iterations |
int
|
Number of Newton iterations actually executed. |
Source code in jaxonomy/library/linearization_workflow.py
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
PCEModel
Fitted polynomial-chaos expansion y = sum_k c_k Psi_k(xi).
The orthonormal basis (Askey scheme) gives closed-form statistics: the mean is the constant coefficient, the variance is the sum of squared non-constant coefficients, and Sobol indices follow from partitioning that sum by which inputs each basis term depends on (Xiu & Karniadakis 2002; Sudret, Reliab. Eng. Syst. Saf. 93(7):964--979, 2008).
Source code in jaxonomy/library/rom/surrogates.py
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | |
mean()
Analytic mean = constant-term coefficient.
Source code in jaxonomy/library/rom/surrogates.py
370 371 372 | |
predict(Xstar)
Surrogate response at Xstar (jax-traceable).
Source code in jaxonomy/library/rom/surrogates.py
363 364 365 366 367 368 | |
sobol_indices()
Main-effect (first-order) and total Sobol indices per input.
Returns a dict {"first_order": (dim,), "total": (dim,)}.
Source code in jaxonomy/library/rom/surrogates.py
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 | |
variance()
Analytic variance = sum of squared non-constant coefficients.
Source code in jaxonomy/library/rom/surrogates.py
374 375 376 377 378 | |
PID
Bases: LTISystem
Continuous-time PID controller.
The PID controller is implemented as a state-space system with matrices (A, B, C, D), which are then used to create a (second-order) LTISystem. Note that this only supports single-input, single-output PID controllers.
The PID controller implements the following control law:
u = kp * e + ki * ∫e + kd * ė
where e is the error signal, and ∫e and ė are the integral and derivative of the error signal, respectively.
With a filter coefficient of n (to make the transfer function proper), the
state-space form of the system is:
A = [[0, 1], [0, -n]]
B = [[0], [1]]
C = [[ki * n, (kp * n + ki) - (kp + kd * n) * n]]
D = [[kp + kd * n]]
Since D is nonzero, the block is feedthrough.
Input ports
(0) e: Error signal (scalar)
Output ports
(0) u: Control signal (scalar)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kp
|
Proportional gain |
required | |
ki
|
Integral gain |
required | |
kd
|
Derivative gain |
required | |
n
|
Derivative filter coefficient |
required | |
initial_state
|
Initial state of the integral term (default: 0) |
0.0
|
Source code in jaxonomy/library/linear_system.py
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | |
PIDController2DOF
Bases: LeafSystem
Two-degree-of-freedom discrete-time PID controller.
Implements the standard 2-DOF PID control law::
u = Kp * (b*r - y) + Ki * integral(r - y) + Kd * d/dt(c*r - y)
where r is the setpoint, y is the measurement, and b and
c are setpoint weights in [0, 1] for the proportional and
derivative paths respectively. With b = c = 1 the block is
numerically equivalent to the existing :class:PIDDiscrete block on
the error signal e = r - y; with b = c = 0 it becomes an
"I-PD" controller (only the integral term reacts to setpoint
changes).
The integral term uses a forward-Euler approximation::
e_int[k+1] = e_int[k] + (r[k] - y[k]) * dt
and the derivative term is computed exactly as for
:class:DerivativeDiscrete / :class:PIDDiscrete, including the
optional first-order filter (filter_type, filter_coefficient).
Input ports
(0) Setpoint signal r.
(1) Measurement signal y.
Dynamic-port appendices, declared in this deterministic order
when the corresponding *_dynamic flag is True:
(a) b if b_dynamic=True (T-127-followup-external-weights)
(b) c if c_dynamic=True
(c) kp if kp_dynamic=True
(T-127-followup-gain-scheduling)
(d) ki if ki_dynamic=True
(e) kd if kd_dynamic=True
(f) kff if kff_dynamic=True
(g) u_ext if tracking_enabled=True
(T-127-followup-tracking-mode)
(h) mode_flag if tracking_enabled_dynamic=True
(T-127-followup-bumpless-mode-switch). Scalar input cast to
a {0, 1} gate that selects whether the tracking-pull branch
runs this tick (0 = OFF / AUTO, non-zero = ON / MANUAL /
TRACKING). Requires tracking_enabled=True so the
u_ext port exists.
Port indices skip any flag set to False, so e.g. with only
kp_dynamic=True the kp port is at index 2; with
b_dynamic=True + kp_dynamic=True the b port is at
index 2 and kp is at index 3. The instance attributes
self.b_index / self.c_index / self.kp_index /
self.ki_index / self.kd_index / self.kff_index /
self.u_ext_index / self.mode_flag_index expose the
resolved positions.
Output ports
(0) The control signal u computed by the 2-DOF PID law.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kp
|
Proportional gain (scalar). |
1.0
|
|
ki
|
Integral gain (scalar). |
1.0
|
|
kd
|
Derivative gain (scalar). |
1.0
|
|
b
|
Setpoint weight for the proportional term, in |
1.0
|
|
c
|
Setpoint weight for the derivative term, in Recommendation for real-world controllers: prefer
|
1.0
|
|
derivative_on_measurement_only
|
T-127-followup-derivative-on-measurement. Convenience flag
equivalent to |
required | |
b_dynamic
|
If True, the proportional setpoint weight |
False
|
|
c_dynamic
|
If True, the derivative setpoint weight |
False
|
|
dt
|
Sampling period of the block. |
required | |
initial_state
|
Initial value of the integral. Default 0.0. |
0.0
|
|
filter_type
|
One of |
'none'
|
|
filter_coefficient
|
Filter coefficient |
1.0
|
|
output_min
|
Lower saturation limit on the control output (T-127-followup-
anti-windup). |
None
|
|
output_max
|
Upper saturation limit on the control output. |
None
|
|
anti_windup_method
|
One of
Anti-windup is a no-op unless |
'none'
|
|
anti_windup_gain
|
Tracking time constant |
1.0
|
|
integrator_method
|
One of |
'forward_euler'
|
|
derivative_method
|
One of |
'forward_diff'
|
|
kff
|
Feedforward gain on the setpoint (T-127-followup-feedforward).
Adds |
0.0
|
|
kp_dynamic
|
T-127-followup-gain-scheduling. If True, the proportional
gain |
False
|
|
ki_dynamic
|
Same as |
False
|
|
kd_dynamic
|
Same as |
False
|
|
kff_dynamic
|
Same as |
False
|
|
error_deadband
|
T-127-followup-deadband-error. Non-negative scalar; when
positive, the raw error signal |
0.0
|
|
error_deadband_mode
|
|
'hard'
|
|
error_deadband_sharpness
|
Positive scalar controlling the steepness of the smooth
deadband transition (passed straight to
:func: |
10.0
|
|
tracking_enabled
|
T-127-followup-tracking-mode. If True, declares an extra
input port
This is the standard "tracking mode" / "manual mode"
mechanism: while another controller (or an operator) drives
|
False
|
|
tracking_gain
|
Tracking time constant |
1.0
|
|
integrate_tracking_error
|
T-127-followup-i-on-error-only. Selects whether the
tracking-error term
preserving the T-127-followup-tracking-mode kernel exactly.
When
and |
True
|
|
tracking_enabled_dynamic
|
T-127-followup-bumpless-mode-switch. When |
False
|
Gain-scheduling recipe
Each of kp_dynamic, ki_dynamic, kd_dynamic, and
kff_dynamic is the natural plug for a lookup-table-driven
gain. The standard wiring uses one :class:LookupTable1d (or
:class:LookupTable2d for two scheduling variables) per
scheduled gain and the same scheduling-variable signal source
for all of them::
import jaxonomy
from jaxonomy.library import (
Constant, LookupTable1d, PIDController2DOF,
)
builder = jaxonomy.DiagramBuilder()
r = builder.add(Constant(1.0, name="r"))
y = builder.add(Constant(0.0, name="y"))
# Scheduling variable -- e.g. engine speed, Mach number,
# tank level. Replace with whatever source you have.
sched = builder.add(Constant(0.5, name="sched"))
# Schedule kp as a function of the scheduling variable.
kp_tbl = builder.add(
LookupTable1d(
input_array=[0.0, 0.5, 1.0],
output_array=[1.0, 2.0, 4.0],
interpolation="linear",
name="kp_schedule",
)
)
pid = builder.add(
PIDController2DOF(
dt=0.01, kp_dynamic=True, name="pid"
)
)
builder.connect(r.output_ports[0], pid.input_ports[0])
builder.connect(y.output_ports[0], pid.input_ports[1])
builder.connect(sched.output_ports[0], kp_tbl.input_ports[0])
# kp port is at index 2 when only kp_dynamic is set.
builder.connect(kp_tbl.output_ports[0], pid.input_ports[2])
Because every dynamic port is a regular signal port, gradients
flow through the lookup-table parameters (breakpoints / values)
AND through the scheduling-variable signal — the standard T-114
guarantee. Multiple gains can be scheduled simultaneously;
flagging ki_dynamic and kd_dynamic simply adds two more
ports for the integral / derivative tables.
Source code in jaxonomy/library/dynamics.py
2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 | |
cohen_coon(K, tau, theta, dt, mode='PID', **kwargs)
classmethod
Construct a PID tuned by the Cohen-Coon rule for a FOPDT plant.
For a first-order-plus-dead-time plant
G(s) = K * exp(-theta*s) / (tau*s + 1) (process gain K,
time constant tau, dead time theta), the Cohen-Coon
(1953) formulas are::
r = theta / tau
P: Kp = (1/K) * (1/r) * (1 + r/3)
PI: Kp = (1/K) * (1/r) * (9/10 + r/12)
Ti = theta * (30 + 3*r) / (9 + 20*r)
PID: Kp = (1/K) * (1/r) * (4/3 + r/4)
Ti = theta * (32 + 6*r) / (13 + 8*r)
Td = theta * 4 / (11 + 2*r)
with Ki = Kp / Ti and Kd = Kp * Td.
Cohen-Coon is more aggressive than Ziegler-Nichols on plants
where theta / tau is large (dead-time-dominated processes);
it is widely used in chemical-process control.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
Process (steady-state) gain. Must be non-zero. |
required | |
tau
|
First-order time constant in seconds. Must be positive. |
required | |
theta
|
Dead time in seconds. Must be positive. |
required | |
dt
|
Sampling period for the discrete PID. |
required | |
mode
|
One of |
'PID'
|
|
**kwargs
|
Forwarded to :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
the Cohen-Coon formulas for the requested mode. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in jaxonomy/library/dynamics.py
4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 | |
from_dict(data, **block_kwargs)
classmethod
Reconstruct a :class:PIDController2DOF from a config dict.
Extra keyword arguments (name=, system_id=, ...) are
forwarded to the constructor so a deserialized block can pick
up a fresh name in its target diagram.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict produced by :meth: |
required | |
**block_kwargs
|
forwarded to |
{}
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Returns:
| Type | Description |
|---|---|
|
A new :class: |
|
|
matches |
Source code in jaxonomy/library/dynamics.py
3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 | |
standard(kp, ki, kd, dt, **kwargs)
classmethod
Construct a textbook PID with b = c = 1.
Convenience factory equivalent to PIDController2DOF(dt, kp,
ki, kd): the proportional and derivative paths both see the
setpoint with weight 1, so the block reduces to a 1-DOF PID on
the error signal e = r - y. Useful as the explicit
counterpart to :meth:with_derivative_on_measurement —
callers self-document which 2-DOF configuration they want.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kp
|
Proportional gain. |
required | |
ki
|
Integral gain. |
required | |
kd
|
Derivative gain. |
required | |
dt
|
Sampling period. |
required | |
**kwargs
|
Forwarded to :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Source code in jaxonomy/library/dynamics.py
3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 | |
to_dict()
Return a JSON-serializable dict describing this controller.
The dict captures every construction-time field that controls
the block's behavior — all @parameters-registered fields
plus the mode strings and *_dynamic port-topology flags
that live outside @parameters. Round-tripping through
:meth:from_dict (optionally via json.dumps /
json.loads) produces a block with identical step-response
behavior on a fixed input.
Note
Diagram wiring (which signal feeds which input port) is
not part of the block config and must be re-established by
the caller after :meth:from_dict. This is especially
relevant when any *_dynamic flag is True — the
reconstructed block still declares the runtime port, but
it has no upstream connection until the caller wires it
up.
Returns:
| Type | Description |
|---|---|
|
dict mapping each of :attr: |
|
|
attr: |
Source code in jaxonomy/library/dynamics.py
3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 | |
tyreus_luyben(Ku, Tu, dt, **kwargs)
classmethod
Construct a PI controller tuned by the Tyreus-Luyben rule.
A gentler Ziegler-Nichols alternative that trades response speed for robustness. Tyreus & Luyben (1992) recommend the PI form for most chemical-process applications because the derivative term tends to amplify measurement noise::
Kp = Ku / 3.2, Ti = 2.2 * Tu → Ki = Kp / Ti
and Kd = 0 (no derivative action). Compared with Z-N,
Tyreus-Luyben gives roughly 1/3 the proportional gain and a
~4x longer integral time, producing a much less aggressive
loop with substantially better robustness to model error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Ku
|
Ultimate gain (proportional-only gain at sustained oscillation). Must be positive. |
required | |
Tu
|
Ultimate period (period of the sustained oscillation in seconds). Must be positive. |
required | |
dt
|
Sampling period for the discrete PID. |
required | |
**kwargs
|
Forwarded to :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
controller ( |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in jaxonomy/library/dynamics.py
4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 | |
with_derivative_on_measurement(kp, ki, kd, dt, **kwargs)
classmethod
Construct a PID with derivative-on-measurement-only (b=1, c=0).
Convenience factory for the standard "no derivative kick"
recipe used by most real-world controllers. With c = 0 the
derivative term sees only the measurement (-d/dt(y)), so a
step change in the setpoint does NOT inject a Kd / dt spike
through the derivative path — only integral and proportional
action drive the transient.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kp
|
Proportional gain. |
required | |
ki
|
Integral gain. |
required | |
kd
|
Derivative gain. |
required | |
dt
|
Sampling period. |
required | |
**kwargs
|
Forwarded to :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Source code in jaxonomy/library/dynamics.py
3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 | |
ziegler_nichols(Ku, Tu, dt, mode='PID', **kwargs)
classmethod
Construct a PID tuned by the Ziegler-Nichols ultimate-cycle rule.
Given the ultimate gain Ku (the proportional-only gain at
which the closed loop just sustains oscillation) and the
corresponding ultimate period Tu, the Z-N table maps to
controller gains as::
P: Kp = 0.5 * Ku, Ki = 0, Kd = 0
PI: Kp = 0.45 * Ku, Ti = Tu / 1.2 → Ki = 0.54*Ku/Tu, Kd = 0
PID: Kp = 0.6 * Ku, Ti = Tu / 2.0 → Ki = 1.2 *Ku/Tu,
Td = Tu / 8.0 → Kd = 0.075*Ku*Tu
The coefficients are the canonical Ziegler & Nichols (1942) values; see e.g. Astrom & Hagglund, PID Controllers: Theory, Design, and Tuning (1995), Table 4.1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
Ku
|
Ultimate gain (proportional-only gain at sustained oscillation). Must be positive. |
required | |
Tu
|
Ultimate period (period of the sustained oscillation in seconds). Must be positive. |
required | |
dt
|
Sampling period for the discrete PID. |
required | |
mode
|
One of |
'PID'
|
|
**kwargs
|
Forwarded to :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
the Z-N table for the requested mode. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in jaxonomy/library/dynamics.py
4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 | |
PIDDiscrete
Bases: LeafSystem
Discrete-time PID controller.
This block implements a discrete-time PID controller with a first-order approximation to the integrated error and an optional derivative filter. The integrated error term is computed as:
e_int[k+1] = e_int[k] + e[k] * dt
where e is the error signal and dt is the sampling period. The derivative
term is computed in the same way as for the DerivativeDiscrete block, including
filter options described there. With the running error integral e_int and
current estimate of the time derivative of the error e_dot, the output is:
u[k] = kp * e[k] + ki * e_int[k] + kd * e_dot[k]
Input ports
(0) The error signal.
Output ports
(0) The control signal computed by the PID algorithm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kp
|
The proportional gain (scalar) |
1.0
|
|
ki
|
The integral gain (scalar) |
1.0
|
|
kd
|
The derivative gain (scalar) |
1.0
|
|
dt
|
The sampling period of the block. |
required | |
initial_state
|
The initial value of the running error integral. Default is 0. |
0.0
|
|
enable_external_initial_state
|
Source for the value used for the integrator initial state. True=from inport, False=from the initial_state parameter. |
False
|
|
filter_type
|
One of "none", "forward", "backward", or "bilinear". Determines the type of filter used to estimate the derivative of the error signal. Default is "none". See DerivativeDiscrete documentation for details. |
'none'
|
|
filter_coefficient
|
The filter coefficient for the derivative filter. Default is 1.0. See DerivativeDiscrete documentation for details. |
1.0
|
Source code in jaxonomy/library/dynamics.py
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 | |
initialize_static_data(context)
Set the initial state from the input port, if specified via config
Source code in jaxonomy/library/dynamics.py
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 | |
PRBS
Bases: LeafSystem
Pseudo-Random Binary Sequence (PRBS) source.
Emits +amplitude or -amplitude at each sample_time
tick, drawn from a fair Bernoulli(0.5) under
jax.random.bernoulli and remapped via 2*b - 1. Useful as
a broad-band excitation signal for system identification.
The amplitude parameter is differentiable (scaling the binary
selector); the +1 / -1 selector itself is wrapped in
lax.stop_gradient.
Input ports
None.
Output ports
(0) The most recent ±amplitude sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sample_time
|
float
|
Period (s) at which a fresh bit is drawn. |
required |
amplitude
|
float
|
Magnitude of the binary output (differentiable). |
1.0
|
seed
|
int
|
Integer seed for the PRNG key. If |
None
|
Notes
Phase 1 uses Bernoulli(0.5) sampling rather than a true
maximal-length LFSR. Period-faithful PRBS-N (n_bits register
size) is deferred — see T-122-followup-lfsr.
Per-vmap-batch independence: pass fold_in_batch_index=True
(T-122-followup-vmap-fold-in) to derive a per-replica
independent PRNG stream via jax.lax.axis_index("batch")
inside simulate_batch(use_vmap=True) / simulate_distributed.
Default False preserves bit-identical phase 1 behaviour.
Source code in jaxonomy/library/sources.py
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 | |
PRBSLFSR
Bases: LeafSystem
True maximal-length PRBS-N source built on a binary LFSR.
Emits +amplitude or -amplitude at each sample_time tick,
drawn from a Linear-Feedback Shift Register (LFSR) of length
register_length configured with the standard primitive
feedback polynomial. The output sequence has period exactly
2^N - 1 and a flat power spectrum below 1/(2N) of the
sample rate, making it the canonical "white" excitation for system
identification.
Reproducibility: same seed -> bit-identical sequence. Distinct
seeds traverse the same cyclic orbit at different starting phases.
Differentiability: amplitude is a dynamic parameter and flows
through gradients linearly; the binary selector itself is wrapped
in lax.stop_gradient (the LSB extraction is non-differentiable).
Input ports
None.
Output ports
(0) The most recent ±amplitude sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sample_time
|
float
|
Period (s) at which the LFSR advances by one step. |
required |
amplitude
|
float
|
Magnitude of the binary output (differentiable). |
1.0
|
register_length
|
int
|
One of |
15
|
seed
|
int
|
Non-zero integer seeding the LFSR register state. |
1
|
Notes
Per-vmap-batch independence: pass fold_in_batch_index=True
(T-122-followup-vmap-fold-in) to derive a per-replica
independent starting phase on the same maximal-length cycle.
Inside simulate_batch(use_vmap=True) /
simulate_distributed (which wrap their vmap with
axis_name="batch"), the LFSR register is XOR-perturbed by a
per-replica non-zero salt derived from
jax.lax.axis_index("batch") on the very first update step
(tracked via a phase_advanced flag in the discrete state).
The salt is masked to the low N bits of the register and
promoted from 0 to 1 to avoid the all-zero fixed point. Default
False preserves bit-identical behaviour with the original
LFSR follow-up.
Source code in jaxonomy/library/sources.py
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 | |
PolynomialChaos
Bases: LeafSystem
Polynomial-chaos surrogate y = sum_k c_k Psi_k(u) as a feedthrough
block. Input port 0 is the feature vector u; the coefficients are a
dynamic parameter (Xiu & Karniadakis 2002).
Source code in jaxonomy/library/rom/surrogates.py
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | |
Power
Bases: FeedthroughBlock
Raise the input signal to a constant power.
Dispatches to jax.numpy.power, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.power.html
For input signal u with exponent p, the output will be y = u ** p.
Input ports
(0) The input signal.
Output ports
(0) The input signal raised to the power of the exponent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exponent
|
The exponent to which the input signal is raised. |
required |
Source code in jaxonomy/library/math_ops.py
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | |
Prelookup
Bases: LeafSystem
Compute the (bucket_index, fraction) pair for a query against a precomputed grid.
This is the upstream half of the standard
Prelookup/InterpolationUsingPrelookup pair. Pair with one or
more :class:InterpolationUsingPrelookup blocks downstream -- each
can interpolate a DIFFERENT output table that shares the same grid
axis without re-running the bucket search.
The marketing wedge: when N downstream tables share one query axis
(e.g. 10 lookup maps on a common engine-RPM input), this saves
N - 1 binary searches per evaluation.
Input ports
(0) -- the query coordinate (scalar).
Output ports
(0) -- a NamedTuple with fields (index, fraction) ready
to plug into one or more :class:InterpolationUsingPrelookup
blocks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_array
|
1-D, strictly-increasing grid of breakpoints. Stored verbatim for the bucket search. |
required | |
dtype
|
optional
|
If set (e.g. |
None
|
extrapolation
|
(optional, T - 114 - fu - prelookup - extrap)
|
Out-of-range policy for the |
'clip'
|
Notes
Differentiable through the query coordinate via fraction
(the discrete index is piecewise-constant).
Source code in jaxonomy/library/tables.py
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 | |
extrapolation
property
The OOB policy applied to alpha ("clip"/"linear"/"nan").
input_array
property
The breakpoint array used for the bucket search.
PrelookupInverse
Bases: LeafSystem
Compute the (bucket_index, fraction) pair for an INVERSE-direction lookup against a strictly-monotonic value array.
Forward :class:Prelookup answers: given x, find (i, alpha)
s.t. xp[i] + alpha * (xp[i+1] - xp[i]) ≈ x.
Inverse :class:PrelookupInverse answers: given y, find
(i, alpha) s.t. yp[i] + alpha * (yp[i+1] - yp[i]) ≈ y.
The output is the same NamedTuple-typed
:class:_PrelookupResult produced by :class:Prelookup, so it plugs
straight into one or more :class:InterpolationUsingPrelookup blocks
connected to OTHER tables -- typically the inverse table that maps
i back to the recovered x (for example the breakpoints of the
forward table).
Marketing wedge: implicit equations y = f(x) where f is a
monotonic 1-D table -- gain scheduling, sensor calibration, etc.
Input ports
(0) -- the query coordinate in the OUTPUT space (y).
Output ports
(0) -- a :class:_PrelookupResult NamedTuple
(index, fraction) ready to plug into an
:class:InterpolationUsingPrelookup block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
output_array
|
1-D, strictly-monotonic (increasing OR decreasing) array of values to invert. Stored verbatim for the bucket search; decreasing tables are handled by reversing the search direction. |
required | |
dtype
|
optional
|
If set, the value array is cast to this dtype on
construction. Mirrors the :class: |
None
|
extrapolation
|
optional
|
Only |
'clip'
|
Notes
Differentiable through the query coordinate and through
output_array. Non-monotonic output_array raises
ValueError at construction time.
Source code in jaxonomy/library/tables.py
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 | |
direction
property
"increasing" or "decreasing" -- monotonicity sense.
extrapolation
property
The OOB policy (always "clip" in this followup).
output_array
property
The 1-D monotonic value array being inverted.
Product
Bases: ReduceBlock
Compute the product and/or quotient of the input signals.
The block will multiply or divide the input signals, depending on the specified
operators. For example, if the block has three inputs u1, u2, and u3 and
is configured with operators="**/", then the output signal will be
y = u1 * u2 / u3. By default, the block will multiply all of the input signals.
Input ports
(0..n_in-1) The input signals.
Output ports
(0) The product and/or quotient of the input signals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_in
|
The number of input ports. |
required | |
operators
|
A string of length |
None
|
|
denominator_limit
|
Currently unsupported |
None
|
|
divide_by_zero_behavior
|
Currently unsupported |
None
|
Source code in jaxonomy/library/math_ops.py
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | |
ProductOfElements
Bases: FeedthroughBlock
Compute the product of the elements of the input signal.
Dispatches to jax.numpy.prod, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.prod.html
Input ports
(0) The input signal.
Output ports
(0) The product of the elements of the input signal.
Source code in jaxonomy/library/math_ops.py
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | |
Pulse
Bases: SourceBlock
A periodic pulse signal.
Given amplitude a, pulse width w, and period p, the output signal is:
y(t) = a if t % p < w else 0
where % is the modulo operator.
Input ports
None
Output ports
(0) The pulse signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amplitude
|
The amplitude of the pulse signal. |
1.0
|
|
pulse_width
|
The fraction of the period during which the pulse is "high". |
0.5
|
|
period
|
The period of the pulse signal. |
1.0
|
|
phase_delay
|
Currently unsupported. |
0.0
|
Source code in jaxonomy/library/sources.py
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | |
PyTorch
Bases: LeafSystem
Block to perform inference with a pre-trained PyTorch model saved as TorchScript.
The input to the block should be of compatible type and shape expected by
the TorchScript. For example, if the TorchScript model expects
a torch.float32 tensor of shape (3, 224, 224), the input to the block should be
a jax.numpy array of shape (3, 224, 224) of dtype jnp.float32.
For output types, if no casting is specified through the cast_outputs_to_dtype
parameter, the output of the block will have the same dtype as the TorchScript
model output, but expressed as jax.numpy types. For example. if the
TorchScript model outputs a torch.float32 tensor, the output of the block will be
a jax.numpy array of dtype jnp.float32.
If casting is specified through cast_outputs_to_dtype parameter, all the outputs,
of the block will be casted to this specific jax.numpy dtype.
.. note:: float32 models under jaxonomy's global x64.
import jaxonomy enables JAX 64-bit mode (jax_enable_x64)
for the whole process, so upstream signals are float64 by
default. A TorchScript model traced in torch.float32
therefore receives float64 inputs (a dtype error or a silent
arithmetic change) unless you cast at the block boundary.
One-line idiom: pass cast_outputs_to_dtype="float32" and
feed the block x.astype(jnp.float32) inputs.
Input ports
(i) The ith input to the model.
Output ports
(j) The jth output of the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Path to the model Torchscript |
required |
num_inputs
|
int
|
The number of inputs to the model. Only required for TorchScript models. |
1
|
num_outputs
|
int
|
The number of outputs of the model. |
1
|
cast_outputs_to_dtype
|
str
|
The dtype to cast all the outputs of the block to. Must correspond to a
|
None
|
add_batch_dim_to_inputs
|
bool
|
Whether to add a new first dimension to the inputs before evaluating the TorchScript or TensorFlow model. This is useful when the model expects a batch dimension. |
False
|
Source code in jaxonomy/library/predictor.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
initialize_static_data(context)
Infer the output shapes and dtypes of the ML model.
Source code in jaxonomy/library/predictor.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | |
QuadraticCost
Bases: ReduceBlock
LQR-type quadratic cost function for a state and input.
Computes the cost as x'Qx + u'Ru, where Q and R are the cost matrices.
In order to compute a running cost, combine this with an Integrator
or IntegratorDiscrete block.
Source code in jaxonomy/library/costs_and_losses.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
QuanserHAL
Bases: LeafSystem
Hardware Abstraction Layer for Quanser hardware.
This block provides an interface to virtual or physical Quanser hardware. It requires that the Quanser hardware or QLabs simulator be properly configured and that the Quanser python library is available on the system path. See the Quanser documentation for more information.
To use an idealized model of the Qube Servo hardware, see the
jaxonomy.library.QubeServoModel block, which may be run without hardware
or in the cloud-based simulation UI.
Input ports
(0) Control signal to the motor in volts
Output ports
(0) The observed rotor and pendulum angles in radians
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
The time step of the simulation. |
required | |
version
|
The version of the Qube hardware (2 or 3). By default, version 2 is
used with |
2
|
|
hardware
|
If True, connect to the physical hardware. If False, connect to the QLabs simulator. |
False
|
|
name
|
The name of the system in the Jaxonomy model. |
'QuanserHAL'
|
Source code in jaxonomy/library/quanser.py
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | |
Quantizer
Bases: FeedthroughBlock
Discritize the input signal into a set of discrete values.
Given an input signal u and a resolution interval, this block
quantizes the input signal onto the integer multiples of interval.
The output signal is y = interval * f(u / interval) where f is
selected by mode:
"round"(default): round-half-to-even (banker's rounding, IEEE-754 default). Byte-equivalent with the phase-1 implementation (which usednpa.roundunconditionally)."floor": round toward -inf (truncation in many DSP impls)."ceil": round toward +inf."trunc": round toward zero (chops the fractional part regardless of sign).
Quantization is non-differentiable: the output is piecewise-constant
with measure-zero jumps. The block wraps the rounded result in
:func:jax.lax.stop_gradient (JAX backend only) so JAX always sees a
zero gradient through the block. This both matches the underlying
mathematical reality and prevents spurious gradient leakage if any
backend ever provides a smoothed surrogate for round/floor/
ceil/trunc. Under the numpy backend the helper is the
identity, preserving dtype/value byte-equivalence.
Input ports
(0) The continuous input signal. In most cases, should be scaled to the range
[0, interval].
Output ports
(0) The quantized output signal, on the same scale as the input signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
interval
|
The quantization step size — output values are integer
multiples of |
required | |
mode
|
One of |
'round'
|
Source code in jaxonomy/library/nonlinearities.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | |
QubeServoModel
Bases: LeafSystem
Plant model for the Quanser Qube Servo Furuta Pendulum.
The Quanser Qube Servo is a pendulum controlled by a rotary arm. The rotary arm is actuated by a DC motor. The pendulum is free to rotate about the rotary arm.
The state of the system is given by the rotor angle (theta), pendulum angle (alpha), rotor angular velocity, and pendulum angular velocity. The input to the system is the voltage applied to the motor, which is converted to torque by a simple linear model.
Input ports
(0) The motor voltage signal
Output ports
(0) If full_state_output is False, the rotor angle and pendulum angle.
Otherwise, will return the entire continuous state vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x0
|
Initial state of the system [theta, alpha, theta_dot, alpha_dot] |
[0.0, 0.0, 0.0, 0.0]
|
|
Rm
|
Motor resistance (Ohms) |
8.4
|
|
km
|
Back-emf constant (V-s/rad) |
0.042
|
|
mr
|
Rotary arm mass (kg) |
0.095
|
|
Lr
|
Rotor arm length (m) |
0.085
|
|
br
|
Rotor arm damping coefficient (N-m-s/rad) |
0.0005
|
|
mp
|
Pendulum mass (kg) |
0.024
|
|
Lp
|
Pendulum arm length (m) |
0.129
|
|
bp
|
Pendulum damping coefficient (N-m-s/rad) |
2.5e-05
|
|
g
|
Gravitational constant (m/s^2) |
9.81
|
|
kr
|
Feedback control to send the rotor back to zero |
0.0
|
|
full_state_output
|
If True, output the full state vector. Otherwise, only output the rotor and pendulum angles. |
False
|
Source code in jaxonomy/library/quanser.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
RBFModel
Fitted radial-basis-function interpolant with optional polynomial tail.
s(x) = sum_i w_i phi(||x - c_i||) + sum_k c_k p_k(x) (Hardy 1971;
Wendland 2005).
Source code in jaxonomy/library/rom/surrogates.py
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | |
predict(Xstar)
Interpolant value at Xstar (jax-traceable).
Source code in jaxonomy/library/rom/surrogates.py
499 500 501 502 503 504 505 506 | |
RadialBasisSurrogate
Bases: LeafSystem
RBF surrogate y = sum_i w_i phi(||u - c_i||) (+ poly tail) as a
feedthrough block. Input port 0 is the feature vector u; the RBF weights
(and polynomial-tail coefficients) are dynamic parameters (Hardy 1971).
Source code in jaxonomy/library/rom/surrogates.py
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | |
Ramp
Bases: SourceBlock
Output a linear ramp signal in time.
Given a slope m, a start value y0, and a start time t0, the output signal is:
y(t) = m * (t - t0) + y0 if t >= t0 else y0
where t is the current simulation time.
Input ports
None
Output ports
(0) The ramp signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_value
|
The value of the output signal at the start time. |
0.0
|
|
slope
|
The slope of the ramp signal. |
1.0
|
|
start_time
|
The time at which the ramp signal begins. |
1.0
|
|
units
|
(optional, T - 104 - followup - units - on - source - blocks)
|
If set, the output port advertises this :class: |
None
|
Source code in jaxonomy/library/sources.py
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | |
RandomNumber
Bases: LeafSystem
Discrete-time random number generator.
Generates independent, identically distributed random numbers at each time step.
Dispatches to jax.random for the actual random number generation.
Supported distributions include "ball", "cauchy", "choice", "dirichlet", "exponential", "gamma", "lognormal", "maxwell", "normal", "orthogonal", "poisson", "randint", "truncated_normal", and "uniform".
See https://jax.readthedocs.io/en/latest/jax.random.html#random-samplers for a full list of available distributions and associated parameters.
Although the JAX random number generator is a deterministic function of the key, this block maintains the key as part of the discrete state, making it a stateful RNG. The block can be seeded for reproducibility by passing an integer seed; if None, a random seed will be generated using numpy.random.
Note that this block should typically not be used as a source of randomness for
continuous-time systems, as it generates a discrete-time signal. For continuous
systems, use a continuous-time noise source, such as WhiteNoise.
Input ports
None
Output ports
(0) The most recently generated random number.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float
|
The rate at which random numbers are generated. |
required |
distribution
|
str
|
The name of the random distribution to sample from. |
'normal'
|
seed
|
int
|
An integer seed for the random number generator. If None, a random 32-bit seed will be generated. |
None
|
dtype
|
DTypeLike
|
data type of the random number. If None, the default data type for the specified distribution will be used. Not all distributions support all data types; check the JAX documentation for details. |
None
|
distribution_parameters
|
A dictionary of additional parameters to pass to the distribution function. |
{}
|
Source code in jaxonomy/library/random.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
with_key(key, **kwargs)
classmethod
Construct RandomNumber with an explicit JAX PRNGKey.
Use this when you need independent noise streams in batched (jax.vmap) simulations.
Example
keys = jax.random.split(jax.random.PRNGKey(0), 16)
Each diagram gets a different key
diagrams = [ build_diagram_with( RandomNumber.with_key(keys[i], ...) ) for i in range(16) ]
OR with with_parameters (preferred):
diagram.with_parameters({"noise.key": keys[i]})
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
'jax.Array'
|
JAX PRNGKey array (shape (2,) for default RNG) |
required |
**kwargs
|
other constructor arguments |
{}
|
Source code in jaxonomy/library/random.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | |
RandomSource
Bases: LeafSystem
Multi-distribution discrete-time random source.
Unified rebuild of the single-distribution UniformRandomNumber
pattern from T-122 phase 1: one block, four distributions, selected
at construction by a string flag plus a params dict.
Supported distributions::
distribution="uniform" params={"low": ..., "high": ...}
distribution="normal" params={"mean": ..., "std": ...}
distribution="lognormal" params={"mu": ..., "sigma": ...}
distribution="triangular" params={"low": ..., "peak": ...,
"high": ...}
distribution="exponential" params={"rate": ...}
distribution="poisson" params={"rate": ...} # integer-typed output
distribution="bernoulli" params={"p": ...} # integer-typed 0/1 output
distribution="beta" params={"alpha": ..., "beta": ...}
distribution="gamma" params={"shape": ..., "scale": ...}
distribution="weibull" params={"shape": ..., "scale": ...}
distribution="pareto" params={"scale": ..., "alpha": ...}
"exponential" is differentiable through rate via the
standard inverse-CDF reparameterisation x = -log(1-u) / rate;
"poisson" is the discrete count distribution and is not
differentiable through rate w.r.t. its samples (the per-sample
grad is zero by construction — the sampler is wrapped in
stop_gradient). See T-122-followup-poisson.
Same seed -> bit-identical sequence (determinism contract). Under
simulate_batch(use_vmap=True) / simulate_distributed, pass
fold_in_batch_index=True (T-122-followup-vmap-fold-in) to derive
a per-replica independent stream from the same master seed via
jax.lax.axis_index("batch"). Default False preserves
bit-identical behaviour with the original distributions follow-up.
All named params flow through smooth, differentiable
reparameterisations of an underlying Uniform[0,1) or N(0,1)
draw; the random draw itself is wrapped in lax.stop_gradient so
gradients of downstream losses flow cleanly through the
distribution parameters but never attempt to differentiate the PRNG
key.
Input ports
None.
Output ports
(0) The most recent sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sample_time
|
float
|
Period (s) at which a fresh sample is drawn. |
required |
distribution
|
str
|
One of |
'uniform'
|
params
|
dict
|
Dict of distribution parameters (see above for keys). Each value is registered as a dynamic parameter and is differentiable / vmap-mappable. |
None
|
seed
|
int
|
Integer seed for the PRNG key. If |
None
|
shape
|
Output shape. Default |
()
|
Notes
Honest-fallback note: the spec contemplated a lax.switch
over distributions to share one block class. Because each
distribution has different params keys (and triangular
has three), a runtime switch would require padding/aligning
the param tuples per distribution, which is clunky and
defeats the whole point of named params. Instead we dispatch
at Python time on the static distribution flag --
different distributions trace into different compute graphs,
which is exactly the JAX-idiomatic path for static-flag
polymorphism.
Source code in jaxonomy/library/sources.py
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 | |
RateLimiter
Bases: LeafSystem
Limit the time derivative of the block output.
Given an input signal u computes the derivative of the output signal as:
y_rate = (u(t) - y(Tprev))/(t - Tprev)
Where Tprev is the last time the block was called for output update.
When y_rate is greater than the upper_limit, the output is:
y(t) = (t - Tprev)*upper_limit + y(Tprev)
When y_rate is less than the lower_limit, the output is:
y(t) = (t - Tprev)*lower_limit + y(Tprev)
If the lower_limit is greater than the upper_limit, and both are being violated, the upper_limit takes precedence.
Optionally, the block can also be configured with "dynamic" limits, which will add input ports for time-varying upper and lower limits.
Presently, the block is constrainted to periodic updates.
Input ports
(0) The input signal. (1) The upper limit, if dynamic limits are enabled. (2) The lower limit, if dynamic limits are enabled. (Will be indexed as 1 if dynamic upper limits are not enabled.)
Output ports
(0) The rate limited output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
upper_limit
|
The upper limit of the input signal. Default is |
inf
|
|
enable_dynamic_upper_limit
|
If True, then the upper limit can be set by an external signal. Default is False. |
False
|
|
lower_limit
|
The lower limit of the input signal. Default is |
-inf
|
|
enable_dynamic_lower_limit
|
If True, then the lower limit can be set by an external signal. Default is False. |
False
|
T-115-followup-mode-flag
The mode kwarg unifies the smooth (differentiable) variant
previously exposed as :class:SoftRateLimiter. mode="hard"
(default) is byte-equivalent to the legacy behavior.
mode="smooth" replaces the inner per-step delta clip with
:func:soft_saturate so gradients flow through active rate
limiting. Smooth mode requires finite (static) upper_limit /
lower_limit and sharpness > 0 (defaults to 10.0).
Source code in jaxonomy/library/nonlinearities.py
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | |
initialize_static_data(context)
Infer the size and dtype of the internal states
Source code in jaxonomy/library/nonlinearities.py
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | |
Reciprocal
Bases: FeedthroughBlock
Compute the reciprocal of the input signal.
Input ports
(0) The input signal.
Output ports
(0) The reciprocal of the input signal: y = 1 / u.
Source code in jaxonomy/library/math_ops.py
730 731 732 733 734 735 736 737 738 739 740 741 | |
RecursiveLeastSquares
Bases: LeafSystem
Recursive Least Squares (RLS) estimator for online parameter identification in linear-in-parameters models:
``y[k] = φ[k]ᵀ θ + noise``
where
y[k]is a scalar (or vector) measurement at timestep k,φ[k]is a regressor vector of sizen_params,θis the unknown parameter vector to be estimated.
The RLS update equations with forgetting factor λ are:
.. code-block:: text
e[k] = y[k] − φ[k]ᵀ θ̂[k−1] (prediction error)
K[k] = P[k−1] φ[k] / (λ + φ[k]ᵀ P[k−1] φ[k]) (Kalman gain)
θ̂[k] = θ̂[k−1] + K[k] e[k] (parameter update)
P[k] = (P[k−1] − K[k] φ[k]ᵀ P[k−1]) / λ (covariance update)
A forgetting factor λ < 1 down-weights older measurements, making the
estimator track slowly time-varying parameters. λ = 1 (default) is the
classic batch RLS equivalent.
The block is fully JAX-traceable and compatible with JIT/autodiff.
+--------------------+
--- phi[k] ---->| |----> theta_hat[k]
| Recursive Least |----> P[k]
--- y[k] ------>| Squares |----> prediction_error[k]
+--------------------+
Input ports
(0) phi : regressor vector at timestep k, shape (n_params,)
(1) y : scalar measurement at timestep k
Output ports
(0) theta_hat : parameter estimate, shape (n_params,)
(1) P : parameter covariance matrix, shape (n_params, n_params)
(2) prediction_error : scalar prediction residual e = y − φᵀ θ̂
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Sampling period. |
required | |
n_params
|
int Number of parameters to estimate (dimension of θ). |
required | |
theta_0
|
array_like, optional
Initial parameter estimate, shape |
required | |
P_0
|
array_like, optional
Initial covariance matrix, shape |
required | |
forgetting_factor
|
float, optional
Forgetting factor λ ∈ (0, 1]. Default |
required |
Example::
import numpy as np
import jaxonomy
from jaxonomy import library, DiagramBuilder, SimulatorOptions
# True parameters: y = 2*phi_0 + 3*phi_1
TRUE_THETA = np.array([2.0, 3.0])
DT = 0.1
rls = library.RecursiveLeastSquares(
dt=DT, n_params=2,
forgetting_factor=1.0,
)
Source code in jaxonomy/library/state_estimators/rls.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
DiscreteStateType
Bases: NamedTuple
Internal state: current parameter estimate and covariance.
Source code in jaxonomy/library/state_estimators/rls.py
88 89 90 91 92 | |
initialize(dt, n_params, theta_0=None, P_0=None, forgetting_factor=1.0)
Called at context-creation time to store resolved parameters.
Source code in jaxonomy/library/state_estimators/rls.py
175 176 177 178 179 180 181 182 183 184 185 | |
ReducedOrderModel
dataclass
A reduced model plus its provenance.
Attributes:
| Name | Type | Description |
|---|---|---|
system |
Any
|
The reduced, simulatable Jaxonomy block — an |
method |
str
|
The reduction method that produced it. |
full_order |
Optional[int]
|
State dimension of the source model (when known). |
reduced_order |
Optional[int]
|
State dimension of |
info |
dict
|
Method-specific extras — e.g. |
Source code in jaxonomy/library/rom/framework.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |
to_block()
Return the reduced Jaxonomy block (alias for .system).
Source code in jaxonomy/library/rom/framework.py
80 81 82 | |
ReferenceSubdiagram
Registry for reusable diagram templates ("reference subdiagrams").
A reference subdiagram is a parameterized diagram factory. It is registered
once via :meth:register and can then be instantiated multiple times with
different parameter values via :meth:create_diagram.
Example::
def my_submodel(instance_name, parameters):
builder = DiagramBuilder()
gain = parameters["gain"].get()
...
return builder.build(instance_name)
ref_id = ReferenceSubdiagram.register(
my_submodel,
default_parameters=[Parameter("gain", 1.0)],
)
diagram = ReferenceSubdiagram.create_diagram(ref_id, "my_instance")
Source code in jaxonomy/library/reference_subdiagram.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
create_diagram(ref_id, instance_name, *args, instance_parameters=None, **kwargs)
classmethod
Create a diagram based on the given reference ID and parameters.
Note that for submodels we evaluate all parameters, there is no "pure" string parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref_id
|
str
|
The reference ID of the diagram. |
required |
instance_name
|
str
|
Name for this specific instance. |
required |
*args
|
Variable length arguments passed to the constructor. |
()
|
|
instance_parameters
|
dict[str, Any]
|
Per-instance parameter
overrides. Keys must match names declared at registration time.
Example: |
None
|
**kwargs
|
Keyword arguments passed to the constructor. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
Diagram |
Diagram
|
The created diagram. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the reference subdiagram with the given ref_id is not found. |
ValueError
|
If an instance_parameter key does not match any registered parameter. |
Source code in jaxonomy/library/reference_subdiagram.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
get_default_parameters(ref_id)
staticmethod
Return the default parameters for the given reference subdiagram.
Source code in jaxonomy/library/reference_subdiagram.py
168 169 170 171 172 173 174 175 | |
get_parameter_definitions(ref_id)
staticmethod
Return the default parameters for the given reference subdiagram.
.. deprecated::
Use :meth:get_default_parameters instead.
Source code in jaxonomy/library/reference_subdiagram.py
177 178 179 180 181 182 183 184 185 186 | |
register(constructor, default_parameters=None, ref_id=None, parameter_definitions=None)
staticmethod
Register a diagram constructor as a reusable reference subdiagram.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
constructor
|
ReferenceSubdiagramProtocol
|
A callable that builds a :class: |
required |
default_parameters
|
list[Parameter]
|
Default :class: |
None
|
ref_id
|
str | None
|
Optional stable identifier. A UUID is generated if omitted. |
None
|
parameter_definitions
|
list[Parameter]
|
Deprecated – use |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The |
Source code in jaxonomy/library/reference_subdiagram.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
Relay
Bases: LeafSystem
Simple state machine implementing hysteresis behavior.
The input-output map is as follows:
output
|
on_value | -------<------<---------------------
| | |
| ⌄ ^
| | |
off_value |----------|-------->----->-----|
|
|---------------------------------------------- input
| off_threshold | on_threshold
Note that the "time mode" behavior of this block will follow the input signal. That is, if the input signal varies continuously in time, then the zero-crossing event from OFF->ON or vice versa will be localized in time. On the other hand, if the input signal varies only as a result of periodic updates to the discrete state, the relay will only change state at those instants. If the input signal is continuous, the block can be "forced" to this discrete-time periodic behavior by adding a ZeroOrderHold block before the input.
The exception to this is the case where there are no blocks in the system containing either discrete or continuous state. In this case the state changes will only be localized to the resolution of the major step.
Input ports
(0) The input signal.
Output ports
(0) The relay output signal, which is equal to either the on_value or the off_value, depending on the internal state of the relay.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
on_threshold
|
When input rises above this value, the internal state transitions to ON. |
required | |
off_threshold
|
When input falls below this value, the internal state transitions to OFF. |
required | |
on_value
|
Value of the output signal when state is ON. |
required | |
off_value
|
Value of the output signal when state is OFF |
required | |
initial_state
|
If equal to on_value, the block will be initialized in the ON state. Otherwise, it will be initialized to the OFF state. |
required |
Events
There are two zero-crossing events: one to transition from OFF->ON and one for the opposite transition from ON->OFF.
Source code in jaxonomy/library/logic.py
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | |
ReplicatedFunction
Bases: LeafSystem
Container block: evaluate a submodel N times in parallel via vmap.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submodel
|
Callable
|
Callable |
required |
n
|
int
|
Number of replicas. |
required |
n_inputs
|
int
|
Number of input ports the block should declare (and the number of positional inputs the submodel takes). |
1
|
in_axes
|
Sequence[int | None] | None
|
Tuple of length |
None
|
name
|
Optional block name. |
required |
Source code in jaxonomy/library/replicated.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | |
RigidBody
Bases: LeafSystem
Implements dynamics of a single three-dimensional body.
The block models both translational and rotational degrees of freedom, for a total of 6 degrees of freedom. With second-order equations, the block has 12 state variables, 6 for the position/orientation and 6 for the velocities/rates.
Currently only a roll-pitch-yaw (Euler angle) representation is supported for the orientation.
The full 12-dof state vector is x = [p_i, Φ, vᵇ, ωᵇ], where pⁱ is the
position in an inertial "world" frame i, Φ is the (roll, pitch, and yaw)
Euler angle sequence defining the rotation from the inertial "world" frame to
the body frame, vᵇ is the translational velocity with respect to body-fixed
axes b, and ωᵇ is the angular velocity about the body-fixed axes.
The mass and inertia properties of the block can independently be defined statically as parameters, or dynamically as inputs to the block.
Input ports
(0) force_vector: 3D force vector, defined in the body-fixed coordinate frame. For example, if gravity is acting on the body, the gravity vector should be pre-rotated using CoordinateRotation.
(1) torque_vector: 3D torque vector, be defined in the body-fixed coordinate frame.
(2) inertia: If enable_external_inertia_matrix=True, this input provides
the time-varying body-fixed inertia matrix.
Output ports
(0): The position in the inertial "world" frame pⁱ.
(1): The orientation of the body, represented as a roll-pitch-yaw Euler angle sequence.
(2): The translational velocity with respect to body-fixed axes vᵇ.
(3): The angular velocity about the body-fixed axes ωᵇ.
(4): (if enable_output_state_derivatives=True) The time derivatives of the
position variables in the world frame ṗⁱ. Not generally equal to the state
vᵇ, defining time derivatives in the body frame.
(5): (if enable_output_state_derivatives=True) The "Euler rates" Φ̇,
which are the time derivatives of the Euler angles. Not generally equal to
the angular velocity ωᵇ.
(6): (if enable_output_state_derivatives=True) The body-fixed acceleration
vector aᵇ.
(7): (if enable_output_state_derivatives=True) The angular acceleration in
body-fixed axes ω̇ᵇ.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_position
|
Array
|
The initial position in the inertial frame. |
required |
initial_orientation
|
Array
|
The initial orientation of the body, represented as a roll-pitch-yaw Euler angle sequence. |
required |
initial_velocity
|
Array
|
The initial translational velocity with respect to body-fixed axes. |
required |
initial_angular_velocity
|
Array
|
The initial angular velocity about the body-fixed axes. |
required |
enable_external_mass
|
bool
|
If |
False
|
mass
|
float
|
The constant value for the body mass when
|
1.0
|
enable_external_inertia_matrix
|
bool
|
If |
False
|
inertia_matrix
|
The constant value for the body inertia matrix when
|
eye(3)
|
|
enable_output_state_derivatives
|
bool
|
If |
False
|
gravity_vector
|
Array
|
The constant gravitational acceleration vector
acting on the body, defined in the inertial frame. If |
zeros(3)
|
Notes
Assumes that the inertia matrix is computed at the center of mass.
Assumes that the mass and inertia matrix are quasi-steady. This means that
if one or both is specified as "dynamic" inputs their time derivative is
neglected in the dynamics. For instance, for pure translation (w_b=0) the
approximation to Newton's law is F_net = (d/dt)(m * v) ≈ m * (dv/dt).
Source code in jaxonomy/library/rotations.py
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | |
Ros2Publisher
Bases: LeafSystem
Ros2Publisher block can emit signals to a ROS2 topic, based on input signal data.
Source code in jaxonomy/library/ros2.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
__init__(dt, topic, msg_type, fields, **kwargs)
Publish messages to a ROS2 topic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float
|
Period of the system, in both sim and real (ros2) time. |
required |
topic
|
str
|
ROS2 topic to publish to. Eg. |
required |
msg_type
|
type
|
ROS2 message type, e.g. |
required |
fields
|
dict[str, type]
|
Ordered dictionary of default values to extract from the received message. The keys are the full attribute path (with dots) to the value in the message, and the values are the default values. This is used to create the output ports with valid data types. Use Python or Numpy data types, not JAX.
|
required |
Source code in jaxonomy/library/ros2.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |
Ros2Subscriber
Bases: LeafSystem
Ros2Subscriber block listens to messages over a ROS2 topic and outputs them as signals in jaxonomy.
Source code in jaxonomy/library/ros2.py
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
__init__(dt, topic, msg_type, fields, read_before_start=True, **kwargs)
Subscribe to a ROS2 topic and extract message values to output ports.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Period of the system, in both sim and real (ros2) time. |
required | |
topic
|
str
|
ROS2 topic to subscribe to. Eg. |
required |
msg_type
|
type
|
ROS2 message type, e.g. |
required |
fields
|
dict[str, type]
|
Ordered dictionary of default values to extract from the received message. The keys are the full attribute path (with dots) to the value in the message, and the values are the default values. This is used to create the output ports with valid data types. Use Python or Numpy data types, not JAX.
|
required |
read_before_start
|
If True, the subscriber will read the first message before the simulation starts. Otherwise, the initial outputs will be 0. |
True
|
Source code in jaxonomy/library/ros2.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | |
Sawtooth
Bases: SourceBlock
Produces a modulated linear sawtooth signal.
The signal is similar to: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.sawtooth.html
Given amplitude a, period p, and phase delay phi, the output signal is:
y(t) = a * ((t - phi) % p)
where % is the modulo operator.
Input ports
None
Output ports
(0) The sawtooth signal.
Source code in jaxonomy/library/sources.py
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | |
ScalarBroadcast
Bases: FeedthroughBlock
Broadcast a scalar to a vector or matrix.
Given a scalar input u and dimensions m and n, this block will return
a vector or matrix of shape (m, n) with all elements equal to u.
Input ports
(0) The scalar input signal.
Output ports
(0) The broadcasted output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
m
|
The number of rows in the output matrix. If |
required | |
n
|
The number of columns in the output matrix. If |
required |
Source code in jaxonomy/library/math_ops.py
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | |
ShiftRegister
Bases: LeafSystem
Fixed-length shift register delay line.
Delays an input signal by exactly n_steps discrete timesteps. Output at time t is the input value from n_steps timesteps ago.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_steps
|
int
|
Number of steps to delay. STATIC — set at construction, cannot be changed at runtime. Must be >= 1. |
required |
signal_shape
|
tuple
|
Shape of each signal frame. Use () for scalar, (3,) for 3-vector, etc. |
()
|
initial_value
|
array - like
|
Value to fill the buffer with before any input has been received. Default: zeros. |
None
|
dt
|
float
|
Discrete update interval in seconds. |
0.01
|
Ports
Input[0] "u": signal to delay, shape=signal_shape Output[0] "y": delayed signal, shape=signal_shape
Source code in jaxonomy/library/delay.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
SignalDatatypeConversion
Bases: FeedthroughBlock
Convert the input signal to a different data type. Input ports: (0) The input signal. Output ports: (0) The input signal converted to the specified data type. Parameters: dtype: The data type to which the input signal is converted. Must be a valid NumPy data type, e.g. "float32", "int64", etc.
Source code in jaxonomy/library/routing.py
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
SimulationResultsSource
Bases: LeafSystem
Replays one recorded trajectory from :class:~jaxonomy.simulation.types.SimulationResults.
Output port y is the signal value at the current simulation time, using linear
interpolation or zero-order hold. Values clamp to the first/last sample outside
the recorded time range (jnp.interp semantics for linear mode).
Source code in jaxonomy/library/data_source.py
443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | |
Sindy
Bases: LeafSystem
This class implements System Identification (SINDy) algorithm with or without control inputs for contiuous-time and discrete-time systems.
The learned continuous-time dynamical system model will be of the form:
dx/dt = f(x, u)
where x is the state vector and u is the optional control input vector. The
block will output the full state vector x of the system.
The learned discrete-time dynamical system model will be of the form:
x_{k+1} = f(x_k, u_k)
where x_k is the state vector at time step k and u_k is the optional control
vector. The block will update the output to x_k at an interval provided by the
parameter discrete_time_update_interval.
Input ports
(0) u: control vector for the system. This port is only available if the Sindy
model is trained with control inputs, i.e. control_input_columns is not
None during training.
Output ports
(0) x: full state output of the system.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Path to the CSV file containing training data. |
None
|
header_as_first_row
|
bool
|
If True, the first row of the CSV file is treated as the header. |
False
|
state_columns
|
int | str | list[int] | list[str]
|
For training, either one of the following for CSV columns representing
state variables |
1
|
control_input_columns
|
int | str | list[int] | list[str]
|
For training, either one of the following for CSV columns representing
control inputs |
None
|
dt
|
float
|
Fixed value of dt if rows of the CSV file represent equidistant time steps. |
None
|
time_column
|
(str, int)
|
Column name (str) for column index (int) for time data |
None
|
state_derivatives_columns
|
int | str | list[int] | list[str]
|
For training, either one of the following for csv columns representing
state derivatives |
None
|
discrete_time
|
bool
|
If True, the SINDy model will be trained for discrete-time systems. In
this case, the dynamical system is treated as a map. Rather than
predicting derivatives, the right hand side functions step the system
forward by one time step. If False, dynamical system is assumed to be a
flow (right-hand side functions predict continuous time derivatives).
See documentation for |
False
|
differentiation_method
|
str
|
Method to use for differentiating the state data |
'centered difference'
|
threshold
|
float
|
Threshold for the Sequentially thresholded least squares (STLSQ) algorithm used for training SINDy model. |
0.1
|
alpha
|
float
|
Regularization strength for the STLSQ algorithm. |
0.05
|
max_iter
|
int
|
Maximum number of iterations for the STLSQ algorithm. |
20
|
normalize_columns
|
bool
|
If True, normalize the columns of the data matrix before regression. |
False
|
poly_order
|
int
|
Degree of polynomial features. Set to |
2
|
fourier_n_frequencies
|
int
|
Number of Fourier frequencies. Set to |
None
|
custom_basis_functions
|
list of functions
|
A list of custom basis functions to use for training the SINDy model.
For example to include Currently only supported for jaxonomy interface. Calls from UI and pretrained model loading does not support custom basis functions. |
None
|
pretrained
|
bool
|
If True, use a pretrained model specified by the |
False
|
pretrained_file_path
|
str
|
Path to the pretrained model file. |
None
|
initial_state
|
ndarray
|
|
None
|
discrete_time_update_interval
|
float
|
Interval at which the discrete-time model should be updated. Default is 1.0. |
1.0
|
equations
|
list of strings
|
(For internal UI use only) The identified system equations. |
None
|
base_feature_names
|
list of strings
|
(For internal UI use only) Features x_i and u_i. |
None
|
feature_names
|
list of strings
|
(For internal UI use only) Composed features with basis libraries. |
None
|
coefficients
|
ndarray
|
(For internal UI use only) Coefficients of the identified model. |
None
|
has_control_input
|
bool
|
(For internal UI use only) If True, the model was trained with control.
For standard training from CSV file, this is inferred from the
parameter |
True
|
Source code in jaxonomy/library/sindy.py
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | |
serialize(filename)
Save the relevant class attributes post training so that model state can be restored
Source code in jaxonomy/library/sindy.py
636 637 638 639 640 641 642 643 644 645 646 647 648 649 | |
serialize_trained_pysindy_model(model, filename)
staticmethod
Serialize a PySindy model trained outside of Jaxonomy. The saved file can be used as a pretrained model in Jaxonomy.
Source code in jaxonomy/library/sindy.py
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | |
Sine
Bases: SourceBlock
Generates a sinusoidal signal.
Given amplitude a, frequency f, phase phi, and bias b, the output signal is:
y(t) = a * sin(f * t + phi) + b
Input ports
None
Output ports
(0) The sinusoidal signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amplitude
|
The amplitude of the sinusoidal signal. |
1.0
|
|
frequency
|
The frequency of the sinusoidal signal. |
1.0
|
|
phase
|
The phase of the sinusoidal signal. |
0.0
|
|
bias
|
The bias of the sinusoidal signal. |
0.0
|
|
units
|
(optional, T - 104 - followup - units - on - source - blocks)
|
If set, the output port advertises this :class: |
None
|
Source code in jaxonomy/library/sources.py
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | |
Slice
Bases: FeedthroughBlock
Slice the input signal using Python indexing rules.
Input ports
(0) The input signal.
Output ports
(0) The sliced output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
slice_
|
The slice operator to apply to the input signal. Must be specified as a
string input, e.g. the output |
required |
Notes
Currently only up to 3-dimensional slices are supported.
Source code in jaxonomy/library/routing.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
SnapshotData
dataclass
Container for a column-wise snapshot matrix.
Attributes:
| Name | Type | Description |
|---|---|---|
X |
ndarray
|
State/output snapshots, shape |
time |
Optional[ndarray]
|
Optional sample times, shape |
inputs |
Optional[ndarray]
|
Optional input snapshots |
Xdot |
Optional[ndarray]
|
Optional time-derivative snapshots, shape |
Source code in jaxonomy/library/rom/snapshots.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
SoftRateLimiter
Bases: LeafSystem
Smooth (differentiable) rate limiter.
Drop-in differentiable variant of :class:RateLimiter. Identical
discrete update semantics, except the inner hard clip on the
desired step (u - y_prev) is replaced by a smooth saturation so
gradients flow through the limiter even when it is actively limiting.
The smooth clip is implemented via :func:soft_saturate and recovers
the hard rate limiter as sharpness -> inf.
Parameters mirror :class:RateLimiter plus:
sharpness:
Scalar > 0 controlling how sharply the smooth saturation
transitions at the rate limits. Larger sharpness -> closer
to the hard rate limiter. Default 10.0.
See :class:RateLimiter for the (non-smoothed) reference behavior.
Source code in jaxonomy/library/nonlinearities.py
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | |
SoftSaturate
Bases: FeedthroughBlock
Smooth (differentiable) saturation block.
Drop-in differentiable variant of :class:Saturate that uses
:func:soft_saturate instead of npa.clip. The original hard
:class:Saturate block is unchanged.
Why a separate block: the standard :class:Saturate block returns
npa.clip(u, lo, hi), whose gradient is exactly zero outside the
bounds. That kills gradient signal in any optimization that drives
the input past the limits. SoftSaturate keeps gradient flow alive
so e.g. trajectory optimization through actuator limits actually
converges.
See :func:soft_saturate for the formula. Unlike :class:Saturate,
this block does not declare zero-crossing events (it has no
discontinuity to catch).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
upper_limit
|
Upper limit; default |
1.0
|
|
lower_limit
|
Lower limit; default |
0.0
|
|
sharpness
|
Smoothing knob, > 0; default |
10.0
|
Input ports
(0) The input signal.
Output ports
(0) The smoothly-saturated output signal.
Source code in jaxonomy/library/nonlinearities.py
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 | |
SourceBlock
Bases: LeafSystem
Simple blocks with a single time-dependent output
Source code in jaxonomy/library/generic.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |
__init__(func, **kwargs)
Create a source block with a time-dependent output.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
A function of time and parameters that returns a single value.
Signature should be |
required |
Source code in jaxonomy/library/generic.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
SquareRoot
Bases: FeedthroughBlock
Compute the square root of the input signal.
Dispatches to jax.numpy.sqrt, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.sqrt.html
Input ports
(0) The input signal.
Output ports
(0) The square root of the input signal.
Source code in jaxonomy/library/math_ops.py
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | |
Stack
Bases: ReduceBlock
Stack the input signals into a single output signal along a new axis.
Dispatches to jax.numpy.stack, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.stack.html
Input ports
(0..n_in-1) The input signals.
Output ports
(0) The stacked output signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
The axis along which the input signals are stacked. Default is 0. |
0
|
Source code in jaxonomy/library/math_ops.py
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | |
StateMachine
Bases: LeafSystem
Finite State Machine similar to Mealy Machine. https://en.wikipedia.org/wiki/Mealy_machine
The state machine can be executed either periodically or by zero_crossings.
Each state as 0 or more exit transitions. These are prioritized such that when 2 exits are simultaneously valid, the higher priority is executed. It is not allowed for a state to have more than one exit transition with no guard. Guardless exits only make sense in the periodic case.
Each transitions may have 0 or more actions. Each action is a python statement that modifies the value of an output. When a transitions is executed (i.e. it's guard evaluates to true), its actions are then processed.
If 'time' is needed for guards or actions, pass 'time' in from clock block.
Whether executed periodically or by zero_crossings, the states are constant between transitions executions. In the zero_crossing case, all guards for transitions exiting the current state are continuously checked, and if any 'triggers', then the earlist point in time that any guard becomes true is determined, the actions of the earliest (and highest priority if multiple trigger simultaneously) guard are executed at that time, and the simulation continues afterwards.
Input ports
User specified.
Output ports
User specified.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Either Float or None. When not None, state machine is executed periodically. When None, the transitions are monitored by zero_crossing events. |
None
|
|
accelerate_with_jax
|
bool
|
Bool. When True, the actions and guards are JIT-compiled with JAX. Default is False. |
False
|
Source code in jaxonomy/library/state_machine.py
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 | |
Step
Bases: SourceBlock
A step signal.
Given start value y0, end value y1, and step time t0, the
output signal is:
y(t) = y0 if t < t0 else y1
Input ports
None
Output ports
(0) The step signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_value
|
The value of the output signal before the step time. |
0.0
|
|
end_value
|
The value of the output signal after the step time. |
1.0
|
|
step_time
|
The time at which the step occurs. |
1.0
|
|
units
|
(optional, T - 104 - followup - units - on - source - blocks)
|
If set, the output port advertises this :class: |
None
|
Source code in jaxonomy/library/sources.py
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | |
Stop
Bases: LeafSystem
Stop the simulation early as soon as the input signal becomes True.
If the input signal changes as a result of a discrete update, the simulation will terminate the major step early (before advancing continuous time).
Input ports
(0): the boolean- or binary-valued termination signal
Output ports
None
Source code in jaxonomy/library/nonlinearities.py
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | |
SumOfElements
Bases: FeedthroughBlock
Compute the sum of the elements of the input signal.
Dispatches to jax.numpy.sum, so see the JAX docs for details:
https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.sum.html
Input ports
(0) The input signal.
Output ports
(0) The sum of the elements of the input signal.
Source code in jaxonomy/library/math_ops.py
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 | |
Switch
Bases: LeafSystem
Route one of two data signals based on a thresholded control signal.
Three inputs (data_a, control, data_b) and one output:
.. code-block:: python
y = data_a if criteria(control, threshold) else data_b
Default mode="where" is implemented via npa.where, so JAX
gradients flow through both data branches simultaneously (the
selector branch is treated as non-differentiable, which is the
only well-defined choice for a hard threshold).
mode="smooth" replaces the hard where with a sigmoid blend
.. code-block:: python
alpha = sigmoid(sharpness * sign * (control - threshold))
y = alpha * data_a + (1 - alpha) * data_b
where sign is +1 for the >=/> criteria and -1 for the
<=/< criteria, so the smooth output approaches the hard
answer in the strict-active region as sharpness -> inf. This
mode lets gradients flow through the threshold itself, which the
hard where zeroes out — the killer feature for trajectory
optimization where the threshold is a tunable parameter.
data_a and data_b must be broadcast-compatible (same as
npa.where's requirements). The block does not enforce that
control is a scalar — element-wise selection is supported when
control and the data inputs broadcast together.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold
|
scalar threshold against which |
0.0
|
|
criteria
|
one of |
'>='
|
|
mode
|
one of |
'where'
|
|
sharpness
|
positive scalar controlling sigmoid steepness in
|
10.0
|
Input ports
(0) data_a — output when criteria(control, threshold) is True.
(1) control — the selector signal compared to threshold.
(2) data_b — output when criteria(control, threshold) is False.
Output ports
(0) The selected data signal, with shape determined by broadcasting between data_a and data_b.
Source code in jaxonomy/library/logic.py
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 | |
TableSearch
Bases: LeafSystem
Search a monotonic table for the bucket containing a query value.
Given a strictly-increasing 1-D grid xp of length n and a
scalar query x, returns the bucket index i (as a float) such
that xp[i] <= x < xp[i+1]. Out-of-range queries clamp to the
nearest endpoint: x < xp[0] returns 0; x >= xp[-1]
returns n - 1.
The standard "Direct Lookup" pattern. Different from
:class:Prelookup in that the output is just the bucket index --
no fractional alpha is computed. Useful for binning,
threshold detection, and inverse-table indexing.
Input ports
(0) -- scalar query coordinate x.
Output ports
(0) -- scalar bucket index, returned as a float (so it
composes with the float-defaulting numeric pipeline). The
output is wrapped in jax.lax.stop_gradient -- gradient is
zero almost everywhere by construction (step function), so we
make that non-differentiability explicit to avoid spurious
grad-flow surprises.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xp
|
1-D, strictly-monotonically-increasing grid of breakpoints (length >= 2). Stored verbatim for the bucket search. |
required | |
mode
|
|
'binary'
|
|
dtype
|
optional
|
If set (e.g. |
None
|
Notes
Index is wrapped in jax.lax.stop_gradient -- the gradient
through the query coordinate is zero, by construction. Callers
who need a differentiable index-like quantity should use
:class:Prelookup (which exposes the fractional alpha) or
:class:LookupTable1d directly.
Source code in jaxonomy/library/tables.py
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | |
mode
property
Search mode ("binary" or "linear").
xp
property
The 1-D strictly-increasing breakpoint array.
TensorFlow
Bases: LeafSystem
Block to perform inference with a pre-trained TensorFlow SavedModel.
The input to the block should be of compatible type and shape expected by
the TensorFlow model. For example, if the TensorFlow SavedModel model expects a
tf.float32 tensor of shape (3, 224, 224), the input to the block should be a
jax.numpy array of shape (3, 224, 224) of dtype jnp.float32.
For output types, if no casting is specified through the cast_outputs_to_dtype
parameter, the output of the block will have the same dtype as the
TensorFlow model output, but expressed as jax.numpy types. For example. if the
TensorFlow model outputs a tf.float32 tensor, the output of the block will be
a jax.numpy array of dtype jnp.float32.
If casting is specified through cast_outputs_to_dtype parameter, all the outputs,
of the block will be casted to this specific jax.numpy dtype.
.. note:: float32 models under jaxonomy's global x64.
import jaxonomy enables JAX 64-bit mode (jax_enable_x64)
for the whole process, so upstream signals are float64 by
default. A SavedModel with tf.float32 signatures therefore
receives float64 inputs (a dtype error or a silent arithmetic
change) unless you cast at the block boundary. One-line idiom:
pass cast_outputs_to_dtype="float32" and feed the block
x.astype(jnp.float32) inputs.
Input ports
(i) The ith input to the model.
Output ports
(j) The jth output of the model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Path to the model file. This should be a |
required |
cast_outputs_to_dtype
|
str
|
The dtype to cast all the outputs of the block to. Must correspond to a
|
None
|
add_batch_dim_to_inputs
|
bool
|
Whether to add a new first dimension to the inputs before evaluating the TorchScript or TensorFlow model. This is useful when the model expects a batch dimension. |
False
|
Source code in jaxonomy/library/predictor.py
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | |
initialize_static_data(context)
Infer the output shapes and dtypes of the ML model.
Source code in jaxonomy/library/predictor.py
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | |
TransferFunction
Bases: LTISystem
Continuous-time LTI system specified as a transfer function.
The transfer function is converted to state-space form using scipy.signal.tf2ss.
https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.tf2ss.html
The resulting system will be in canonical controller form with matrices (A, B, C, D), which are then used to create an LTISystem. Note that this only supports single-input, single-output systems.
Input ports
(0) u: Input vector (scalar)
Output ports
(0) y: Output vector (scalar). Note that this is feedthrough from the input port iff D is nonzero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num
|
Numerator polynomial coefficients, in descending powers of s |
required | |
den
|
Denominator polynomial coefficients, in descending powers of s |
required |
Source code in jaxonomy/library/linear_system.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
TransferFunctionDiscrete
Bases: LTISystemDiscrete
Implements a Discrete Time Transfer Function.
https://en.wikipedia.org/wiki/Z-transform#Transfer_function
The resulting system will be in canonical controller form with matrices (A, B, C, D), which are then used to create an LTISystem. Note that this only supports single-input, single-output systems.
Input ports
(0) u[k]: Input vector (scalar)
Output ports
(0) y[k]: Output vector (scalar). Note that this is feedthrough from the input port if and only if D is nonzero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Sampling period of the discrete system. |
required | |
num
|
Numerator polynomial coefficients, in descending powers of z |
required | |
den
|
Denominator polynomial coefficients, in descending powers of z |
required | |
initialize_states
|
Initial state vector (default: 0) |
None
|
Source code in jaxonomy/library/linear_system.py
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | |
TransportDelay
Bases: LeafSystem
Continuous-time fixed transport (pure) delay.
Implements y(t) = u(t - delay_seconds) for t >= delay_seconds;
for t < delay_seconds the output is initial_output (the
standard "Initial output" semantics).
The block samples its input on a periodic clock with period dt and
stores the most recent history_length (time, value) pairs in a
discrete-state ring buffer. Output evaluation at any continuous time
t is a linear interpolation over the buffered (time, value)
samples at t - delay_seconds.
The delay is differentiable via the input signal (gradient flows
through npa.interp over the values buffer). Differentiability
w.r.t. the delay value itself is well-defined wherever the buffer
interpolant is differentiable; the linear interpolant has a kink at
sample boundaries — pass method="pchip" on
:class:VariableTransportDelay for a C¹-smooth alternative.
The buffer is sized statically as history_length samples. To cover
a delay of delay_seconds at sample period dt, you need at
least ceil(delay_seconds / dt) + 1 slots; we recommend a small
safety margin. history_length defaults to
max(8, ceil(delay_seconds / dt) + 4) which is sufficient for the
default constant delay.
Input ports
(0) The input signal u(t). Scalar or array.
Output ports
(0) The delayed signal y(t) = u(t - delay_seconds) (or
initial_output while t < delay_seconds).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Sampling period for the history buffer. Smaller |
required | |
delay_seconds
|
Fixed delay τ in seconds. Dynamic parameter (may
be tuned via |
required | |
initial_output
|
Output value while |
0.0
|
|
history_length
|
Number of |
None
|
Notes
- For arbitrary array-shaped signals the interpolation is applied
elementwise via
jax.vmapover the trailing axes. - Buffer overflow (delay larger than
history_length * dt) is not raised;npa.interpclamps to the boundary, which means the oldest stored sample is repeated. This is a documented T-107 follow-up; for now, sizehistory_lengthgenerously. VariableTransportDelay(signal-driven τ) is the natural phase-2 extension; it reuses the same ring-buffer machinery with the delay sourced from an input port.
Source code in jaxonomy/library/dynamics.py
1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 | |
TriggerEdge
Allowed string values for TriggeredSubsystem.edge.
Source code in jaxonomy/framework/containers.py
139 140 141 142 143 144 145 146 147 148 | |
TriggeredSubsystem
Bases: LeafSystem
Container block: latch the submodel output on edge transitions (the child still RUNS every step — only the output is gated).
Important: this does not skip execution of the submodel on
non-triggered steps. The submodel is evaluated on every step so its
inputs participate in the JAX trace; the trigger only controls
whether a fresh result is latched into the held output. If you
need to actually skip computation between triggers, gate it yourself
with jax.lax.cond at the application level.
Phase-1 implementation runs the submodel on every step (so the inputs participate in the trace) but only latches a new output on an edge transition of the trigger signal. Between transitions the output holds the most recently latched value.
The trigger signal is sampled at sample_period. Edges are
detected by comparing the current trigger sample against the
previously-stored sample held in discrete state.
This is not the eventual zero-crossing-driven TriggeredSubsystem
described in the T-120 architecture notes (that requires hooking
into the continuous-time event detector); but it is functionally
correct for any sample-rate use case and matches the behaviour
documented in the test fixtures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submodel
|
Callable
|
Callable |
required |
n_inputs
|
int
|
Number of user inputs (NOT counting the trigger). |
1
|
edge
|
Literal['rising', 'falling', 'either']
|
|
RISING
|
sample_period
|
float
|
Period (seconds) at which the trigger signal is sampled and the latch is updated. Must be positive. |
0.0
|
initial_value
|
Latched output value before any edge has been detected. Defines output shape/dtype. |
0.0
|
|
name
|
Optional block name. |
required |
Limitations (phase 1):
- Trigger detection runs on the periodic sample grid, not on
continuous-time zero crossings. Trigger pulses shorter than
sample_period may be missed.
- The latch is a single discrete state; the submodel must
produce a single output array.
- The submodel runs on every output evaluation; only the
output is gated. Users who need to skip computation on
non-triggered steps should use jax.lax.cond at the
application level.
Source code in jaxonomy/framework/containers.py
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | |
Trigonometric
Bases: FeedthroughBlock
Apply a trigonometric function to the input signal.
Available functions are
sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh
Dispatches to jax.numpy.sin, jax.numpy.cos, etc, so see the JAX docs for details.
Input ports
(0) The input signal.
Output ports
(0) The trigonometric function applied to the input signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
function
|
The trigonometric function to apply to the input signal. Must be one of "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "asinh", "acosh", "atanh". |
required |
Source code in jaxonomy/library/math_ops.py
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 | |
TruthTable
Bases: LeafSystem
Evaluate a fixed truth table over boolean-castable inputs.
Given a list of (input_pattern, output) rows, this block compares
its inputs against each pattern and emits the output of the first
matching row (or default_output if none match). Patterns are tuples
of bool values or the string "X" as a wildcard.
Example — a 2-input AND gate:
.. code-block:: python
tt = TruthTable(
rows=[
((True, True), 1.0),
((True, False), 0.0),
((False, True), 0.0),
((False, False), 0.0),
],
n_inputs=2,
default_output=0.0,
)
Wildcard example — ignore the first input:
.. code-block:: python
tt = TruthTable(
rows=[(("X", True), 1.0), (("X", False), 0.0)],
n_inputs=2,
default_output=0.0,
)
Callable output example — row output depends on raw input values (T-119-followup-numeric-output):
.. code-block:: python
tt = TruthTable(
rows=[
((True, True), lambda a, b: a + b),
((True, False), lambda a, b: a - b),
((False, "X"), 0.0), # constant fallback row
],
n_inputs=2,
default_output=0.0,
)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
list of |
required | |
n_inputs
|
number of input ports. |
required | |
default_output
|
value emitted when no row matches. May be a
scalar/array (constant fallback) or a callable
|
required |
Input ports
(0..n_inputs-1) Boolean-castable scalars. Non-boolean inputs are coerced to bool before pattern matching (any non-zero is True).
Output ports
(0) The output of the first matching row, or default_output.
Notes
Earlier rows take precedence: if multiple patterns would match
the same input combination, the one listed first in rows wins.
The static-completeness/ambiguity checker is deferred
(see T-119-followup-completeness-checker); JSON serialization
of the rows table is deferred (see
T-119-followup-serialization).
Source code in jaxonomy/library/logic.py
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 | |
builder(n_inputs, default_output, input_names=None, **block_kwargs)
classmethod
Construct a fluent builder for this truth table.
See :class:TruthTableBuilder for usage. Equivalent to
TruthTableBuilder(n_inputs, default_output, input_names, **block_kwargs).
Source code in jaxonomy/library/logic.py
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 | |
from_csv(path, **block_kwargs)
classmethod
Load a TruthTable from a CSV file.
The CSV must have a header row whose last column(s) are named
output (single scalar output) or any sequence of columns
whose names start with output (e.g. output_x, output_y)
which are stacked into a 1-D vector output per row. All columns
preceding the first output* column are treated as input
columns, in order.
Input cells accept T/True/1 (True), F/False/
0 (False), and X/-/* or an empty cell
(wildcard). Matching is case-insensitive and whitespace is
stripped. Output cells must parse as float.
Example CSV::
in1,in2,in3,output
T,T,T,1.0
T,T,F,0.5
T,F,X,0.25
F,X,X,0.0
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
filesystem path ( |
required | |
**block_kwargs
|
forwarded to |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
if the file is empty, has no header, has no
|
Source code in jaxonomy/library/logic.py
1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 | |
from_dict(data, **block_kwargs)
classmethod
Reconstruct a TruthTable from the dict produced by :meth:to_dict.
Extra keyword arguments (name=, system_id=, ...) are
forwarded to the underlying TruthTable constructor, so a
deserialized block can pick up a fresh name in its target diagram.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict with the keys documented on :meth: |
required | |
**block_kwargs
|
forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
|
A new :class: |
|
|
|
Source code in jaxonomy/library/logic.py
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 | |
to_csv(path, **csv_kwargs)
Write this TruthTable to a CSV file (inverse of from_csv).
Emits a header row of in1,in2,...,output (single-output) or
in1,...,output_0,output_1,... (vector output), followed by
one data row per rows entry. Input cells are written as
T / F / X; output cells are written as
float(...).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
filesystem path ( |
required | |
**csv_kwargs
|
forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
|
|
|
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if any row's output is a callable
(T-119-followup-numeric-output) or |
Source code in jaxonomy/library/logic.py
1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 | |
to_dict()
Return a JSON-serializable dict describing this TruthTable.
The dict round-trips through :meth:from_dict to a TruthTable
with identical behaviour for every input combination. Pattern
wildcards ("X") and vector outputs are preserved.
Returns:
| Type | Description |
|---|---|
|
dict with keys: |
|
|
|
|
|
|
Source code in jaxonomy/library/logic.py
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 | |
validate(strict_completeness=False, strict_disjointness=False)
Static analysis of the truth-table rows.
Enumerates all 2**n_inputs boolean input vectors and checks:
- Completeness — each vector is matched by at least one row's
pattern (with
"X"as wildcard). Vectors that no row matches are reported asmissing_patterns; without coverage they silently hitdefault_outputat runtime. - Disjointness — no two rows match the same input vector.
Overlaps are reported as
(earlier_idx, later_idx)pairs. Jaxonomy's runtime resolves overlaps by earlier-row-wins, so this is informational unlessstrict_disjointness=True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strict_completeness
|
if True, raise :class: |
False
|
|
strict_disjointness
|
if True, raise :class: |
False
|
Returns:
| Type | Description |
|---|---|
|
dict with keys: |
|
|
|
|
|
|
|
|
Notes
For n_inputs > 10 (i.e. > 1024 enumerated combinations)
the check emits a :class:UserWarning since cost grows as
2 ** n_inputs * len(rows).
Source code in jaxonomy/library/logic.py
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 | |
TruthTableBuilder
Fluent builder for :class:TruthTable rows by named-input keywords.
Example — a 2-input AND gate:
.. code-block:: python
tt = (
TruthTable.builder(n_inputs=2, default_output=0.0)
.row(in1=True, in2=True, output=1.0)
.row(in1=True, in2=False, output=0.0)
.row(in1=False, in2="X", output=0.0)
.build()
)
Inputs omitted from a .row(...) call default to the wildcard
"X", so partial decision tables are concise. Custom input names
may be supplied via the input_names= constructor argument; the
default names are in1, in2, ..., inN.
Source code in jaxonomy/library/logic.py
1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 | |
build()
Materialize the accumulated rows into a :class:TruthTable.
Source code in jaxonomy/library/logic.py
2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 | |
row(output, **input_assignments)
Append a row, named by input keyword.
output is the value emitted when the row matches. Each
keyword in input_assignments must be one of the configured
input names; omitted inputs default to the wildcard "X".
Returns self for fluent chaining.
Source code in jaxonomy/library/logic.py
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 | |
UniformRandomNumber
Bases: LeafSystem
Discrete-time uniform random number generator.
Emits a fresh Uniform[low, high] sample every sample_time
seconds, using jax.random.uniform with a key carried in the
block's discrete state. Reproducible: same seed and same
diagram → bit-identical sequence.
The sample is computed as low + (high - low) * u where
u ~ Uniform[0, 1), so gradients of downstream losses flow
cleanly through low and high via the reparameterization
trick. The u draw is wrapped in lax.stop_gradient so JAX
never tries to differentiate the random sequence w.r.t. the key.
Input ports
None.
Output ports
(0) The most recent uniform sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sample_time
|
float
|
Period (s) at which a fresh sample is drawn. |
required |
low
|
float
|
Lower bound of the uniform interval (differentiable). |
0.0
|
high
|
float
|
Upper bound of the uniform interval (differentiable). |
1.0
|
seed
|
int
|
Integer seed for the PRNG key. If |
None
|
shape
|
Output shape. Default |
()
|
Notes
Per-vmap-batch independence: pass fold_in_batch_index=True
(T-122-followup-vmap-fold-in) to derive a per-replica
independent PRNG stream via jax.lax.axis_index("batch")
inside simulate_batch(use_vmap=True) / simulate_distributed.
Outside any vmap context the kwarg is a no-op (the unbound-axis
NameError is caught gracefully and the plain seed-derived
key is used). The default False preserves bit-identical
behaviour with T-122 phase 1.
Source code in jaxonomy/library/sources.py
691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 | |
UnitDelay
Bases: LeafSystem
Hold and delay the input signal by one time step.
This block implements a "unit delay" with the following difference equation
for internal state x, input signal u, and output signal y:
x[k+1] = u[k]
y[k] = x[k]
Or, in a hybrid context, the discrete update advances the internal state from
the "pre" or "minus" value x⁻ to the "post" or "plus" value x⁺ at time
tₖ = t0 + k * dt. According to the discrete update rules, this calculation
happens using the input values computed during the update step (i.e. by computing
upstream outputs before evaluating the inputs to this block). That is, the update
rule can be written x⁺(tₖ) = f(tₖ, x⁻(tₖ), u(tₖ)). The values of u are not
distinguished as "pre" or "post" because there is only one value at the update
time. In the difference equation notation, x⁺(tₖ) ≡ x[k+1],x⁻(tₖ) ≡ x[k],
and u(tₖ) ≡ u[k]. The hybrid update rule is then:
x⁺(tₖ) = u(tₖ)
y(t) = x⁻(tₖ), between tₖ⁺ and (tₖ+dt)⁻
The output signal "seen" by all other blocks on the time interval (tₖ, tₖ+dt) is then the value of the input signal u(tₖ) at the previous update. Therefore, all downstream discrete-time blocks updating at the same time tₖ will still see the value of x⁻(tₖ), the value of the internal state prior to the update.
Input ports
(0) The input signal.
Output ports
(0) The input signal delayed by one time step
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
The time step of the discrete update. |
required | |
initial_state
|
The initial state of the block. Default is 0.0. |
required |
Note
For a multi-step / fixed transport latency, do not chain N
UnitDelay blocks — use a single :class:TransportDelay
(delay_seconds = N * dt), which buffers the history in one block
and is differentiable through the signal. UnitDelay is the exact
one-sample z⁻¹ primitive; :class:TransportDelay is the
parameterized N-sample delay line.
Source code in jaxonomy/library/dynamics.py
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 | |
UnscentedKalmanFilter
Bases: KalmanFilterBase
Unscented Kalman Filter (UKF) for the following system:
```
x[n+1] = f(x[n], u[n]) + G(t[n]) w[n]
y[n] = g(x[n], u[n]) + v[n]
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Q(t[n], x[n], u[n])
E(v[n]v'[n] = R(t[n])
E(w[n]v'[n] = N(t[n]) = 0
```
f and g are discrete-time functions of state x[n] and control u[n],
while RandGare discrete-time functions of timet[n].Qis a discrete-time
function oft[n], x[n], u[n]`. This last aspect is included for zero-order-hold
discretization of a continuous-time system
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Time step of the discrete-time system |
required | |
forward
|
Callable
A function with signature f(x[n], u[n]) -> x[n+1] that represents |
required | |
observation
|
Callable
A function with signature g(x[n], u[n]) -> y[n] that represents |
required | |
G_func
|
Callable
A function with signature G(t[n]) -> G[n] that represents |
required | |
Q_func
|
Callable
A function with signature Q(t[n], x[n], u[n]) -> Q[n] that represents |
required | |
R_func
|
Callable
A function with signature R(t[n]) -> R[n] that represents |
required | |
x_hat_0
|
ndarray Initial state estimate |
required | |
P_hat_0
|
ndarray Initial state covariance matrix estimate |
required | |
alpha
|
float Sigma point spread to control the amount of nonlinearities taken into account. Usually set to a value (1e-04<= alpha <= 1.0). Default is 1.0. |
1.0
|
|
beta
|
float Scaling constant to include prior information about the distribution of the state. Default is 0.0. |
0.0
|
|
kappa
|
float Relatively non-critical parameter to control the kurtosis of sigma point distribution. Default is 0.0. |
0.0
|
Source code in jaxonomy/library/state_estimators/unscented_kalman_filter.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | |
for_continuous_plant(plant, dt, G_func, Q_func, R_func, x_hat_0, P_hat_0, discretization_method='euler', discretized_noise=False, alpha=1.0, beta=0.0, kappa=0.0, name=None, ui_id=None)
staticmethod
Unscented Kalman Filter system for a continuous-time plant.
The input plant contains the deterministic forms of the forward and observation operators:
dx/dt = f(x,u)
y = g(x,u)
Note: (i) Only plants with one vector-valued input and one vector-valued output are currently supported. Furthermore, the plant LeafSystem/Diagram should have only one vector-valued integrator; (ii) the user may pass a plant with disturbances (not recommended) as the input plant. In this case, the forward and observation evaluations will be corrupted by noise.
A plant with disturbances of the following form is then considered:
dx/dt = f(x,u) + G(t) w -- (C1)
y = g(x,u) + v -- (C2)
where:
`w` represents the process noise,
`v` represents the measurement noise,
and
E(w) = E(v) = 0
E(ww') = Q(t)
E(vv') = R(t)
E(wv') = N(t) = 0
This plant is discretized to obtain the following form:
x[n+1] = fd(x[n], u[n]) + Gd w[n] -- (D1)
y[n] = gd(x[n], u[n]) + v[n] -- (D2)
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Qd
E(v[n]v'[n] = Rd
E(w[n]v'[n] = Nd = 0
The above discretization is performed either via the euler or the zoh
method, and an Unscented Kalman Filter estimator for the system of equations
(D1) and (D2) is returned.
Note: If discretized_noise is True, then it is assumed that the user is
directly providing Gd, Qd and Rd. If False, then Qd and Rd are computed from
continuous-time Q, R, and G, and Gd is set to an Identity matrix.
The returned system will have:
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
a |
required | |
dt
|
float Time step for the discretization. |
required | |
G_func
|
Callable
A function with signature G(t) -> G that represents |
required | |
Q_func
|
Callable
A function with signature Q(t) -> Q that represents |
required | |
R_func
|
Callable
A function with signature R(t) -> R that represents |
required | |
x_hat_0
|
ndarray Initial state estimate |
required | |
P_hat_0
|
ndarray
Initial state covariance matrix estimate. If |
required | |
discretization_method
|
str ("euler" or "zoh") Method to discretize the continuous-time plant. Default is "euler". |
'euler'
|
|
discretized_noise
|
bool
Whether the user is directly providing Gd, Qd and Rd. Default is False.
If True, |
False
|
|
alpha
|
float Sigma point spread to control the amount of nonlinearities taken into account. Usually set to a value (1e-04<= alpha <= 1.0). Default is 1.0. |
1.0
|
|
beta
|
float Scaling constant to include prior information about the distribution of the state. Default is 0.0. |
0.0
|
|
kappa
|
float Relatively non-critical parameter to control the kurtosis of sigma point distribution. Default is 0.0. |
0.0
|
Source code in jaxonomy/library/state_estimators/unscented_kalman_filter.py
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | |
from_operators(dt, forward, observation, G_func, Q_func, R_func, x_hat_0, P_hat_0, alpha=1.0, beta=0.0, kappa=0.0, name=None, ui_id=None)
staticmethod
Unscented Kalman Filter (UKF) for the following system:
x[n+1] = f(x[n], u[n]) + G(t[n]) w[n]
y[n] = g(x[n], u[n]) + v[n]
E(w[n]) = E(v[n]) = 0
E(w[n]w'[n]) = Q(t[n], x[n], u[n])
E(v[n]v'[n] = R(t[n])
E(w[n]v'[n] = N(t[n]) = 0
f and g are discrete-time functions of state x[n] and control u[n],
while Q and R and G are discrete-time functions of time t[n].
Input ports
(0) u[n] : control vector at timestep n (1) y[n] : measurement vector at timestep n
Output ports
(1) x_hat[n] : state vector estimate at timestep n
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float Time step of the discrete-time system |
required | |
forward
|
Callable
A function with signature f(x[n], u[n]) -> x[n+1] that represents |
required | |
observation
|
Callable
A function with signature g(x[n], u[n]) -> y[n] that represents |
required | |
G_func
|
Callable
A function with signature G(t[n]) -> G[n] that represents |
required | |
Q_func
|
Callable
A function with signature Q(t[n]) -> Q[n] that represents
|
required | |
R_func
|
Callable
A function with signature R(t[n]) -> R[n] that represents |
required | |
x_hat_0
|
ndarray Initial state estimate |
required | |
P_hat_0
|
ndarray Initial state covariance matrix estimate |
required | |
alpha
|
float Sigma point spread to control the amount of nonlinearities taken into account. Usually set to a value (1e-04<= alpha <= 1.0). Default is 1.0. |
1.0
|
|
beta
|
float Scaling constant to include prior information about the distribution of the state. Default is 0.0. |
0.0
|
|
kappa
|
float Relatively non-critical parameter to control the kurtosis of sigma point distribution. Default is 0.0. |
0.0
|
Source code in jaxonomy/library/state_estimators/unscented_kalman_filter.py
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | |
VariableTransportDelay
Bases: LeafSystem
Continuous-time variable transport (pure) delay.
Implements y(t) = u(t - tau(t)) where the delay tau is supplied
as a runtime input signal (second input port) rather than as a static
parameter. This is the T-107-followup-variable-tau extension to the
fixed-delay :class:TransportDelay block (T-107 phase 1).
Mechanism: identical to :class:TransportDelay — a periodic clock at
period dt writes the most recent history_length (time, u)
pairs into a discrete-state ring buffer, and the (continuous-time)
output port performs a linear interpolation over the buffer at
t - clip(tau, 0, max_delay_seconds). The clip guards the
interpolation against transient out-of-range delay values from
upstream blocks; out-of-band tau is clamped (not raised) so that
the block remains differentiable everywhere.
Differentiability:
- w.r.t. the data input
u: vianpa.interpovervalues, same as :class:TransportDelay. - w.r.t. the delay input
tau: undermethod="linear"(default, phase 3) vianpa.interp's gradient w.r.t. its query coordinate — the standard linear-interp Jacobian, well defined except at sample boundaries where the gradient has a jump discontinuity. Passmethod="pchip"(T-107 phase 4) to route through the T-106 backend's monotone cubic Hermite interpolant instead: smooth (C^1) gradient w.r.t. tau across every sample boundary, at the cost of one extra slope-array compute per output evaluation.
The buffer is sized statically from max_delay_seconds: at sample
period dt you need at least ceil(max_delay_seconds / dt) + 1
slots; history_length defaults to
max(8, ceil(max_delay_seconds / dt) + 4).
Input ports
(0) The input signal u(t). Scalar or array.
(1) The delay signal tau(t) in seconds. Runtime scalar in
[0, max_delay_seconds]; values outside that range are
silently clamped.
Output ports
(0) The delayed signal y(t) = u(t - tau(t)) (or
initial_output while t < tau(t)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
Sampling period for the history buffer. Smaller |
required | |
max_delay_seconds
|
Upper bound on the runtime delay value. Used
to size the ring buffer and to clip out-of-range |
required | |
initial_output
|
Output value while |
0.0
|
|
history_length
|
Number of |
None
|
Notes
- Default-off / non-touched-block path is byte-equivalent: the
existing :class:
TransportDelayis untouched. - Buffer overflow (
tau > max_delay_seconds) is clamped tomax_delay_secondsrather than raised; this keeps the block differentiable but means the user is responsible for choosing a sufficiently largemax_delay_seconds. - The variable-tau interpolation runs once per output evaluation
(continuous-time semantics). For workloads where the delay
changes only at major-step granularity, sampling
tauat the periodic update would be cheaper — deferred until profiling demands it. - For arbitrary array-shaped data signals the interpolation is
applied elementwise via a static loop over the trailing axes
(mirrors :class:
TransportDelay).
Source code in jaxonomy/library/dynamics.py
4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 | |
VideoSink
Bases: LeafSystem
Records RGB frames to a video file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
float
|
Interval at which to record frames. |
required |
file_name
|
str
|
Name of the video file to write to (optional). |
required |
Source code in jaxonomy/library/video.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | |
VideoSource
Bases: LeafSystem
Reads frames from a video file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_name
|
str
|
Name of the video file to read from. |
required |
no_repeat
|
Whether to stop at the end of the video or loop back to the beginning. |
False
|
Source code in jaxonomy/library/video.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
WhenDisabled
Allowed string values for the when_disabled kwarg.
Source code in jaxonomy/library/conditional.py
65 66 67 68 69 70 71 72 73 74 | |
WhiteNoise
Bases: LeafSystem
Continuous-time white noise generator.
Generates a band-limited white noise signal using a sinc-interpolated random number generator. The output signal is a continuous-time signal, but the underlying random number generator is discrete-time. As a result, the signal is not truly white, but is band-limited by the sample rate. The resulting signal has the following approximate power spectral density:
S(f) = A * fs if |f| < fs else 0,
where A is the noise power and fs = 1/dt is the sample rate.
See Ch. 10.4 in Baraniuk, "Signal Processing and Modeling" for details: https://shorturl.at/floRZ
The output signal will have variance A, zero mean, and will decorrelate at
the sample rate.
Input ports
None
Output ports
(0) The band-limited white noise signal with variance noise_power, zero
mean, and correlation time dt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
correlation_time
|
The correlation time of the output signal and the inverse of the bandwidth. It is the sample frequency of the underlying random number generator. |
required | |
noise_power
|
float
|
The variance of the white noise signal. Also scales the amplitude of the power spectral density. |
1.0
|
num_samples
|
int
|
The number of samples to use for sinc interpolation. More samples will result in a more accurate approximation of the ideal power spectrum, but will also increase the computational cost. The default of 10 is sufficient for most applications. |
10
|
seed
|
int
|
An integer seed for the random number generator. If None, a random 32-bit seed will be generated. |
None
|
dtype
|
DTypeLike
|
data type of the random number. If None, defaults to float. |
None
|
shape
|
ShapeLike
|
The shape of the output signal. If empty, the output will be a scalar. |
()
|
Source code in jaxonomy/library/random.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | |
with_key(key, **kwargs)
classmethod
Construct WhiteNoise with an explicit JAX PRNGKey.
Use this when you need independent noise streams in batched (jax.vmap) simulations.
Example
keys = jax.random.split(jax.random.PRNGKey(0), 16)
Each diagram gets a different key
diagrams = [ build_diagram_with( WhiteNoise.with_key(keys[i], ...) ) for i in range(16) ]
OR with with_parameters (preferred):
diagram.with_parameters({"noise.key": keys[i]})
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
'jax.Array'
|
JAX PRNGKey array (shape (2,) for default RNG) |
required |
**kwargs
|
other constructor arguments |
{}
|
Source code in jaxonomy/library/random.py
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
ZeroOrderHold
Bases: LeafSystem
Implements a "zero-order hold" A/D conversion.
https://en.wikipedia.org/wiki/Zero-order_hold
The block implements a "zero-order hold" with the following difference equation
for input signal u and output signal y:
y[k] = u[k]
The block does not maintain an internal state, but simply holds the value of the input signal at the previous update time. As a result, the block is "feedthrough" from its inputs to outputs and cannot be used to break an algebraic loop. The data type of this hold value is inferred from upstream blocks.
Input ports
(0) The input signal.
Output ports
(0) The "hold" value of the input signal. If the input signal is continuous, then the output will be the value of the input signal at the previous update time. If the input signal is discrete and synchonous with the block, the output will be the value of the input signal at the current time (i.e. identical to the input signal).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dt
|
The time step of the discrete update. |
required |
Source code in jaxonomy/library/dynamics.py
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 | |
ForEach(submodel, n, n_inputs=1, in_axes=None, name=None)
Container block: evaluate a submodel n times in parallel.
ForEach is a block-diagram-vocabulary alias for the existing
:class:jaxonomy.library.ReplicatedFunction (T-010). It exists so
that users familiar with the ForEach block name can find it
without paying a duplication tax: the implementation
is exactly :class:ReplicatedFunction under the hood.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submodel
|
Callable
|
Callable |
required |
n
|
int
|
Number of replicas (the iteration count). |
required |
n_inputs
|
int
|
Number of input ports the block declares. |
1
|
in_axes
|
As in :func: |
None
|
|
name
|
str | None
|
Optional block name. |
None
|
Returns:
| Type | Description |
|---|---|
|
A configured :class: |
|
|
wired into a :class: |
Source code in jaxonomy/framework/containers.py
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | |
RateTransition(input_dt, output_dt, initial_state=0.0, *, name=None, dtype=None, **kwargs)
Auto-pick the right rate-bridging block based on input_dt vs output_dt.
input_dt > output_dt(slow source → fast destination): :class:ZeroOrderHoldatoutput_dt(the fast rate). The held value is whatever the upstream slow block last produced; the ZOH re-samples on every fast tick.input_dt < output_dt(fast source → slow destination): :class:Decimatoratoutput_dt(the slow rate).input_dt == output_dt(same rate): :class:UnitDelayatinput_dt— a one-step delay so adjacent same-rate blocks can still break feedthrough loops.
Both ZOH and Decimator paths are tagged with the
_jaxonomy_rate_transition marker so
:func:jaxonomy.simulation.rate_groups.detect_rate_mismatches
silences the rate-mismatch warning across the connection. The
same-rate (UnitDelay) path does not need the marker because it
cannot itself be a rate mismatch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_dt
|
Sample period of the upstream block. |
required | |
output_dt
|
Sample period of the downstream block. |
required | |
initial_state
|
Initial output value (only meaningful for the
same-rate |
0.0
|
|
name
|
Optional block name. |
None
|
|
dtype
|
Optional per-block dtype (forwarded to the underlying
block). See |
None
|
|
**kwargs
|
Forwarded to the underlying block constructor. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
class: |
Source code in jaxonomy/library/dynamics.py
2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 | |
balanced_realization(sys)
Internally-balanced realization of sys.
Returns (balanced_system, hsv) where balanced_system is an
equivalent :class:LinearizedSystem whose controllability and
observability Gramians are equal and diagonal, with the Hankel singular
values hsv on the diagonal (Moore 1981; square-root algorithm of
Laub, Heath, Paige & Ward 1987).
Requires a stable sys. A non-minimal or stiff system (Gramians only
numerically semidefinite) is handled — see :func:_psd_sqrt — but its
~zero Hankel-value states are ill-defined in the full balanced form;
use :func:balanced_truncation or :func:minimal_realization to remove
them.
Source code in jaxonomy/library/rom/linear_mor.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
balanced_truncation(sys, order=None, tol=None)
Balanced truncation (Moore 1981).
Balances sys and keeps the states associated with the largest Hankel
singular values.
Order selection:
ordergiven — keep exactly that many states.tolgiven (andorderisNone) — keep the fewest states whose retained "energy"Σσ_kept² / Σσ²is at least1 - tol; i.e.tolis the fraction of Gramian energy allowed to be discarded.- neither given — no truncation (returns the balanced realization).
The returned :class:LinearizedSystem additionally exposes:
.hsv— the full Hankel-singular-value spectrum,.reduced_order— the retained state countr,.error_bound— the a priori :math:H_\inftyerror bound :math:\lVert G - G_r\rVert_\infty \le 2\sum_{i>r}\sigma_i(Glover 1984 / Enns 1984).
Source code in jaxonomy/library/rom/linear_mor.py
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | |
bode_data(linsys, omegas)
Return matplotlib-ready Bode arrays for linsys.
Handles MIMO systems out of the box: when the underlying
:func:frequency_response returns shape (K, p, m) with p > 1
or m > 1, the returned magnitude_db / phase_deg arrays
keep the same (K, p, m) shape — one Bode pair per
(output, input) channel pair. The phase is unwrapped along the
frequency axis (axis=0) independently for each channel, which is
the standard convention for MIMO Bode plots.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
LinearizedSystem
|
A :class: |
required |
omegas
|
1-D array-like of angular frequencies |
required |
Returns:
| Type | Description |
|---|---|
|
Dictionary with keys:
|
Source code in jaxonomy/library/linearization_workflow.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
collect_snapshots(results, signals=None)
Assemble a snapshot matrix from a jaxonomy SimulationResults.
Selected recorded signals (results.outputs) are stacked column-wise
into X of shape (n_features, n_samples) where n_features is the
total width of the selected signals and n_samples == len(results.time).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
results
|
A |
required | |
signals
|
Optional[Sequence[str]]
|
Names to include (in order). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
SnapshotData
|
class: |
Source code in jaxonomy/library/rom/snapshots.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
controllability_gramian(A, B, dt=None)
Controllability Gramian :math:W_c.
Continuous time (dt is None) solves the Lyapunov equation
.. math:: A W_c + W_c A^\mathsf{T} = -B B^\mathsf{T}
Discrete time (dt given) solves the Stein equation
.. math:: A W_c A^\mathsf{T} - W_c + B B^\mathsf{T} = 0
Both require A stable (continuous: Re(eig) < 0; discrete:
|eig| < 1) for a positive-semidefinite solution.
Source code in jaxonomy/library/rom/linear_mor.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
deim(nonlinear_snapshots, rank=None, energy=None)
Greedy DEIM point selection (Chaturantabut & Sorensen 2010).
Takes an SVD basis U of the nonlinear-term snapshots and greedily
selects m interpolation indices, then forms the oblique DEIM projector
U (Pᵀ U)⁻¹ (P selects the chosen rows).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nonlinear_snapshots
|
Snapshots of the nonlinear term, shape
|
required | |
rank
|
Optional[int]
|
Number of DEIM modes/points |
None
|
energy
|
Optional[float]
|
Cumulative-energy threshold used when |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
ndarray
|
( |
Source code in jaxonomy/library/rom/pod.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
deim_galerkin_reduce(linear_rhs_fn, nonlinear_fn, basis, deim_result, x_ref=None, input_size=0, name=None)
Build a DEIM hyper-reduced POD-Galerkin ROM.
The full-order dynamics are split as ẋ = f_lin(t, x, u) + g(x) with a
(affine-)linear part f_lin and an elementwise nonlinearity g. The
linear operator is reduced offline to dense r×r / r×m operators, and
the nonlinearity is approximated by DEIM so it is evaluated only at the
selected points (Chaturantabut & Sorensen 2010).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linear_rhs_fn
|
Callable
|
Affine-linear part. Called |
required |
nonlinear_fn
|
Callable
|
Elementwise nonlinearity |
required |
basis
|
POD trial basis |
required | |
deim_result
|
Tuple[ndarray, ndarray]
|
The |
required |
x_ref
|
Reference/offset state (default zeros). |
None
|
|
input_size
|
int
|
Width of the single input port; |
0
|
name
|
Optional[str]
|
Optional block name. |
None
|
Returns:
| Type | Description |
|---|---|
_DEIMGalerkinROM
|
A jaxonomy |
_DEIMGalerkinROM
|
per-step cost is independent of the full dimension |
Source code in jaxonomy/library/rom/pod.py
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | |
discretize(linsys, dt, *, method='zoh', base_context=None, input_port=None, output_port=None)
Discretize a continuous-time linear system (T-109 phase 4).
Two call patterns, dispatched on the type of linsys:
discretize(linsys: LinearizedSystem, dt, *, method)— the LTI-level path (shipped first as the T-109 phase-4 sub-piece). Wraps the matrix-level helpers in :mod:jaxonomy.library.state_estimators.utils.discretize(system: SystemBase, dt, *, method, base_context, input_port, output_port)— the diagram-level lift (T-109 phase 4 completion). Linearizessystemaboutbase_context(via :func:linearize) then routes the result through path 1. Equivalent todiscretize(linearize(system, base_context, ...), dt, method=method); provided so controller-design workflows can writeddiagram = jaxonomy.discretize(diagram, dt, base_context=ctx)in one call.
Converts dx/dt = Ax + Bu into x[k+1] = A_d x[k] + B_d u[k]
while keeping C, D, and the operating point untouched (the
output map is unaffected by discretization). The returned
:class:LinearizedSystem carries dt so downstream consumers
(e.g. :meth:LinearizedSystem.is_stable) interpret it as
discrete-time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
Either a continuous-time :class: |
required | |
dt
|
float
|
Sampling period in seconds. Must be positive. |
required |
method
|
str
|
Discretization rule.
|
'zoh'
|
base_context
|
Required when |
None
|
|
input_port
|
Optional input port for :func: |
None
|
|
output_port
|
Optional output port for :func: |
None
|
Returns:
| Type | Description |
|---|---|
LinearizedSystem
|
A new :class: |
LinearizedSystem
|
|
LinearizedSystem
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Notes
Differentiable through A, B, C, D, and dt
via the JAX-traceable matrix exponential and linear solve.
The diagram path is differentiable through whatever
:func:linearize is itself differentiable through.
See also
:func:linearize — the continuous-time linearization step.
:func:jaxonomy.library.state_estimators.utils.discretize_forward_zoh
and :func:discretize_forward_euler — the matrix-level
primitives the LTI path wraps.
Source code in jaxonomy/library/linearization_workflow.py
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 | |
dmdc(X, Xp, U, rank=None, B_known=None)
Dynamic Mode Decomposition with control (Proctor, Brunton & Kutz 2016).
Fits x[k+1] ≈ A x[k] + B u[k] from snapshot pairs and control inputs.
Two cases are handled:
- Unknown
B(default): regress on the augmented snapshotΩ = [X; U]so[A B] = Xp Ω⁺. - Known
B(passB_known): subtract the known control effect first,A = (Xp − B U) X⁺.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
State snapshots |
required | |
Xp
|
Advanced snapshots |
required | |
U
|
Control inputs |
required | |
rank
|
Optional POD rank |
None
|
|
B_known
|
Optional known input matrix |
None
|
Returns:
| Type | Description |
|---|---|
|
class: |
Source code in jaxonomy/library/rom/dmd.py
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
edmd(X, Xp, dictionary, U=None)
Extended DMD — approximate the Koopman operator on lifted snapshots.
Lifts the snapshot pair through dictionary and least-squares fits the
lifted linear dynamics z[k+1] ≈ K z[k] (+ B u[k]).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
State snapshots |
required | |
Xp
|
Advanced snapshots |
required | |
dictionary
|
Callable |
required | |
U
|
Optional control inputs |
None
|
Returns:
| Type | Description |
|---|---|
|
class: |
|
|
|
Source code in jaxonomy/library/rom/koopman.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
era(markov, n_inputs, n_outputs, num_rows=None, num_cols=None, rank=None)
Eigensystem Realization Algorithm (Juang & Pappa 1985).
Builds a minimal discrete-time state-space realization (A, B, C, D) from a
sequence of impulse-response Markov parameters
Y_0 = D, Y_1 = C B, Y_2 = C A B ...
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
markov
|
Markov parameters. Either an array of shape
|
required | |
n_inputs
|
Number of inputs |
required | |
n_outputs
|
Number of outputs |
required | |
num_rows
|
Block rows |
None
|
|
num_cols
|
Block cols |
None
|
|
rank
|
Optional model order |
None
|
Returns:
| Type | Description |
|---|---|
|
class: |
|
|
singular values. |
Source code in jaxonomy/library/rom/dmd.py
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | |
estimate_frequency_response(diagram, ctx, t_span, input_port, output_port, freq_grid, *, options=None, recorded_signals_extra=None, window=True, coherence_floor=1e-12, n_segments=8, segment_overlap=0.5)
Empirically estimate the SISO transfer function of diagram.
Drives diagram with whatever signal is already wired to input_port
(typically a :class:jaxonomy.library.Chirp, :class:PRBS, or
:class:BandLimitedNoise source connected upstream of input_port)
and records the input/output trajectories. The empirical transfer
function is computed as the cross-spectral ratio
G(f) = Sxy(f) / Sxx(f) where Sxx and Sxy are the (Hann-
windowed) auto- and cross-spectral densities of input/output. Results
are interpolated onto the user-supplied freq_grid (Hz).
This is the practical alternative to analytic :func:linearize /
:func:frequency_response when:
- the system contains hard nonlinearities (lookup tables, saturation, contact dynamics) that make symbolic linearization fragile, or
- you want an empirical sanity-check against the linearized model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
diagram
|
A built diagram (typically with a chirp or PRBS source wired to the block-under-test's input port). |
required | |
ctx
|
Initial simulation context. |
required | |
t_span
|
|
required | |
input_port
|
|
required | |
output_port
|
|
required | |
freq_grid
|
1-D array of frequencies (Hz) at which the empirical
response should be evaluated. Frequencies outside the
simulation's resolved band |
required | |
options
|
Optional :class: |
None
|
|
recorded_signals_extra
|
Optional |
None
|
|
window
|
bool
|
If True (default) apply a Hann window before the FFT to suppress spectral leakage. If False (rectangular) the transfer-function ratio is more sensitive to leakage but faithful to the raw FFT. |
True
|
coherence_floor
|
float
|
Minimum |
1e-12
|
n_segments
|
int
|
Number of overlapping segments to average (Welch's
method). More segments → less variance, lower frequency
resolution. |
8
|
segment_overlap
|
float
|
Fractional overlap between consecutive segments
(Welch's method), in |
0.5
|
Returns:
| Type | Description |
|---|---|
FrequencyResponse
|
class: |
FrequencyResponse
|
|
FrequencyResponse
|
|
FrequencyResponse
|
func: |
Notes
- The implementation is intentionally pure-NumPy on the
post-simulation arrays; it does not need to be JAX-traceable
(callers can JIT downstream code that consumes the returned
responsearray). - For best results pick an excitation that covers the band of
interest densely: a linear :class:
Chirpfromf0 ≪ freq_mintof1 ≳ freq_maxover a horizon of several seconds, or a :class:PRBSwith sample time≪ 1/(2·freq_max). - The returned
responseis a NumPy complex array (consumers calling :func:bode_datawill seejnp.asarraypromotion); this is fine because :class:FrequencyResponsefields are typedAny.
Source code in jaxonomy/library/linearization_workflow.py
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | |
findop(system, base_context, *, initial_guess=None, input_port=None, tol=1e-08, max_iter=50, damping=1e-10, axis_mask=None, residual_fn=None, residual_scaling=None, scaling_eps=1e-08)
Find a continuous-state operating point x* such that ẋ(x*, u₀) ≈ 0.
Performs damped Newton iteration on the residual r(x) = ẋ(x, u₀) where
u₀ is read from base_context (and held fixed for the duration of
the search). The Jacobian is computed with jax.jacrev and the linear
update is solved with jnp.linalg.solve plus a small Levenberg
regularisation so singular Jacobians degrade to a least-squares step
instead of NaN.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
The system whose equilibrium is sought. |
required | |
base_context
|
A context that supplies the initial state, parameter
values, and (via |
required | |
initial_guess
|
Optional initial state. Defaults to
|
None
|
|
input_port
|
Input port to read |
None
|
|
tol
|
float
|
Stop when |
1e-08
|
max_iter
|
int
|
Hard cap on Newton iterations. |
50
|
damping
|
float
|
Tikhonov damping added to |
1e-10
|
axis_mask
|
Optional selector for which state components the Newton
iteration drives to zero. Either a boolean array (length =
number of flat state components, |
None
|
|
residual_fn
|
Optional |
None
|
|
residual_scaling
|
Optional per-component residual weighting to put
disparate units on a common footing (cf. MATLAB |
None
|
|
scaling_eps
|
float
|
Floor for the |
1e-08
|
Returns:
| Type | Description |
|---|---|
OperatingPoint
|
class: |
OperatingPoint
|
metadata. |
OperatingPoint
|
components carry their initial values when |
Notes
The returned x is a JAX array, so the residual function used here
is differentiable: jax.grad(lambda x0: jnp.sum(residual(x0)**2))
works. Composing :func:findop itself under jax.grad requires an
implicit-differentiation wrapper which is deferred to a follow-up.
Robust fallback. Newton operating-point search can stall on stiff,
strongly-coupled, or badly-scaled systems even with axis_mask and
residual_scaling. The most robust equilibrium finder is simply to
integrate to steady state: simulate the system from a reasonable
initial condition over a horizon long relative to its slowest mode and
take the final state (optionally asserting max(|ẋ|) is small
there). Use that when findop reports converged=False.
Source code in jaxonomy/library/linearization_workflow.py
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | |
fit_gp(X, y, kernel='rbf', length_scale=1.0, signal_var=1.0, noise=1e-08, optimize=False, n_restarts=0, lr=0.05, n_steps=200, matern_nu=2.5)
Fit a Gaussian-process (kriging) surrogate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
training inputs, shape |
required | |
y
|
training targets, shape |
required | |
kernel
|
|
'rbf'
|
|
length_scale, signal_var, noise
|
kernel hyperparameters (initial values
when |
required | |
optimize
|
if True, maximize the marginal log-likelihood over
|
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Source code in jaxonomy/library/rom/surrogates.py
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
fit_lookup_table_1d(xp, x_data, y_data, *, interpolation='linear', extrapolation='clip', weights=None, smoothness=0.0, name=None, **block_kwargs)
Fit a 1-D lookup table to data and return a LookupTable1d block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xp
|
Fixed grid of breakpoints (1-D, strictly increasing). |
required | |
x_data
|
Measured input cloud, shape |
required | |
y_data
|
Measured output cloud, shape |
required | |
interpolation
|
str
|
Interpolation rule for the runtime block
( |
'linear'
|
extrapolation
|
str
|
Out-of-range policy for the runtime block; see
:class: |
'clip'
|
weights
|
Optional per-sample weights for weighted least-
squares. |
None
|
|
smoothness
|
float
|
Non-negative discrete first-difference penalty. Use small values (1e-3 .. 1.0) on noisy / sparse data. |
0.0
|
name
|
str | None
|
Optional block name, forwarded to |
None
|
**block_kwargs
|
Additional kwargs forwarded to the
|
{}
|
Returns:
| Type | Description |
|---|---|
|
A |
|
|
|
Source code in jaxonomy/library/lookup_table_fitting.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
fit_lookup_table_2d(xp, yp, x_data, y_data, z_data, *, interpolation='linear', extrapolation='clip', weights=None, smoothness=0.0, name=None, **block_kwargs)
Fit a 2-D lookup table to data and return a LookupTable2d block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xp
|
Fixed grid of breakpoints along the first axis (1-D, strictly increasing). |
required | |
yp
|
Fixed grid of breakpoints along the second axis (1-D, strictly increasing). |
required | |
x_data, y_data, z_data
|
Measurement cloud, all shape |
required | |
interpolation
|
str
|
Interpolation rule for the runtime block
(currently only |
'linear'
|
extrapolation
|
str
|
Out-of-range policy for the runtime block. |
'clip'
|
weights
|
Optional per-sample weights for weighted least-squares. |
None
|
|
smoothness
|
float
|
Non-negative 5-point-Laplacian smoothness penalty. |
0.0
|
name
|
str | None
|
Optional block name. |
None
|
**block_kwargs
|
Additional kwargs forwarded to the
|
{}
|
Returns:
| Type | Description |
|---|---|
|
A |
|
|
|
|
|
LS-fit table values of shape |
Source code in jaxonomy/library/lookup_table_fitting.py
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | |
fit_lookup_table_nd(grid_axes, x_data, y_data, *, interpolation='linear', extrapolation='clip', weights=None, smoothness=0.0, name=None, **block_kwargs)
Fit an N-D lookup table to data and return a LookupTableND block.
The public N-D counterpart to :func:fit_lookup_table_1d and
:func:fit_lookup_table_2d. Returns a fully-built block whose
output_array is the LS-fit table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_axes
|
Tuple of |
required | |
x_data, y_data
|
Measurement cloud — |
required | |
interpolation
|
str
|
Interpolation rule for the runtime block. Only
|
'linear'
|
extrapolation
|
str
|
Out-of-range policy for the runtime block; see
:class: |
'clip'
|
weights
|
Optional per-sample weights for weighted least-squares. |
None
|
|
smoothness
|
float
|
Non-negative coefficient on the N-D Laplacian smoothness penalty. |
0.0
|
name
|
str | None
|
Optional block name. |
None
|
**block_kwargs
|
Additional kwargs forwarded to the
|
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
|
|
and |
||
|
|
Source code in jaxonomy/library/lookup_table_fitting.py
938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 | |
fit_pce(X, y, distributions, order)
Fit a polynomial-chaos expansion by least-squares regression.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
training inputs, shape |
required | |
y
|
training targets, shape |
required | |
distributions
|
Sequence
|
per-dimension germ, e.g. |
required |
order
|
int
|
total-degree truncation. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Source code in jaxonomy/library/rom/surrogates.py
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | |
fit_rbf(X, y, kernel='multiquadric', epsilon=1.0, smoothing=0.0, poly_degree=None)
Fit a radial-basis-function surrogate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
training inputs, shape |
required | |
y
|
training targets, shape |
required | |
kernel
|
|
'multiquadric'
|
|
epsilon
|
shape parameter (ignored by the thin-plate spline). |
1.0
|
|
smoothing
|
ridge regularization added to the kernel diagonal; |
0.0
|
|
poly_degree
|
if set, augment with a total-degree polynomial tail and solve the bordered saddle-point system (Wendland 2005, Ch. 8). |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
An |
class: |
Source code in jaxonomy/library/rom/surrogates.py
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | |
fit_table_1d_with_grid(n_grid_points, x_data, y_data, x_lo=None, x_hi=None, init_xp=None, *, smoothness=0.0, optimizer='gd', max_iter=200, learning_rate=0.001, auto_normalize=True)
Jointly optimise the grid xp AND the table values yp.
This is the T-124-followup-grid-optimization deliverable. Phase 1's
:func:fit_table_1d fits yp at a fixed user-supplied xp;
here we ALSO move the breakpoints to better resolve regions where
the data has strong features (sharp peaks, kinks).
The math: for any candidate grid xp, the inner problem is still
a linear least-squares solve for yp (closed form). The outer
loop minimises the resulting data residual w.r.t. xp, with
monotonicity enforced via a smooth cumsum(softplus(deltas))
parametrisation rather than projection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_grid_points
|
int
|
Number of breakpoints to place (must be ≥ 2). |
required |
x_data
|
Measured input cloud, shape |
required | |
y_data
|
Measured output cloud, shape |
required | |
x_lo
|
float | None
|
Lower endpoint of the grid. |
None
|
x_hi
|
float | None
|
Upper endpoint of the grid. |
None
|
init_xp
|
Optional initial grid (1-D, strictly increasing,
spanning |
None
|
|
smoothness
|
float
|
Forwarded to the inner LS solve as a discrete
first-difference penalty on |
0.0
|
optimizer
|
str
|
|
'gd'
|
max_iter
|
int
|
Outer-loop iteration budget. For |
200
|
learning_rate
|
float
|
Step size for |
0.001
|
auto_normalize
|
bool
|
When |
True
|
Returns:
| Type | Description |
|---|---|
|
|
|
|
|
|
|
values (shape |
|
|
through |
|
|
bucket index in the design matrix) when |
|
|
|
Honest fallback note: this ships the gradient-descent path as the
primary solver (rather than full L-BFGS) per the task spec — it's
slower but more robust on the inner-outer formulation. The proper
differentiable L-BFGS via implicit-function-theorem unrolling is
filed as T-124-followup-grid-optimization-lbfgs.
Source code in jaxonomy/library/lookup_table_fitting.py
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | |
fit_table_2d(xp, yp, x_data, y_data, z_data, weights=None, smoothness=0.0, rcond=None)
Fit a 2-D lookup table zp at the fixed grid (xp, yp) to
(x_data, y_data, z_data).
Solves the bilinear least-squares problem
min_zp Σ_k w_k * (z_data[k] - bilinear_interp(x_data[k], y_data[k]; xp, yp, zp))²
+ smoothness * Σ_{i,j} (zp[i,j] - mean(neighbours))²
via :func:jnp.linalg.lstsq on the bilinear design matrix. Linear
bilinear only — the 2-D analogue of the fit_table_1d linear-only
restriction. See T-124-followup-2d-pchip-fit for non-linear
extensions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
xp
|
1-D, strictly increasing grid along the first axis ( |
required | |
yp
|
1-D, strictly increasing grid along the second axis ( |
required | |
x_data, y_data, z_data
|
Measurement cloud, all shape |
required | |
weights
|
Optional per-sample weights, shape |
None
|
|
smoothness
|
float
|
Non-negative coefficient for the 5-point Laplacian
penalty. |
0.0
|
rcond
|
float | None
|
Forwarded to :func: |
None
|
Returns:
| Type | Description |
|---|---|
|
|
|
|
values. Differentiable through |
|
|
|
Source code in jaxonomy/library/lookup_table_fitting.py
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | |
fit_table_nd(grid_axes, x_data, y_data, *, weights=None, smoothness=0.0, rcond=None)
Fit an N-D lookup table at fixed grid breakpoints.
Solves the multilinear least-squares problem
min_zp Σ_k w_k * (y_data[k] - multilinear_interp(x_data[k]; grid_axes, zp))²
+ smoothness * Σ_cells (zp[cell] - mean(in-bounds neighbours))²
via :func:jnp.linalg.lstsq on the multilinear design matrix.
Generalises :func:fit_table_2d (and :func:fit_table_1d for
N=1) to an arbitrary number of grid axes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_axes
|
Tuple of |
required | |
x_data
|
Query points, shape |
required | |
y_data
|
Sample values at the query points, shape |
required | |
weights
|
Optional per-sample weights, shape |
None
|
|
smoothness
|
float
|
Non-negative coefficient on the N-D-Laplacian
penalty. |
0.0
|
rcond
|
float | None
|
Forwarded to :func: |
None
|
Returns:
| Type | Description |
|---|---|
|
|
|
|
Layout matches :class: |
|
|
the result can be passed straight through. |
Memory note: builds a dense (K + prod(B_i), prod(B_i)) design
matrix. For N=5 with B_i = 10 that's 10^5 columns —
fine on CPU up to a few thousand measurements. For larger tables
or higher-D problems, switch to a sparse solver (filed under
T-104-followup-fit-table-nd-sparse).
Source code in jaxonomy/library/lookup_table_fitting.py
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 | |
frequency_response(linsys, omegas)
Compute the frequency response of a linearized state-space system.
For a continuous-time LTI ẋ = Ax + Bu, y = Cx + Du the transfer function
evaluated at s = jω is the (p, m) transfer-function matrix
G(s) = C (sI − A)⁻¹ B + D. This helper vectorises that evaluation
across an omegas array and naturally handles MIMO systems
(m > 1 inputs and/or p > 1 outputs) — the returned array shape
is always (K, p, m). SISO is the special case p = m = 1 which
produces shape (K, 1, 1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
LinearizedSystem
|
A :class: |
required |
omegas
|
1-D array-like of angular frequencies |
required |
Returns:
| Type | Description |
|---|---|
FrequencyResponse
|
class: |
FrequencyResponse
|
|
FrequencyResponse
|
and |
FrequencyResponse
|
transfer function from input |
FrequencyResponse
|
|
Notes
The implementation is fully JAX-traceable and differentiable through
A, B, C, D and omegas so it composes with jax.grad and
jax.vmap. jnp.linalg.solve solves the matrix RHS B in
one shot per frequency so the per-omega cost is one LU decomposition
plus m triangular back-substitutions — substantially cheaper than
looping over input channels.
Source code in jaxonomy/library/linearization_workflow.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | |
galerkin_reduce(rhs_fn, basis, x_ref=None, output_fn=None, input_size=0, test_basis=None, name=None)
Project a full-order RHS onto a reduced basis (POD-Galerkin / LSPG).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_fn
|
Callable
|
Full-order dynamics. Called as |
required |
basis
|
Trial basis |
required | |
x_ref
|
Reference/offset state added on reconstruction (default zeros). |
None
|
|
output_fn
|
Optional[Callable]
|
Optional map applied to the reconstructed full state for the output port. |
None
|
input_size
|
int
|
Width of the single input port; |
0
|
test_basis
|
Optional test basis |
None
|
|
name
|
Optional[str]
|
Optional block name. |
None
|
Returns:
| Type | Description |
|---|---|
_ProjectionROM
|
A jaxonomy |
Source code in jaxonomy/library/rom/pod.py
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |
hankel_singular_values(sys)
Hankel singular values, sorted descending.
:math:\sigma_i = \sqrt{\lambda_i(W_c W_o)} for the controllability and
observability Gramians of sys (Moore 1981).
Source code in jaxonomy/library/rom/linear_mor.py
150 151 152 153 154 155 156 157 158 159 160 161 | |
identity_dictionary()
Trivial dictionary g(x) = x.
eDMD with this dictionary reduces to plain (linear) DMD — a useful baseline.
Source code in jaxonomy/library/rom/koopman.py
52 53 54 55 56 57 58 59 60 61 | |
impulse_response(linsys, t_grid)
Closed-form impulse response of a continuous-time LTI system.
For zero initial state the (finite part of the) impulse response is
.. code-block:: text
y(t) = C · expm(A·t) · B for t > 0
The Dirac component D · δ(t) is omitted from the returned
samples since it is not representable on a numeric grid; consumers
that need it can add D to the t = 0 sample explicitly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
LinearizedSystem
|
A :class: |
required |
t_grid
|
Scalar or 1-D array of evaluation times. |
required |
Returns:
| Type | Description |
|---|---|
|
Array of shape |
|
|
for scalar |
|
|
|
Notes
Fully differentiable through A, B, C, D.
Source code in jaxonomy/library/linearization_workflow.py
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | |
linearize(system, base_context, name=None, output_index=None, input_port=None, output_port=None)
Linearize the system about an operating point specified by the base context.
Note: Deprecated return type. Previously returned LTISystem directly, now returns
a LinearizedSystem object. Use .to_lti() on the result if you need an LTISystem block.
Source code in jaxonomy/library/linear_system.py
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | |
linearize_to_lti(system, base_context, input_port=None, output_port=None, name=None)
Linearize system at base_context and return an LTISystem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
'SystemBase'
|
A |
required |
base_context
|
'ContextBase'
|
The operating-point context. State, inputs, and parameters read from this context define the point about which the linearization is performed. |
required |
input_port
|
Input port to linearize against. Required when
|
None
|
|
output_port
|
Output port to linearize against. Required when
|
None
|
|
name
|
Optional[str]
|
Optional name for the returned |
None
|
Returns:
| Type | Description |
|---|---|
'LTISystem'
|
An |
'LTISystem'
|
matrices. Drop this into a |
'LTISystem'
|
original subdiagram would go; downstream blocks should be |
'LTISystem'
|
wired to |
'LTISystem'
|
|
Source code in jaxonomy/library/linearize_container.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | |
merge_buses(bus_a, bus_b, *, on_collision='error')
Merge two NamedTuple-shaped bus signals by union of fields.
The merged bus is a fresh NamedTuple (named "MergedBus") whose
fields are bus_a._fields followed by the fields of
bus_b._fields not already in bus_a (de-duplicated while
preserving declaration order). The result is a JAX-pytree-friendly
value identical in shape to what :class:BusCreator would produce
for the merged schema.
Differentiability: gradients flow from each merged-bus leaf back to
whichever input bus contributed the leaf — the underlying op is
NamedTuple construction over getattr lookups, both of which are
transparent to jax.grad / jax.jit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bus_a
|
First bus signal. Must be a NamedTuple-shaped value
( |
required | |
bus_b
|
Second bus signal. Same contract as |
required | |
on_collision
|
str
|
Policy for fields that appear in both inputs.
The merged-bus schema (field order) is independent of the policy: collisions only change which leaf value lands in the colliding slot. |
'error'
|
Returns:
| Type | Description |
|---|---|
|
A NamedTuple instance whose fields are the union of |
|
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If either input is not a NamedTuple-shaped value. |
ValueError
|
If |
Source code in jaxonomy/library/routing.py
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 | |
minimal_realization(sys, tol=1e-08)
Minimal realization of sys (Kalman decomposition).
Removes uncontrollable and unobservable modes by projecting onto the
controllable subspace (range of the controllability matrix) and then onto
the observable subspace (range of the observability matrix transposed).
Ranks are decided from singular values with the relative threshold tol.
The input/output transfer function is preserved.
Source code in jaxonomy/library/rom/linear_mor.py
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | |
modal_truncation(sys, order=None, keep=None)
Modal truncation.
Transforms sys to a real block-diagonal modal realization and keeps
the dominant (slowest) modes, discarding the rest. Complex-conjugate
pairs are always kept or dropped together, so the reduced model stays
real; the retained poles are exactly the retained eigenvalues.
order— target number of retained states (a straddling conjugate pair may push the actual count toorder + 1).keep— explicit iterable of modal-state indices to retain (expanded to whole blocks).- neither — no truncation (returns the modal-form equivalent).
Because coupling to the discarded modes is dropped outright, the DC gain
generally shifts; use :func:residualize to preserve it.
Source code in jaxonomy/library/rom/linear_mor.py
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | |
model_description_xml(diagram, *, model_name, guid=None, description='Exported by jaxonomy.library.fmu_export', generation_tool='jaxonomy')
Build the FMI 2.0 modelDescription XML as a string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
diagram
|
'Diagram'
|
A :class: |
required |
model_name
|
str
|
Human-readable model name. Also used as the modelIdentifier (with non-identifier characters stripped). |
required |
guid
|
str | None
|
Optional FMU GUID; auto-generated if None. |
None
|
description
|
str
|
Free-form description string. |
'Exported by jaxonomy.library.fmu_export'
|
generation_tool
|
str
|
Stored in the FMU metadata. |
'jaxonomy'
|
Returns:
| Type | Description |
|---|---|
str
|
UTF-8 XML string ending with a trailing newline. |
Source code in jaxonomy/library/fmu_export.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
nyquist_data(linsys, omegas)
Return Nyquist-contour arrays for linsys.
The Nyquist plot traces G(jω) through the complex plane. This
helper returns the real and imaginary parts of G(jω) over the
supplied positive angular frequencies and additionally the reflected
negative-frequency arrays (since G(-jω) = conj(G(jω)) for a
real-coefficient LTI, the reflection is given exactly by
(Re, -Im)). Consumers can concatenate the negative and positive
arrays to obtain the full closed contour used for encirclement
counting; for stability margins computed only from the positive
sweep, real and imag are sufficient.
For MIMO systems the returned real / imag arrays preserve
the (K, p, m) channel structure from :func:frequency_response;
for SISO they are squeezed to (K,), matching the convention of
:func:bode_data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
LinearizedSystem
|
A :class: |
required |
omegas
|
1-D array-like of positive angular frequencies
|
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary with keys:
|
Notes
Fully differentiable through A, B, C, D and omegas via
the underlying :func:frequency_response.
Source code in jaxonomy/library/linearization_workflow.py
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 | |
observability_gramian(A, C, dt=None)
Observability Gramian :math:W_o.
Continuous time (dt is None) solves
.. math:: A^\mathsf{T} W_o + W_o A = -C^\mathsf{T} C
Discrete time (dt given) solves
.. math:: A^\mathsf{T} W_o A - W_o + C^\mathsf{T} C = 0
Source code in jaxonomy/library/rom/linear_mor.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
pod_basis(X, rank=None, energy=None)
Proper-orthogonal-decomposition basis of a snapshot matrix.
Computes the (host-side) thin SVD X = U Σ Vᵀ and truncates to r
left singular vectors, which are the energetically optimal orthonormal
modes (Sirovich 1987).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
Snapshot matrix, shape |
required | |
rank
|
Optional[int]
|
Explicit number of modes to keep. |
None
|
energy
|
Optional[float]
|
Cumulative-energy threshold in |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
ndarray
|
orthonormal columns, |
int
|
|
Source code in jaxonomy/library/rom/pod.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | |
pole_zero_map(linsys)
Compute poles and zeros of a :class:LinearizedSystem.
Poles are the eigenvalues of A. Zeros are the (transmission)
zeros of the SISO transfer function G(s) = C (sI − A)⁻¹ B + D,
computed as the finite generalised eigenvalues of the Rosenbrock
system pencil
.. code-block:: text
P(s) = [[ sI − A, −B ],
[ C , D ]]
by solving the generalised eigenproblem λ E v = M v with
.. code-block:: text
E = [[ I, 0 ], M = [[ A, B ],
[ 0, 0 ]] [ C, D ]]
Finite eigenvalues (those with non-zero E-weight) of this pencil
are the invariant zeros of the system; for SISO they coincide with
the numerator roots of the transfer function. The high-frequency
gain is reported as D[0, 0] (the asymptotic value of
G(s) → D for |s| → ∞); for a strictly-proper system
(D = 0) the leading-coefficient gain is harder to define
unambiguously without polynomial fitting and is left to a deeper
follow-up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
LinearizedSystem
|
A :class: |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary with keys:
|
Notes
Pole computation is differentiable through A (via
jnp.linalg.eigvals). Zero computation uses
:func:scipy.linalg.eig on the generalised problem and is
therefore not currently traceable by JAX — call it eagerly,
outside jit. A differentiable variant is a deeper follow-up.
Source code in jaxonomy/library/linearization_workflow.py
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 | |
polynomial_dictionary(degree, include_constant=True)
Monomial dictionary up to degree.
Layout: [x_1..x_n, (1), (degree-2..degree monomials)] — identity first so
the state is recoverable. The constant term is included by default (it makes
affine dynamics representable in the lifted space).
Source code in jaxonomy/library/rom/koopman.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
projection_error(X, basis)
Relative projection error ‖X − ΦΦᵀX‖ / ‖X‖ of X onto basis.
basis (Φ) is assumed to have orthonormal columns.
Source code in jaxonomy/library/rom/snapshots.py
137 138 139 140 141 142 143 144 145 146 147 148 | |
rbf_dictionary(centers, epsilon=1.0)
Gaussian radial-basis dictionary.
Lifts to [x, exp(-epsilon ||x - c_j||²) for each center c_j] — identity
observables first, followed by one RBF feature per center.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
centers
|
Array |
required | |
epsilon
|
float
|
Shape parameter of the Gaussian kernel. |
1.0
|
Source code in jaxonomy/library/rom/koopman.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |
reduce(target, method='balred', *, order=None, tol=None, dt=1.0, **kwargs)
Reduce target by method and return a :class:ReducedOrderModel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
An LTI model (linear MOR) or snapshot data (data-driven). |
required | |
method
|
See the module docstring for the supported names. |
'balred'
|
|
order
|
Target reduced order, where the method takes one. |
None
|
|
tol
|
Energy/tolerance selector for balanced truncation / |
None
|
|
dt
|
Sampling period for the data-driven predictor blocks. |
1.0
|
|
**kwargs
|
Forwarded to the underlying routine (e.g. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
class: |
Source code in jaxonomy/library/rom/framework.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
relative_error(x_true, x_approx)
Relative L2 (Frobenius) error ‖x_true − x_approx‖ / ‖x_true‖.
Works for a single trajectory column or a full snapshot matrix.
Source code in jaxonomy/library/rom/snapshots.py
110 111 112 113 114 115 116 117 118 119 120 | |
residualize(sys, order=None, keep=None)
Singular-perturbation (residualization) reduction.
Like :func:modal_truncation, but instead of deleting the fast modes it
sets their derivative (continuous) or their increment (discrete) to zero
and solves for their quasi-steady value, folding it back into the
retained model. This matches the DC gain of the discarded modes
(Kokotović, Khalil & O'Reilly 1986).
Partitioning the modal realization into retained (1) and discarded
(2) states, continuous time gives
.. math::
A_r &= A_{11} - A_{12} A_{22}^{-1} A_{21}, &
B_r &= B_1 - A_{12} A_{22}^{-1} B_2, \\
C_r &= C_1 - C_2 A_{22}^{-1} A_{21}, &
D_r &= D - C_2 A_{22}^{-1} B_2,
and discrete time replaces A_{22}^{-1} by -(I - A_{22})^{-1}.
Selection arguments match :func:modal_truncation.
Source code in jaxonomy/library/rom/linear_mor.py
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | |
retained_energy(singular_values, r)
Fraction of total energy captured by the first r POD modes.
Energy is measured in squared singular values,
Σ_{i<r} σ_i² / Σ_i σ_i² — monotonically non-decreasing in r.
Source code in jaxonomy/library/rom/snapshots.py
123 124 125 126 127 128 129 130 131 132 133 134 | |
soft_dead_zone(u, half_range, sharpness=10.0)
Smooth (differentiable) dead-zone gate.
Approximates the hard dead-zone where(|u| < half_range, 0, u)
used by :class:DeadZone(mode="hard") with a sigmoid-blended kernel
so gradients flow through the band. The blend factor is
sigmoid(sharpness * (|u| - half_range)):
::
gate = 0.5 * (1.0 + tanh(sharpness * (|u| - half_range) / half_range))
y = u * gate
Properties
y(0) = 0exactly.gate -> 1outside the band, soy -> ufor|u| >> half_range.gate -> 0inside the band, soy -> 0for|u| << half_range.- Continuous everywhere; finite gradient even inside the band (this is the whole reason it exists).
- As
sharpness -> infthe function converges to the hard gate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
Input array. |
required | |
half_range
|
Positive scalar; band half-width. |
required | |
sharpness
|
Positive scalar; default |
10.0
|
Returns:
| Type | Description |
|---|---|
|
Smoothly gated array, same shape as |
Source code in jaxonomy/library/nonlinearities.py
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | |
soft_saturate(u, lower, upper, sharpness=10.0)
Smooth (differentiable) saturation between lower and upper.
Approximates npa.clip(u, lower, upper) with a tanh-based smooth
clamp (per the T-115 spec):
::
mid = (lower + upper) / 2
span = upper - lower
y = mid + (span / 2) * tanh(sharpness * (u - mid) / span)
With sharpness = 10.0 and a unit span this gives ~99% saturation
by |u - mid| = span, which is the design default.
Properties
- As
sharpness -> infthe function converges to a hardclip. - Strictly monotonically increasing in
u(analytically; in finite precision the slope underflows to zero very far frommidbecause tanh saturates exponentially). - Has a positive derivative across and inside the bound region -- gradients flow through saturation, which is the whole reason this exists.
- Requires finite
lower/upper; for unbounded sides use the hard :class:Saturateblock.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
u
|
Input array. |
required | |
lower
|
Lower limit (scalar or broadcastable array). |
required | |
upper
|
Upper limit (scalar or broadcastable array). |
required | |
sharpness
|
Positive scalar; default |
10.0
|
Returns:
| Type | Description |
|---|---|
|
Smoothly saturated array, same shape as |
Source code in jaxonomy/library/nonlinearities.py
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 | |
step_response(linsys, t_grid)
Closed-form step response of a continuous-time LTI system.
For zero initial state and unit step input u(t) = 1 (for t ≥ 0)
the response is
.. code-block:: text
y(t) = C · ∫₀ᵗ expm(A·s) ds · B + D·1
The matrix integral is computed via the augmented-matrix expm trick
(see :func:_augmented_step_block) so the routine works correctly
for non-invertible A (e.g. integrators). When A is
invertible the same value equals C·A⁻¹·(expm(A·t) − I)·B + D.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
linsys
|
LinearizedSystem
|
A :class: |
required |
t_grid
|
Scalar or 1-D array of evaluation times. Negative times
are evaluated formally (the closed-form result is still well
defined; physically the step starts at |
required |
Returns:
| Type | Description |
|---|---|
|
Array of shape |
|
|
each |
|
|
|
|
|
the returned shape is |
|
|
scalar |
Notes
Fully differentiable through A, B, C, D via
:func:jax.scipy.linalg.expm. For very large state dimensions
(n > 50) the augmented expm may be slow — the honest fall-
back is to simulate the diagram with a :class:Step source
(deferred to a deeper follow-up).
Source code in jaxonomy/library/linearization_workflow.py
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 | |
with_observer(plant, observer, *, plant_u_port=0, plant_y_port=0, name='plant_with_observer')
Build a new diagram with observer attached to plant.
Wires the plant's control input through to both the plant and the
observer; wires the plant's measurement output through to the
observer; exports the observer's x_hat estimate as a top-level
output of the augmented diagram. The plant's other output ports
are not re-exported automatically — call sites that need them can
wire them up in a parent diagram.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
A built :class: |
required | |
observer
|
A built observer block (typically
:class: |
required | |
plant_u_port
|
int
|
Index of the plant input port carrying the
control signal |
0
|
plant_y_port
|
int
|
Index of the plant output port carrying the
measurement |
0
|
name
|
str
|
Name for the resulting wrapper diagram. |
'plant_with_observer'
|
Returns:
| Type | Description |
|---|---|
|
A new :class: |
|
|
|
|
|
|
|
Notes
The result is a "passive" instrumentation pattern — the
observer reads (u, y) and emits an estimate, but the
estimate is not fed back into the plant. To close a loop
around the estimate (state-feedback control with observed
state), build a controller subdiagram and wire its output
back to plant.u in a parent diagram.
Source code in jaxonomy/library/linearization_workflow.py
1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | |
write_model_description(diagram, path, *, model_name=None, guid=None, description=None)
Write a Jaxonomy diagram's FMI 2.0 modelDescription.xml to disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
diagram
|
'Diagram'
|
Diagram to export. |
required |
path
|
str
|
Output file path. |
required |
model_name
|
str | None
|
Defaults to |
None
|
guid
|
str | None
|
Optional GUID. |
None
|
description
|
str | None
|
Optional free-form description. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The same |
Source code in jaxonomy/library/fmu_export.py
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | |