Structures

Contents

Structures#

All structures are immutable, frame-annotated, and built on plain jax.numpy arrays internally — every method returns a symbolic Expr, so distances, areas, and interpolated values compose with the rest of the graph and stay differentiable. A singular form (Point, Line) is simply a batch-of-one of the plural form (PointList, LineList), sharing the same API.

Point / PointList#

class prophys.structures.PointList(coords, frame, registry=None)[source]#

An immutable collection of n points in frame, shape (n, ndim).

Coordinates may be a plain array (fixed data, such as house locations) or an Expr (such as a Param, so the points themselves, like turbine positions, can be optimized). Evaluating a PointList yields its coordinates. Points in another frame are aligned through the frame registry before any distance is computed. The distance primitives need 2D points, while 3D points serve as queries for Field3D.

Parameters:
  • coords (Any) – (n, ndim) coordinates, an array or an expression.

  • frame (Frame) – Coordinate frame of the points.

  • registry – Frame registry used for alignment, by default prophys.frames.default_registry.

Example:

site = prp.Frame("site")
houses = prp.PointList(np.array([[0.0, 0.0], [120.0, 40.0]]), site)
turbines = prp.PointList(prp.Param("xy", shape=(3, 2), init=xy0), site)
d = houses.closest_distance(turbines)  # shape (2,)
pairwise_distance(other)[source]#

Return the (n, m) matrix of Euclidean distances from these points to other’s points.

Parameters:

other (PointList)

Return type:

Expr

closest_distance(other, mode=None, tau=None)[source]#

Return, for each point, the distance to the closest point in other, shape (n,).

Exact minimum (native kernel with a BVH, O(n log m)) or a smooth softmin with temperature tau, chosen at evaluate time. Pass mode="eval" or mode="opt" to force a choice for this node, or leave both None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

farthest_distance(other, mode=None, tau=None)[source]#

Return, for each point, the distance to the farthest point in other, shape (n,).

Exact maximum in eval mode or a smooth softmax with temperature tau in opt mode. mode and tau follow the model’s compile(mode=, tau=) setting when left None (see closest_distance()).

Parameters:
Return type:

Expr

closest_point(other)[source]#

Return, for each point, the coordinates of the closest point in other, shape (n, ndim).

Uses a hard argmin, since indexing is discrete. Use closest_distance() in optimization objectives.

Parameters:

other (PointList)

Return type:

Expr

farthest_point(other)[source]#

Return, for each point, the coordinates of the farthest point in other, shape (n, ndim).

Uses a hard argmax, so it is not differentiable in the choice of point.

Parameters:

other (PointList)

Return type:

Expr

average_distance(other)[source]#

Return, for each point, the mean Euclidean distance to all points in other, shape (n,).

Parameters:

other (PointList)

Return type:

Expr

count_within(other, radius, mode=None, tau=None)[source]#

Return, for each point, how many of other’s points lie within radius, shape (n,).

An exact count in eval mode and, in opt mode, a sum of sigmoid indicators 1 / (1 + exp((d - radius) / w)) with a fixed width w = radius / 20 (the temperature tau is not used). mode follows the model’s compile(mode=, tau=) setting when left None (see closest_distance()).

Parameters:
Return type:

Expr

centroid()[source]#

Return the arithmetic mean of the points, shape (ndim,).

Return type:

Expr

class prophys.structures.Point(coords, frame, registry=None)[source]#

A single point, a PointList of length 1 with the same API.

Parameters:
  • coords (Any) – (ndim,) coordinates, an array or an expression.

  • frame (Frame) – Coordinate frame of the point.

  • registry – Frame registry used for alignment.

Line / LineList#

class prophys.structures.LineList(segments, frame, registry=None)[source]#

A set of m independent straight 2D segments in frame, such as roads or power lines.

segments has shape (m, 2, 2), the start and end point of each segment. For a connected, ordered route use Polyline.

Parameters:
  • segments (Any) – (m, 2, 2) segment end points, an array or an expression.

  • frame (Frame) – Coordinate frame of the segments.

  • registry – Frame registry used to align query points.

