API Reference¶
Simulation¶
- class pybounds.Simulator(f, h, dt=0.01, discrete=False, n=None, m=None, state_names=None, input_names=None, measurement_names=None, params_simulator=None, mpc_horizon=10)[source]¶
Bases:
object- simulator_tvp_function(t)[source]¶
Set the set-point function for MPC simulator. :type t: :param t: current time
- simulate(x0=None, u=None, aux=None, mpc=False, return_full_output=False)[source]¶
Simulate the system.
- Parameters:
x0 – initial state dict or array
u – input dict or array, if True then mpc must be None
aux – auxiliary input
mpc – boolean to run MPC, if True then u must be None
return_full_output – boolean to run (time, x, u, y) instead of y
Observability¶
- class pybounds.EmpiricalObservabilityMatrix(simulator, x0, u, aux=None, eps=1e-05, parallel=False, z_function=None, z_state_names=None)[source]¶
Bases:
object
- class pybounds.SlidingEmpiricalObservabilityMatrix(simulator, t_sim, x_sim, u_sim, aux_list=None, w=None, eps=1e-05, parallel_sliding=False, parallel_perturbation=False, simulator_factory=None, n_workers=None, z_function=None, z_state_names=None)[source]¶
Bases:
object
- class pybounds.FisherObservability(O, R=None, lam=None, force_R_scalar=False, states=None, sensors=None, time_steps=None, w=None)[source]¶
Bases:
object
- class pybounds.SlidingFisherObservability(O_list, R=None, lam=1000000.0, time=None, states=None, sensors=None, time_steps=None, w=None)[source]¶
Bases:
object
- pybounds.compute_observability(simulator, t_sim, x_sim, u_sim, R, w=6, eps=0.0001, lam=1e-08, use_jax=False)[source]¶
Compute sliding-window Fisher observability in one call.
- Parameters:
simulator (Simulator or JaxSimulator) – A configured simulator instance. Pass a
JaxSimulatorwhenuse_jax=True.t_sim (trajectory returned by simulator.simulate(..., return_full_output=True))
x_sim (trajectory returned by simulator.simulate(..., return_full_output=True))
u_sim (trajectory returned by simulator.simulate(..., return_full_output=True))
R (dict — sensor noise covariance, e.g. {'r': 0.1})
w (int — sliding window length (time steps))
eps (float — finite-difference perturbation size (ignored when use_jax=True))
lam (float — Chernoff regularization for Fisher inversion)
use_jax (bool — if True, use JAX autodiff (exact Jacobians, faster for many windows).) – Requires JAX to be installed and
simulatorto be aJaxSimulatorwhosefandhfunctions are written withjax.numpy(jnp) instead ofnumpy. SeeJaxSimulatorfor details.
- Returns:
DataFrame with columns ‘time’, ‘time_initial’, and one column per state
containing the minimum error variance for each sliding window.
Visualisation¶
- class pybounds.ObservabilityMatrixImage(O, state_names=None, sensor_names=None, vmax_percentile=100, vmin_ratio=1.0, cmap='bwr')[source]¶
Bases:
object
Utilities¶
- pybounds.transform_states(O=None, square_flag=False, z_function=None, x0=None, z_state_names=None)[source]¶
Transform the coordinates of an observability matrix (O) or Fisher information matrix (F) from the original coordinates (x) to new user defined coordinates (z).
- Parameters:
O – observability matrix or Fisher information matrix
square_flag (boolean) – whether to square the transform Jacobian or not should be set to False if passing squared an observability matrix as O should be set to True if passing squared a Fisher information matrix as O
z_function (callable) – function that transforms coordinates from original to new states must be of the form z = z_function(x), where x & z are the same size should use sympy functions wherever possible
x0 (np.array) – initial state in original coordinates
z_state_names (list | tuple) – (optional) names of states in new coordinates. will only have an effect if O or F is a data-frame
- Returns:
Z: observability matrix or Fisher information matrix in transformed coordinates dzdx: numerical Jacobian dz/dx (inverse of dx/dz) evaluated at x0 dxdz_sym: symbolic Jacobian dx/dz
JAX Backend (optional)¶
The JAX backend provides exact autodiff Jacobians via jax.jacfwd and
batched window computation via jax.vmap. Requires pip install
pybounds[jax] and dynamics/measurement functions written with
jax.numpy.
- class pybounds.JaxSimulator(f_jax, h_jax, dt, state_names, input_names, measurement_names, integrator='rk4')[source]¶
Bases:
objectOpen-loop forward simulator implemented in pure JAX.
Uses
jax.lax.scanover RK4 (or Euler) time steps so the simulation function is fully JAX-traceable. This makes the measurement trajectory Y differentiable with respect to the initial state x₀ viajax.jacfwd.- Parameters:
f_jax (callable) – Dynamics function
f_jax(x, u) -> x_dot.xanduare 1-Djnparrays; return value must also be ajnparray of shape(n,).h_jax (callable) – Measurement function
h_jax(x, u) -> y. Returns ajnparray of shape(p,).dt (float) – Integration time step (seconds).
state_names (list of str) – Names of state variables (length n).
input_names (list of str) – Names of input variables (length m).
measurement_names (list of str) – Names of measurement variables (length p).
integrator ({'rk4', 'euler'}) – Numerical integration scheme.
'rk4'is more accurate and recommended;'euler'is faster but first-order.
- simulate(x0, u_seq)[source]¶
Run the open-loop simulation.
- Parameters:
x0 (array-like or dict) – Initial state, shape
(n,)or dict mapping state name → value.u_seq (array-like or dict) – Input sequence, shape
(w, m)or dict mapping input name → array of lengthw.
- Returns:
y_traj – Measurement trajectory.
- Return type:
np.ndarray, shape (w, p)
- class pybounds.JaxEmpiricalObservabilityMatrix(jax_simulator, x0, u_seq, eps=None)[source]¶
Bases:
objectObservability matrix via JAX forward-mode autodiff.
Replaces the 2n numerical perturbation simulations used by
EmpiricalObservabilityMatrixwith a singlejax.jacfwdcall, giving the exact Jacobian dY/dx₀ in one forward pass.Output attributes match those of
EmpiricalObservabilityMatrixso this class can be used as a drop-in replacement.- Parameters:
jax_simulator (JaxSimulator) – A configured
JaxSimulatorinstance.x0 (array-like or dict) – Initial state, shape
(n,)or dict.u_seq (array-like or dict) – Input sequence, shape
(w, m)or dict.eps (float, optional) – Accepted for API compatibility but not used (the Jacobian is exact).
- class pybounds.JaxSlidingEmpiricalObservabilityMatrix(jax_simulator, t_sim, x_sim, u_sim, w)[source]¶
Bases:
objectSliding observability matrix computed via JAX vmap + jacfwd.
Batches all sliding windows into a single vmapped
jax.jacfwdcall, giving exact Jacobians for every window in one XLA kernel launch.Output attributes match those of
SlidingEmpiricalObservabilityMatrix(O_sliding,O_df_sliding,O_time,O_index,t_sim).- Parameters:
jax_simulator (JaxSimulator) – A configured
JaxSimulatorinstance.t_sim (array-like, shape (T,)) – Time vector for the trajectory.
x_sim (array-like or dict, shape (T, n)) – State trajectory.
u_sim (array-like or dict, shape (T, m)) – Input trajectory.
w (int) – Window size in time steps.