prophys Documentation
A JAX-native, fully differentiable symbolic DSL for spatial probability and risk models.
prophys lets you describe an uncertainty structure with geometry, physics,
and probability distributions. It offers a symbolic Python DSL, and compiles models
into a jit/grad/vmap-able model with calibration, design optimization,
and a standardized export format. It is not a distribution library like
NumPyro or Distrax but rather sits in the layer above one, combining differentiable
geometry (distances to polygons, point sets, lines, 3D exclusion volumes,
voxel fields, unstructured meshes, directed networks), transformations,
differentiable discrete design decisions, and probabilistic attributes,
including directional climatologies like wind/wave roses, in a single
compiled graph.
prophys is proprietary software by RhineQC GmbH.
Distribution catalog. Gaussian, Weibull, Gamma, Beta, circular (VonMises), multivariate, mixtures, and Gaussian copulas — all differentiable. Browse the catalog →
A complete worked model. A gas-dispersion community health-risk model exercising every primitive family end to end. See the example →
Networks, discrete design, and cascades. A distribution-grid reinforcement model: directed-graph topology, differentiable binary reinforcement decisions, and a multi-hop fault cascade, jointly optimized against continuous substation siting. See the example →
One toolkit, many domains
prophys is not a physics package for one vertical — the same primitives that built the gas-dispersion example also built the electric-grid cascade, and compose just as directly into wake models, catastrophe pricing, or tail-risk layers. What the library actually offers is differentiability and joint calibration/optimization over geometry + physics + uncertainty, whatever the domain:
A plume surrogate over terrain Fields and Polygon zones,
wind as upstream RandomVariables, dose-response calibration,
abatement optimized under a compliance constraint.
A directed Network cascade where each line’s reinforcement is a
differentiable BinaryState — discrete topology decisions and
continuous substation siting optimized in one gradient pass.
DirectionalMixture couples sector weights, circular spread, and
per-sector intensity (e.g. Weibull wind speeds) — a calibratable
wind rose feeding turbine-siting or fatigue-load models.
Terrain rasters and portfolio Polygons under a
GaussianCopula coupling hazard marginals — spatially correlated
loss, differentiable end to end for pricing sensitivities.
Heavy-tailed severity (Gumbel, LogNormal, mixtures) with
quantile()/cvar() on any compiled attribute — attachment
points and layer structures tuned by gradient.
Solver outputs land in a Mesh (P1 barycentric) or voxel
Field3D and become differentiable model inputs — calibrate a
simulated stress or concentration field against point observations.
A Polyline’s route is a Param; a leak location is a
continuous, reparameterized draw along it via point_at —
siting and leak-exposure liability optimized jointly, not
approximated by a hand-picked grid of candidate leak points.
Symbolic graphs, frames, eval vs. opt mode, and Monte-Carlo marginalization explained.
Point, Line, Polygon, Polyhedron, Field, Grid, Network, Field3D, and Mesh — every differentiable geometry primitive.
Univariate, circular, multivariate, mixture, and copula distributions, with plots.
Linear, piecewise-linear, decay, logistic, and table-lookup transforms.
Fit parameters to observations and optimize design variables with Optax, entirely through gradients.
The standardized, consumer-agnostic ModelPackage interchange
format for a compiled model.
Minimal Working Example
import prophys as prp
import jax.numpy as jnp
site = prp.Frame("site")
houses = prp.PointList(jnp.array([[0.0, 0.0], [200.0, 0.0]]), site)
turbines = prp.PointList(prp.Param("pos", shape=(2, 2), init=jnp.array([[80.0, 80.0], [150.0, 20.0]])), site)
distance = houses.closest_distance(turbines, mode="opt", tau=2.0)
level = prp.Param("base", init=100.0) - 20 * prp.log10(distance)
acceptance = prp.UncertainAttribute("acceptance_drop", prp.Weibull(scale=1.0 + level, concentration=prp.Param("k", init=2.0)))
model = prp.ProbabilityModel(acceptance)
compiled = model.compile(mode="opt")
print(compiled.expectation("acceptance_drop"))
Where To Start
Installation: Installation
License and the free tier: License
Core concepts: Concepts
Geometry primitives: Structures
Distribution catalog (with plots): Distributions
Transformation catalog (with plots): Transformations
Calibration and design optimization: Training & Design Optimization
The gas-dispersion worked example: Example: Gas Dispersion & Community Health Risk
The electric-grid worked example: Example: Distribution-Grid Reinforcement
Standardized export format: Export Format
Full API reference: API Reference