Example:

roads = prp.LineList(np.array([[[0, 0], [500, 0]], [[500, 0], [500, 300]]]), site)
d_road = roads.closest_distance(houses)  # shape (n,)
distance_matrix(points)[source]#

Return the (n, m) matrix of distances from each point to each segment.

Parameters:

points (PointList)

Return type:

Expr

closest_distance(points, mode=None, tau=None)[source]#

Return the distance from each point to the closest segment, shape (n,).

Exact minimum by a native kernel with a cached spatial index (O(n log m)), or a smooth softmin with temperature tau over the dense distance matrix, chosen at evaluate time. Pass mode="eval" or mode="opt" to force a choice for this node, or leave both None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

length()[source]#

Return the total length of all segments, shape ().

Return type:

Expr

class prophys.structures.Line(start, end, frame, registry=None)[source]#

A single straight segment, a LineList of length 1 with the same API.

Parameters:
  • start (Any) – (2,) start point.

  • end (Any) – (2,) end point.

  • frame (Frame) – Coordinate frame of the segment.

  • registry – Frame registry used to align query points.

Polyline#

An ordered, connected vertex chain — a route — as opposed to LineList’s unordered bag of independent segments. Its distinguishing capability is point_at(): a differentiable position at any fractional arc length along the whole chain, gradient flowing to the route’s own vertex coordinates. This is the primitive for “a failure can occur anywhere along this route” models — a pipeline leak, a cable fault, a road-defect location — where the failure location itself should be a continuous, reparameterized RandomVariable rather than a hand-picked set of candidate points:

import jax
import jax.numpy as jnp
import prophys as prp

site = prp.Frame("site", units="m")
route = prp.Polyline(prp.Param("route", shape=(4, 2), init=initial_vertices), site)

def expected_exposure(leak_key, receivers, wind_speed, wind_direction):
    leak_point = route.point_at(jax.random.uniform(leak_key, ()))
    # ... a plume/dispersion surrogate from leak_point to receivers,
    # exactly as in the gas-dispersion example, marginalized over the
    # wind climatology and now also over the leak's own location.

Design optimization can then move the route’s vertices — via prp.optimize — to jointly minimize expected exposure and routing cost, with the uncertainty over where a leak occurs built into the objective rather than assumed away.

class prophys.structures.Polyline(vertices, frame, registry=None)[source]#

An ordered, connected route of v vertices in frame, with positions by arc length.

vertices may be a Param, so the route itself can be optimized (such as a pipeline’s siting). Unlike LineList (an unordered set of m independent segments), a Polyline is a single connected route: consecutive vertices are joined into segments, and point_at gives a differentiable position anywhere along the whole chain, parameterized by fractional arc length rather than a discrete segment index. point_at works in any dimension, while length and as_lines need 2D vertices.

Parameters:
  • vertices (Any) – (v, ndim) route vertices in order, an array or an expression.

  • frame (Frame) – Coordinate frame of the route.

  • registry – Frame registry used to align query points.

Example:

pipeline = prp.Polyline(np.array([[0, 0], [300, 50], [600, 40]]), site)
leak_xy = pipeline.point_at(prp.RandomVariable("leak_s", prp.Uniform(0.0, 1.0)))
point_at(t)[source]#

Return the position at fractional arc length t along the route, shape (*t.shape, ndim).

t may have any shape and is clamped to [0, 1], with 0 and 1 the first and last vertex. Differentiable in both the route’s vertex coordinates and t, so the location along the route can be a continuous, reparameterized RandomVariable (Uniform(0, 1) pushed through point_at) rather than a discrete set of candidate locations picked by hand.

Parameters:

t (Any)

Return type:

Expr

length()[source]#

Return the total arc length of the route, shape ().

Return type:

Expr

as_lines()[source]#

Return the route’s consecutive vertex pairs as a LineList of segments (v - 1, 2, ndim).

Every segment primitive (closest_distance, distance_matrix, …) then works directly on the route geometry, such as the distance from a receptor to the nearest point on the pipeline.

Return type:

LineList

