systems.base.utils.CodeGenerator
systems.base.utils.CodeGenerator(system)Orchestrates code generation and caching for a dynamical system.
Manages generation of numerical functions from symbolic expressions, with per-backend caching to avoid redundant compilation.
Example: >>> code_gen = CodeGenerator(system) >>> >>> # Generate dynamics function (with caching) >>> f_numpy = code_gen.generate_dynamics(‘numpy’) >>> f_numpy_again = code_gen.generate_dynamics(‘numpy’) # Returns cached >>> assert f_numpy is f_numpy_again >>> >>> # Compile all backends >>> timings = code_gen.compile_all(backends=[‘numpy’, ‘torch’, ‘jax’])
Methods
| Name | Description |
|---|---|
| compile_all | Pre-compile functions for multiple backends. |
| generate_dynamics | Generate f(x, u) function for specified backend. |
| generate_dynamics_jacobians | Generate A and B Jacobian functions. |
| generate_observation_jacobian | Generate C Jacobian function (∂h/∂x). |
| generate_output | Generate h(x) function for specified backend. |
| get_dynamics | Get cached dynamics function without generating. |
| get_info | Get comprehensive information about code generation status. |
| get_jacobians | Get cached Jacobian functions without generating. |
| get_output | Get cached output function without generating. |
| is_compiled | Check which functions are compiled for a backend. |
| reset_cache | Clear cached functions for specified backends. |
compile_all
systems.base.utils.CodeGenerator.compile_all(
backends=None,
include_jacobians=False,
verbose=False,
**kwargs,
)Pre-compile functions for multiple backends.
Useful for: - Reducing first-call latency - Validating code generation - Warming up JIT compilers (JAX)
Args: backends: List of backends to compile (None = all available) include_jacobians: Also compile Jacobian functions verbose: Print compilation progress **kwargs: Backend-specific options
Returns: Dict mapping backend → function_name → compilation_time
Example: >>> timings = code_gen.compile_all( … backends=[‘numpy’, ‘torch’], … include_jacobians=True, … verbose=True … ) Compiling numpy… f: 0.05s h: 0.03s A, B: 0.08s Compiling torch… f: 0.12s
generate_dynamics
systems.base.utils.CodeGenerator.generate_dynamics(backend, **kwargs)Generate f(x, u) function for specified backend.
Uses caching - if function already generated, returns cached version.
Args: backend: Target backend (‘numpy’, ‘torch’, ‘jax’) **kwargs: Backend-specific options (e.g., jit=True for JAX)
Returns: DynamicsFunction: (x, u) → dx/dt
Example: >>> f_numpy = code_gen.generate_dynamics(‘numpy’) >>> dx = f_numpy(x_vals, u_vals)
generate_dynamics_jacobians
systems.base.utils.CodeGenerator.generate_dynamics_jacobians(backend, **kwargs)Generate A and B Jacobian functions.
Args: backend: Target backend **kwargs: Backend-specific options
Returns: Tuple of (A_func, B_func) where: A_func: (x, u) → ∂f/∂x B_func: (x, u) → ∂f/∂u
Example: >>> A_func, B_func = code_gen.generate_dynamics_jacobians(‘numpy’) >>> A = A_func(x_vals, u_vals) >>> B = B_func(x_vals, u_vals)
generate_observation_jacobian
systems.base.utils.CodeGenerator.generate_observation_jacobian(
backend,
**kwargs,
)Generate C Jacobian function (∂h/∂x).
Returns None if no custom output function.
Args: backend: Target backend **kwargs: Backend-specific options
Returns: C_func: (x) → ∂h/∂x, or None if no custom output
generate_output
systems.base.utils.CodeGenerator.generate_output(backend, **kwargs)Generate h(x) function for specified backend.
Returns None if system has no custom output function (uses identity).
Args: backend: Target backend (‘numpy’, ‘torch’, ‘jax’) **kwargs: Backend-specific options
Returns: OutputFunction: (x) → y, or None if no custom output
Example: >>> h_numpy = code_gen.generate_output(‘numpy’) >>> if h_numpy is not None: >>> y = h_numpy(x_vals)
get_dynamics
systems.base.utils.CodeGenerator.get_dynamics(backend)Get cached dynamics function without generating.
Args: backend: Target backend
Returns: Cached function or None if not yet generated
get_info
systems.base.utils.CodeGenerator.get_info()Get comprehensive information about code generation status.
Returns: Dict with compilation status for all backends
Example: >>> info = code_gen.get_info() >>> print(info) { ‘numpy’: {‘f’: True, ‘h’: True, ‘A’: True, ‘B’: True, ‘C’: False}, ‘torch’: {‘f’: True, ‘h’: False, ‘A’: False, ‘B’: False, ‘C’: False}, ‘jax’: {‘f’: False, ‘h’: False, ‘A’: False, ‘B’: False, ‘C’: False} }
get_jacobians
systems.base.utils.CodeGenerator.get_jacobians(backend)Get cached Jacobian functions without generating.
Args: backend: Target backend
Returns: Tuple of (A_func, B_func, C_func) or None if not yet generated
get_output
systems.base.utils.CodeGenerator.get_output(backend)Get cached output function without generating.
Args: backend: Target backend
Returns: Cached function or None if not yet generated
is_compiled
systems.base.utils.CodeGenerator.is_compiled(backend)Check which functions are compiled for a backend.
Args: backend: Backend to check
Returns: Dict mapping function_name → is_compiled
Example: >>> status = code_gen.is_compiled(‘numpy’) >>> print(status) {‘f’: True, ‘h’: False, ‘A’: True, ‘B’: True, ‘C’: False}
reset_cache
systems.base.utils.CodeGenerator.reset_cache(backends=None)Clear cached functions for specified backends.
Useful when: - Changing devices (need recompilation) - Freeing memory - Debugging
Args: backends: List of backends to reset (None = all)
Example: >>> # Clear all caches >>> code_gen.reset_cache() >>> >>> # Clear only torch cache (e.g., after device change) >>> code_gen.reset_cache([‘torch’])