Capabilities
LawSynth is a Rust-first toolkit with Python and TypeScript SDKs. Every capability below is a real command in the lawsynth CLI, and most are mirrored by a function in the Python SDK. They all read and write the same .lsworld bundle.
The work falls into four pillars: Discover, Analyze, Control, and Share.
Discover
Recover governing equations from observations by sparse symbolic regression over a configurable feature library.
- Sparse regression — fit a compact law system with a choice of solver (
stlsq,sr3,frols,ssr, ortrapping), polynomial degree, and optional trigonometric or bounded-rational features.
$ lawsynth discover obs.csv --time t --state x,y --output world.lsworld --solver stlsq --pareto
- Regimes, Pareto, refinement, causality — add
--regimesto detect mode switches,--paretofor the accuracy/complexity frontier,--refineto jointly fit parameters, and--causalfor dependency hypotheses.
- Controlled discovery (SINDYc) — learn dynamics that include exogenous control inputs.
$ lawsynth control obs.csv --time t --state x,v --control u
- Network coupling — recover which variables drive which across a multivariate system.
$ lawsynth network obs.csv --state x1,x2,x3 --edge-threshold 0.1
- Cross-validated model selection — sweep degrees and thresholds under time-series cross-validation to choose a model that generalizes.
$ lawsynth select obs.csv --state x,y --degrees 2,3 --folds 5 --scheme rolling
Alternative discovery engines
When the strong (derivative) form struggles, switch engines — each recovers a different class of law:
- Weak / integral form — noise-robust discovery that never differentiates the data. Same command, one flag:
$ lawsynth discover obs.csv --time t --state x,y --method weak-form --output world.lsworld
- Koopman / DMD — a linear operator on the (lifted) state; reports discrete and continuous eigenvalues and their stability. Returns an operator, not a symbolic world.
$ lawsynth koopman obs.csv --time t --state x,y
- Stochastic (SDE) — recover drift
a(x)and diffusionb²(x)from a single noisy path via Kramers–Moyal moments (a statistical estimator: accuracy grows with path length).
$ lawsynth sde obs.csv --time t --state x --bins 40
- Partial differential equations (PDE-FIND) — recover an evolution law
u_t = F(u, u_x, u_xx, …)from a space–time field grid (finite-difference, so it wants a resolved grid).
$ lawsynth pde field.csv --dx 0.1 --dt 0.01
The same discovery flow from Python, through the Study façade:
import lawsynth
study = lawsynth.Study.from_csv("obs.csv", time="t", state=["x", "y"])
result = study.discover()
result.save("world.lsworld")
Analyze
Interrogate a discovered world — its structure, its long-run behavior, and how far to trust it.
- Stability — locate and classify fixed points over a bounded region:
lawsynth stability world.lsworld --box 0:5,0:5.
- Bifurcation — sweep a parameter and track how fixed points appear, merge, or lose stability:
lawsynth bifurcation world.lsworld --parameter mu --range 0:2 --box -3:3,-3:3.
- Sensitivity — measure how the trajectory responds to each parameter:
lawsynth sensitivity world.lsworld --parameters a,b.
- Lyapunov exponents — a chaos diagnostic; a positive leading exponent signals sensitive dependence:
lawsynth lyapunov world.lsworld --initial x=1,y=1,z=1.
- Invariants — search a bounded basis for conserved quantities:
lawsynth invariants world.lsworld --degree 2.
- Basins of attraction — map which initial conditions flow to which attractor:
lawsynth basins world.lsworld --box -2:2,-2:2.
- Uncertainty — bootstrap coefficient bounds at discovery time (
discover --bootstrap) and propagate them into forecast bands (forecast --confidence).
The analysis surface is mirrored in the SDK:
import lawsynth
fixed_points = lawsynth.stability("world.lsworld", box="0:5,0:5")
spectrum = lawsynth.lyapunov("world.lsworld", initial={"x": 1.0, "y": 1.0, "z": 1.0})
Control
Turn a world into something you can estimate, reduce, or steer.
- State estimation — design an observer by pole placement, or a Kalman filter:
lawsynth estimate world.lsworld --box -2:2,-2:2 --measure x --kalman.
- Balanced model reduction — approximate a higher-order world with a lower-order one:
lawsynth reduce world.lsworld --box -2:2,-2:2 --order 2.
- Model-predictive control — compute a control sequence that drives states to a setpoint:
lawsynth mpc world.lsworld --control u --setpoint x=1 --initial x=0.
- Discrete-time simulation — step a discrete-time world forward:
lawsynth simulate-discrete world.lsworld --initial x=1 --steps 100.
import lawsynth
plan = lawsynth.mpc("world.lsworld", control=["u"], setpoint={"x": 1.0}, initial={"x": 0.0})
Share
Explain, package, and hand off a world — no server, no external assets.
- Explain — a plain-language, structured account of each law, its dominant terms, and its assumptions:
lawsynth explain world.lsworld.
- Report — a self-contained HTML report with rendered equations, fit, and inline trajectory charts:
lawsynth report world.lsworld --output report.html.
- Forecast — run the world forward, with interventions and optional confidence bands:
lawsynth forecast world.lsworld --horizon 40.
- Export — emit runnable code and interchange formats:
lawsynth export world.lsworld --format python(alsoc,onnx,matlab,latex,json).
- Simplify — algebraically reduce a law system with an e-graph:
lawsynth simplify world.lsworld.
- Compare — diff two worlds or two scenarios:
lawsynth compare a.lsworld b.lsworld.
- Domain presets — inspect and self-validate curated textbook systems:
lawsynth domains run damped-oscillator.
Honest boundaries
LawSynth is built to be trusted, which means being explicit about what it does not claim:
- Discovery is a sparse fit to your data — a compact hypothesis, not proof of causality.
--causalproduces dependency *hypotheses*.
- Network coupling is correlational; an edge is not proof of mechanism.
- Lyapunov exponents are a time-averaged numerical estimate, not an analytic result.
- Invariants are found within a bounded basis, so the absence of a result is not proof none exist.
- Determinism is the guarantee: identical inputs, config, version, and binary produce a bit-identical world. See Why determinism.