sample_points(key, shape=())[source]#

Draw uniformly random locations along the route, shape (*shape, ndim).

Reparameterized: u ~ Uniform(0, 1) pushed through point_at(). Differentiable in the route’s vertex coordinates, like any other distribution’s sample.

Parameters:
Return type:

Expr

Ray / RayList#

A half-infinite line {origin + t * direction : t >= 0} — line-of-sight, sensor exposure, and directional risk (e.g. distance to the nearest hazard along a fixed bearing).

class prophys.structures.RayList(origins, directions, frame, registry=None)[source]#

A set of m half infinite rays origin + t * direction, t >= 0 in frame.

Parameters:
  • origins (Any) – (m, d) ray origins.

  • directions (Any) – (m, d) ray directions (need not be normalized).

  • frame (Frame) – Coordinate frame of the rays.

  • registry – Frame registry used to align query points.

distance_matrix(points)[source]#

Return the (n, m) matrix of distances from each point to each ray.

Parameters:

points (PointList)

Return type:

Expr

closest_distance(points, mode=None, tau=None)[source]#

Return the distance from each point to the closest ray, shape (n,).

Hard min or smooth softmin with temperature tau over the dense distance matrix, chosen at evaluate time. Pass mode="eval" or mode="opt" to force a choice for this node, or leave both None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

point_at(t)[source]#

Return the position origin + t * unit_direction along each ray, shape (m, d).

t is a distance along the ray (negative values are clamped to 0), broadcastable to (m,).

Parameters:

t (Any)

Return type:

Expr

class prophys.structures.Ray(origin, direction, frame, registry=None)[source]#

A single half infinite ray, a RayList of length 1 with the same API.

Parameters:
  • origin (Any) – (d,) ray origin.

  • direction (Any) – (d,) ray direction (need not be normalized).

  • frame (Frame) – Coordinate frame of the ray.

  • registry – Frame registry used to align query points.

Ellipse / EllipseList#

A rotatable ellipse. Signed distance is an approximation (there is no closed form for a general ellipse) — exact for a circle, and accurate enough for containment checks and optimization elsewhere.

class prophys.structures.Ellipse(center, semi_axes, frame, angle=0.0, registry=None)[source]#

A single rotatable ellipse in frame, with exact signed distance.

center has shape (2,), semi_axes has shape (2,) = (a, b), and angle is the rotation in radians (0 puts the a axis along the frame’s x axis). All three may be Expr (such as Param), so an ellipse’s shape and pose can be learned or optimized.

Parameters:
  • center (Any) – (2,) center coordinates.

  • semi_axes (Any) – (2,) semi axis lengths (a, b).

  • frame (Frame) – Coordinate frame of the ellipse.

  • angle (Any) – Counterclockwise rotation of the a axis from the x axis, in radians.

  • registry – Frame registry used to align query points.

Example:

plume = prp.Ellipse(center=[50.0, 20.0], semi_axes=[80.0, 25.0], frame=site, angle=0.3)
exposed = plume.contains(houses)
signed_distance(points)[source]#

Return the exact signed distance of each point to the boundary, negative inside, shape (n,).

Parameters:

points (PointList)

Return type:

Expr

distance(points)[source]#

Return the distance of each point to the ellipse, 0 for points inside, shape (n,).

Parameters:

points (PointList)

Return type:

Expr

contains(points, tau=None)[source]#

Return a containment indicator for each point, hard 0/1 or smooth in [0, 1], shape (n,).

The smooth indicator is sigmoid(-signed_distance / tau). Pass an explicit tau (0 or negative means hard, positive means smooth with that temperature, in length units) to force a choice for this node, or leave tau=None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

area()[source]#

Return the area pi * a * b, shape ().

Return type:

Expr

perimeter()[source]#

Return the perimeter by Ramanujan’s second approximation, shape ().

Exact for a circle, with a relative error below 1e-9 for axis ratios down to about 0.5, growing to about 4e-4 as the ellipse degenerates to a segment. Differentiable without special functions.

Return type:

Expr

point_at(t)[source]#

