Metadata-Version: 2.4
Name: gds-symbolic
Version: 0.99.0
Summary: Symbolic math bridge for the GDS ecosystem — SymPy to ODE compilation
Project-URL: Homepage, https://github.com/BlockScience/gds-core
Project-URL: Repository, https://github.com/BlockScience/gds-core
Project-URL: Documentation, https://blockscience.github.io/gds-core
Author-email: Rohan Mehta <rohan@block.science>
License-Expression: Apache-2.0
Keywords: control-systems,gds-framework,generalized-dynamical-systems,symbolic-math,sympy
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: gds-domains[symbolic]>=0.1.0
Description-Content-Type: text/markdown

# gds-symbolic

Symbolic math bridge for the GDS ecosystem — compiles SymPy expressions
into plain Python callables for use with `gds-continuous`.

## Installation

```bash
uv add gds-symbolic[sympy]
```

## Quick Start

```python
from gds_control.dsl.elements import State, Input, Sensor, Controller
from gds_symbolic import SymbolicControlModel, StateEquation

model = SymbolicControlModel(
    name="damped_oscillator",
    states=[State(name="x"), State(name="v")],
    inputs=[Input(name="force")],
    sensors=[Sensor(name="position", observes=["x"])],
    controllers=[Controller(name="actuator", reads=["position", "force"], drives=["x", "v"])],
    state_equations=[
        StateEquation(state_name="x", expr_str="v"),
        StateEquation(state_name="v", expr_str="-k*x - c*v + force"),
    ],
    symbolic_params=["k", "c"],
)

# Compile to plain callable (no SymPy at runtime)
ode_fn, state_order = model.to_ode_function()

# Linearize at origin
lin = model.linearize(x0=[0.0, 0.0], u0=[0.0])
print(lin.A)  # [[0, 1], [-k, -c]] evaluated at operating point
```