Return the boundary position at angle parameter t, shape (*t.shape, 2).

t may have any shape. t=0 and t=1 give the +a end of the a semi axis (before rotation), and t advances counterclockwise around the full ellipse as it goes from 0 to 1. Closed form: center + R(angle) @ diag(a, b) @ (cos(2*pi*t), sin(2*pi*t)), differentiable in all arguments.

This is an angle parameterization, not the arc length one of Polyline.point_at and Polygon.point_at: the arc length of an ellipse is an elliptic integral of the parametric angle, so equal steps in t are not equal steps in boundary distance unless a == b. Where sampling uniformly by arc length matters, approximate the ellipse with a Polygon and use its point_at.

Parameters:

t (Any)

Return type:

Expr

class prophys.structures.EllipseList(centers, semi_axes, angles, frame, registry=None)[source]#

A collection of k rotatable ellipses in frame.

Parameters:
  • centers (Any) – (k, 2) center coordinates.

  • semi_axes (Any) – (k, 2) semi axis lengths.

  • angles (Any) – (k,) rotations in radians.

  • frame (Frame) – Coordinate frame of the ellipses.

  • registry – Frame registry used to align query points.

signed_distance(points)[source]#

Return the exact signed distance from each point to each ellipse, negative inside, shape (n, k).

Parameters:

points (PointList)

Return type:

Expr

closest_distance(points)[source]#

Return the distance from each point to the closest ellipse (0 inside any), shape (n,).

Parameters:

points (PointList)

Return type:

Expr

area()[source]#

Return the area of each ellipse, shape (k,).

Return type:

Expr

Polygon / PolygonList#

class prophys.structures.Polygon(vertices, frame, registry=None)[source]#

A single closed polygon (no holes) in frame.

vertices has shape (v, 2) with at least 3 vertices. The ring is implicitly closed (the last vertex connects back to the first). Vertices may be an expression, so the outline can be optimized or made uncertain.

Parameters:
  • vertices (Any) – (v, 2) ring vertices, an array or an expression.

  • frame (Frame) – Coordinate frame of the polygon.

  • registry – Frame registry used to align query points.

Example:

zone = prp.Polygon(np.array([[0, 0], [200, 0], [200, 100], [0, 100]]), site)
inside = zone.contains(receptors)  # hard 0/1 or smooth, per compile mode
signed_distance(points)[source]#

Return the signed distance of each point to the boundary, negative inside, shape (n,).

Computed by a native kernel: the magnitude from the nearest edge found through a BVH, the sign from the crossing number over all edges. Gradients flow through the nearest boundary point.

Parameters:

points (PointList)

Return type:

Expr

distance(points)[source]#

Return the distance of each point to the polygon, 0 for points inside, shape (n,).

Parameters:

points (PointList)

Return type:

Expr

contains(points, tau=None)[source]#

Return a containment indicator for each point, hard 0/1 or smooth in [0, 1], shape (n,).

The smooth indicator is sigmoid(-signed_distance / tau). Pass an explicit tau (0 or negative means hard, positive means smooth with that temperature, in length units) to force a choice for this node, or leave tau=None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

area()[source]#

Return the enclosed area (positive for either vertex orientation), shape ().

Return type:

Expr

perimeter()[source]#

Return the length of the closed boundary ring, shape ().

Return type:

Expr

centroid()[source]#

Return the mean of the vertices, shape (2,).

This is the vertex average, which in general differs from the area centroid of an irregular polygon.

Return type:

Expr

point_at(t)[source]#

Return the position at fractional arc length t around the closed perimeter, shape (*t.shape, 2).

t may have any shape and is clamped to [0, 1]. This is the same arc length parameterization as Polyline.point_at, with the ring wrapping from the last vertex back to the first. Differentiable in both the polygon’s vertex coordinates and t.

Parameters:

t (Any)

Return type:

Expr

class prophys.structures.PolygonList(vertices, frame, registry=None)[source]#

A collection of k polygons in frame that share the same vertex count v.

Pad or repeat vertices to bring irregular polygons to a common count.

Parameters:
  • vertices (Any) – (k, v, 2) ring vertices, an array or an expression.

  • frame (Frame) – Coordinate frame of the polygons.

  • registry – Frame registry used to align query points.

signed_distance(points)[source]#

Return the signed distance from each point to each polygon, negative inside, shape (n, k).

Parameters:

points (PointList)

Return type:

Expr

closest_distance(points)[source]#

Return the distance from each point to the closest polygon (0 inside any), shape (n,).

Parameters:

points (PointList)

Return type:

Expr

Polyhedron / PolyhedronList#

3D convex bodies given by a halfspace representation \(\{x : Ax \le b\}\). Used, e.g., for underground storage-tank exclusion volumes.

class prophys.structures.Polyhedron(A, b, frame, registry=None)[source]#

A single convex 3D polyhedron given by halfspaces A x <= b.

A has shape (m, 3) and b has shape (m,). Both may be expressions, so the body can be optimized.

Parameters:
  • A (Any) – (m, 3) outward face normals.

  • b (Any) – (m,) face offsets.

  • frame (Frame) – Coordinate frame (ndim=3).

  • registry – Frame registry used to align query points.

Example:

box = prp.Polyhedron(np.vstack([np.eye(3), -np.eye(3)]), np.ones(6), frame=site3d)
inside = box.contains(points3d)
signed_distance(points, mode=None, tau=None)[source]#

Return the signed distance of each point to the body, negative inside, shape (n,).

The eval branch is the largest normalized face slack max_i (a_i . x - b_i) / |a_i|, which is exact inside and underestimates the distance outside near edges and corners. The opt branch replaces the max by a smooth maximum (log sum exp) with temperature tau. Pass mode="eval" or mode="opt" to force a choice for this node, or leave both None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

contains(points, tau=None)[source]#

Return a containment indicator for each point, hard 0/1 or smooth in [0, 1], shape (n,).

The smooth indicator is sigmoid(-signed_distance / tau). Pass an explicit tau (0 or negative means hard, positive means smooth with that temperature) to force a choice for this node and for the underlying signed_distance, or leave tau=None (the default) to follow the model’s compile(mode=, tau=) setting.

Parameters:
Return type:

Expr

volume(samples=None, key=None)[source]#

Return the volume of the polyhedron, shape ().

By default the exact volume: every face is clipped against the other halfspaces and the volume follows from the divergence theorem, with closed form gradients with respect to A and b (dV/db_i is the area of face i over |a_i|). Unbounded polyhedra have infinite volume and empty ones have zero.

Passing samples selects a Monte Carlo estimate instead: containment, smoothed by a tight fixed sigmoid, of samples uniform points in the cube [-8, 8]^3 drawn with key (PRNGKey(0) by default), so the body must lie inside that cube. It is approximate and kept only for comparison.

Parameters:
  • samples (int | None)

  • key (Any)

Return type:

Expr

class prophys.structures.PolyhedronList(A, b, frame, registry=None)[source]#

A collection of k convex polyhedra that share the same face count m.

Parameters:
  • A (Any) – (k, m, 3) outward face normals.

  • b (Any) – (k, m) face offsets.

  • frame (Frame) – Coordinate frame (ndim=3).

  • registry – Frame registry used to align query points.

closest_distance(points, tau=1.0)[source]#

Return the distance from each point to the closest polyhedron (0 inside any), shape (n,).

Distances use the face slack of Polyhedron.signed_distance() with a smooth maximum at temperature tau, or the hard maximum for tau=0.

Parameters:
Return type:

Expr

Field#

A raster (scalar or vector) defined on a regular grid in a frame, with differentiable bilinear interpolation at arbitrary query points, computed by an optimized native kernel with exact gradients with respect to the values and the query positions.

A 15 by 15 raster and its bilinear interpolant A 15 by 15 raster and its bilinear interpolant

A 15 by 15 raster, for example exported from a solver, and the same field read by Field.interp at dense query points.

class prophys.structures.Field(values, frame, origin=(0.0, 0.0), cell=1.0, registry=None)[source]#

A scalar or vector raster on a regular 2D grid in frame, with bilinear interpolation.

values has shape (ny, nx) for a scalar field or (ny, nx, c) for a vector field (such as wind u, v components with c=2). origin is the world coordinate (x, y) of the value at index (0, 0) and cell the grid spacing (scalar or (dx, dy)). Rows advance along the frame’s second axis (y) and columns along the first (x), matching the image array convention. The values may be an expression, such as a Param raster to calibrate.

Parameters:
  • values (Any) – (ny, nx) or (ny, nx, c) grid values.

  • frame (Frame) – Coordinate frame of the raster.

  • origin (tuple[float, float]) – World coordinate (x, y) of the value at index (0, 0).

  • cell (float | tuple[float, float]) – Grid spacing, a scalar or (dx, dy).

  • registry – Frame registry used to align query points.

Example:

terrain = prp.Field(elevation, site, origin=(0.0, 0.0), cell=25.0)
z = terrain.interp(houses)  # shape (n,)
interp(points)[source]#

Bilinearly interpolate the field at points.

Queries outside the raster clamp to its edge cells. Differentiable in both the field values and the point coordinates.

Returns:

Shape (n,) for scalar fields, (n, c) for vector fields.

Parameters:

points (PointList)

Return type:

Expr

gradient()[source]#

Return the spatial gradient of a scalar field by finite differences, as a Field with 2 channels.

The channels are (d/dy, d/dx) on the same grid, with central differences inside and one sided differences at the edges.

Return type:

Field

mean()[source]#

Return the mean over all cells (and channels), shape ().

Return type:

Expr

min(tau=0.0)[source]#

Return the minimum over all cells, exact for tau <= 0 or a smooth softmin with temperature tau.

Parameters:

tau (float)

Return type:

Expr

max(tau=0.0)[source]#

Return the maximum over all cells, exact for tau <= 0 or a smooth softmax with temperature tau.

Parameters:

tau (float)

Return type:

Expr

Grid#

A fixed rectangular candidate domain — not itself part of the probabilistic model, but the standard way to evaluate an expression densely for a risk-map plot or a design search.

Risk map evaluated on a Grid in the gas dispersion example Risk map evaluated on a Grid in the gas dispersion example

A risk map evaluated on a Grid in the pipeline-leak example (:doc:`examples/gas_dispersion`).

class prophys.structures.Grid(frame, x_range, y_range, nx, ny)[source]#

A regular 2D grid of candidate or evaluation points in frame.

Not itself an Expr (it is a fixed geometric domain, not part of the probabilistic model), but positions() returns a PointList that can be fed into any structure or primitive.

Parameters:
  • frame (Frame) – Coordinate frame of the grid.

  • x_range (tuple[float, float]) – (min, max) extent along x, endpoints included.

  • y_range (tuple[float, float]) – (min, max) extent along y, endpoints included.

  • nx (int) – Number of points along x.

  • ny (int) – Number of points along y.

Example:

grid = prp.Grid(site, (0.0, 1000.0), (0.0, 600.0), nx=16, ny=15)
d = grid.positions().closest_distance(turbines).evaluate()  # (ny * nx,)
d_map = d.reshape(grid.shape())                             # (ny, nx)
positions()[source]#

Return all ny * nx grid points as a PointList, row by row with x varying fastest.

Return type:

PointList

shape()[source]#

Return the grid shape (ny, nx), for reshaping values evaluated at positions().

Return type:

tuple[int, int]

mask(polygon)[source]#

Return a (ny, nx) mask of the grid points that fall inside polygon.

The mask is evaluated immediately with the default (hard) containment, so it holds 0 or 1 values.

Return type:

Array

Network#

A directed graph in a shared frame: nodes are a PointList (coordinates may be a Param, so siting is optimizable), edges are a fixed (m, 2) connectivity array, and each edge carries an optional transmission weight — any expression, commonly a BinaryState when whether a link is reinforced, open, or online is itself a design decision. Network models supply chains, power grids, and pipeline networks where risk cascades along edges: edge_lengths() gives per-edge distances (cable/pipe cost), as_lines() exposes the edges as a LineList for proximity queries (e.g. distance from a house to the nearest line), and propagate() runs a differentiable multi-hop cascade of a per-node signal (a fault, a contamination front, a load spike) along the directed edges, decaying or amplifying at each hop according to the edge weights.

class prophys.structures.Network(nodes, edges, frame, weights=None, registry=None)[source]#

A directed graph embedded in frame, with optional transmission weights on its edges.

nodes is a PointList or raw (n, ndim) coordinates, which may be a Param so node positions can be optimized. edges is a fixed (m, 2) integer array of (src, dst) node indices, since connectivity is structure, not a differentiable quantity. weights is an optional (m,) transmission factor per edge (any Expr, such as a Param or a vector of BinaryState instances stacked with prophys.stack()), 1 on every edge by default.

Evaluating a Network yields its node coordinates, so it nests inside other expressions like a PointList does.

Parameters:
  • nodes (Any) – A PointList (which supplies its own frame) or (n, ndim) node coordinates.

  • edges (Any) – (m, 2) integer (src, dst) node indices.

  • frame (Frame) – Coordinate frame (ignored when nodes is a PointList).

  • weights (Any) – Optional (m,) transmission factors, one per edge.

  • registry – Frame registry used to align query points.

Raises:

ValueError – If edges is not (m, 2).

Example:

w = prp.Param("w", shape=(3,), init=jnp.full(3, 0.8), bounds=(0.0, 1.0))
net = prp.Network(substations, edges=[[0, 1], [1, 2], [1, 3]], frame=site, weights=w)
load = net.propagate(source=jnp.array([1.0, 0.0, 0.0, 0.0]), steps=3)
property n_nodes: int#

Number of nodes referenced by the edges (largest edge index + 1).

edge_lengths()[source]#

Return the Euclidean length of each edge, shape (m,), differentiable in the node coordinates.

Return type:

Expr

total_length()[source]#

Return the total edge length (such as cable or pipe cost), shape ().

Return type:

Expr

as_lines()[source]#

Return the edges as a LineList of segments (m, 2, ndim).

Every segment primitive (closest_distance, distance_matrix, …) then works on the network geometry, such as the distance from houses to the nearest power line.

Return type:

LineList

propagate(source, steps=1, weights=None)[source]#

Cascade a signal on the nodes along the directed edges and return the accumulated signal.

Propagates source (shape (n,)) for steps hops and returns sum_{k=0..steps} (M_w)^k source, shape (n,), where M_w[dst, src] = w_e for each edge e. The k=0 term is the source itself. weights overrides the network’s own edge weights.

Each hop multiplies by the transmission weight of the edge, so a failure, load or contamination signal decays (w < 1) or amplifies (w > 1) as it travels. Differentiable in both source and the weights. With BinaryState weights the cascade topology itself becomes a design variable.

Parameters:
Return type:

Expr

in_strength(weights=None)[source]#

Return the weighted in degree of each node, shape (n_nodes,).

This is the signal each node receives in one hop when every node emits a unit source.

Parameters:

weights (Any)

Return type:

Expr

Field3D / Grid3#

The volumetric counterparts of Field/Grid: a voxel raster on a regular 3D grid with differentiable trilinear interpolation, and a dense 3D evaluation lattice. Used for subsurface property fields, 3D concentration plumes, and atmospheric or thermal gradients where a single 2D slice isn’t enough.

class prophys.structures.Field3D(values, frame, origin=(0.0, 0.0, 0.0), cell=1.0, registry=None)[source]#

A scalar or vector voxel raster on a regular 3D grid in frame, with trilinear interpolation.

values has shape (nz, ny, nx) for a scalar field or (nz, ny, nx, c) for a vector field (such as a 3D flow with c=3). origin is the world coordinate (x, y, z) of voxel (0, 0, 0) and cell the voxel size (scalar or (dx, dy, dz)). The axis convention matches Field: the last array axis is x, then y, then z.

Parameters:
  • values (Any) – (nz, ny, nx) or (nz, ny, nx, c) voxel values.

  • frame (Frame) – Coordinate frame of the raster (ndim=3).

  • origin (tuple[float, float, float]) – World coordinate (x, y, z) of voxel (0, 0, 0).

  • cell (float | tuple[float, float, float]) – Voxel size, a scalar or (dx, dy, dz).

  • registry – Frame registry used to align query points.

interp(points)[source]#

Trilinearly interpolate the field at points, a PointList of 3D coordinates.

Queries outside the raster clamp to its edge voxels.

Returns:

Shape (n,) for scalar fields, (n, c) for vector fields.

Parameters:

points (PointList)

Return type:

Expr

mean()[source]#

Return the mean over all voxels (and channels), shape ().

Return type:

Expr

min(tau=0.0)[source]#

Return the minimum over all voxels, exact for tau <= 0 or a smooth softmin with temperature tau.

Parameters:

tau (float)

Return type:

Expr

max(tau=0.0)[source]#

Return the maximum over all voxels, exact for tau <= 0 or a smooth softmax with temperature tau.

Parameters:

tau (float)

Return type:

Expr

class prophys.structures.Grid3(frame, x_range, y_range, z_range, nx, ny, nz)[source]#

A regular 3D lattice of evaluation positions in frame.

The volumetric counterpart of Grid, for sampling a Field3D densely or defining a 3D lattice of design candidates. Not itself an Expr.

Parameters:
  • frame (Frame) – Coordinate frame (ndim=3).

  • x_range (tuple[float, float]) – (min, max) extent along x, endpoints included.

  • y_range (tuple[float, float]) – (min, max) extent along y, endpoints included.

  • z_range (tuple[float, float]) – (min, max) extent along z, endpoints included.

  • nx (int) – Number of positions along x.

  • ny (int) – Number of positions along y.

  • nz (int) – Number of positions along z.

positions()[source]#

Return all nz * ny * nx lattice positions as a PointList, x varying fastest.

Return type:

PointList

shape()[source]#

Return the lattice shape (nz, ny, nx), for reshaping values evaluated at positions().

Return type:

tuple[int, int, int]

Mesh#

An unstructured triangular mesh carrying a per-vertex scalar field, with differentiable barycentric (P1 finite-element) interpolation — the ingestion point for FEM/CFD solver outputs (stress, pressure, concentration) into a prophys graph. The mesh connectivity and vertex positions are fixed structure; the field values (and query points) stay differentiable, so a mesh-sampled physics surrogate can be calibrated against observations exactly like any other attribute.

class prophys.structures.Mesh(vertices, triangles, values, frame, registry=None)[source]#

A fixed 2D triangulation in frame carrying a scalar field at its vertices, with P1 interpolation.

vertices is a fixed (v, 2) coordinate array and triangles a fixed (t, 3) integer connectivity array: the mesh is structure. values is the (v,) field at the vertices and may be any Expr (a Param makes the field itself calibratable against point observations). Interpolation is piecewise linear (the FEM P1 basis): exact at vertices, linear inside each triangle, and linearly extrapolated outside the mesh from the triangle the point is least outside of, so gradients stay defined everywhere.

Parameters:
  • vertices (Any) – (v, 2) vertex coordinates.

  • triangles (Any) – (t, 3) vertex indices of each triangle.

  • values (Any) – (v,) field values at the vertices, an array or an expression.

  • frame (Frame) – Coordinate frame of the mesh.

  • registry – Frame registry used to align query points.

Raises:

ValueError – If vertices is not (v, 2) or triangles is not (t, 3).

interp(points)[source]#

Interpolate the vertex field at points barycentrically, shape (n,).

Differentiable in the field values and the query points (with a constant spatial gradient inside each triangle).

Parameters:

points (PointList)

Return type:

Expr

area()[source]#

Return the total mesh area as a plain array (the mesh geometry is fixed, so this is not an Expr).

Return type:

Array

integral()[source]#

Return the integral of the piecewise linear field over the mesh, shape ().

Computed as the sum over triangles of area times mean vertex value, which is exact for the P1 field. Differentiable in the values.

Return type:

Expr