SiNDAE targets hybrid differential-algebraic equation (DAE) systems (also called Universal Differential Equations or UDEs) in which one or more constitutive relations are replaced by a trainable neural network. The notation on this page follows Lueg et al. (2025).
Problem formulation¶
SiNDAE considers the semi-explicit neural DAE on a horizon :
The variables are the differential states , the algebraic variables and , and the independent static variables . The neural network
supplies the unknown terms from a chosen subset of the remaining variables, its inputs with . Domain knowledge defines this structural prior, that is, which variables enter . The maps and (and ) are assumed Lipschitz continuous on once and are fixed. The initial differential state may depend on ; if it is unknown it can be absorbed into .
In the SiNDAE API this maps onto a ProblemDefinition as follows: and
are the differential and algebraic constraints written in build_trajectory,
the network inputs are returned by get_input_vars, the network outputs
by get_output_vars, and is a SimpleMLP (or any compatible
module).
Differential index¶
Substituting the network relation into the other equations gives the algebraic constraint
For a given and , if is nonsingular for all , the DAE is index-1. Otherwise the index is the minimum number of differentiations of the algebraic constraints required to obtain ODEs for the algebraic variables , exactly as for conventional DAEs Biegler (2010). SiNDAE places no restriction on the index; the four-tank example is index-2.
Data and training objective¶
The training data come from a set of trajectories, or scenarios, . The network outputs are usually unobserved; instead we observe the variables that define the network input, which for the problems considered here are the differential states , sampled at times . Writing for the ground-truth trajectory of scenario , the observations are
with zero-mean Gaussian observation noise . The data-fit loss for a continuous state profile on scenario is
Training minimizes over the network parameters together with the state and algebraic trajectories, subject to the neural DAE above. SiNDAE solves this either jointly as a single NLP (the simultaneous approach) or with an outer loop over around inner DAE solves (the decomposition approach).
Collocation discretization¶
The continuous neural DAE is discretized with Lagrange-Radau collocation on a mesh of finite elements with collocation points each. This replaces the differential and algebraic constraints with a finite set of algebraic equations, turning the training problem into a finite-dimensional NLP. Following the paper, a discretized variable at collocation index on scenario is written .
Pyomo’s dae.collocation transformation performs the
symbolic discretization; ProblemDefinition.discretize calls it by default.
Defining your own problem¶
Subclass ProblemDefinition and implement three abstract methods. build_trajectory writes
and and fixes the initial conditions; get_input_vars returns
; get_output_vars returns .
from sindae.problem import ProblemDefinition
import pyomo.dae as dae
import pyomo.environ as pyo
class MyProblem(ProblemDefinition):
def build_trajectory(self, block, traj_idx):
"""Declare Pyomo Var, DerivativeVar, and constraints (no NN yet)."""
block.t = dae.ContinuousSet(bounds=self.t_span)
block.x = pyo.Var(block.t, range(2), initialize=1.0)
block.z = pyo.Var(block.t, range(1))
block.dxdt = dae.DerivativeVar(block.x, wrt=block.t)
@block.Constraint(block.t)
def ode(b, t):
return b.dxdt[t, 0] == -b.x[t, 0] + b.z[t, 0]
block.x[self.t_span[0], 0].fix(self.ics[traj_idx, 0])
def get_input_vars(self, block, t):
"""Network inputs v(t) at time t."""
return [block.x[t, j] for j in range(2)]
def get_output_vars(self, block, t):
"""Network outputs z(t) at time t."""
return [block.z[t, 0]]Optionally override:
| Method | Default | Purpose |
|---|---|---|
get_obs_vars | same as get_input_vars | Observed variables in the data-fit objective |
get_aux_vars | empty | Extra variables to record in InstanceData |
discretize | Radau collocation | Override for custom schemes |
add_true_output_constraints | NotImplementedError | True formula for , used only by generate_data |
See Problem Definition for the full API.
Smoother pre-step¶
Before training the network, SiNDAE solves a smoother NLP that:
Fits a smooth state profile to the noisy observations .
Produces initial values for and to warm-start the training NLP.
Computes the normalization statistics (mean and standard deviation) for the network inputs and outputs .
The smoother penalizes weighted by smooth_coef. A larger
smooth_coef yields smoother but potentially less data-faithful estimates.
See Smoother and sindae.algorithms.smoother.solve_smoother.
Built-in example problems¶
sindae.example_problems ships three benchmark systems:
| Class | System | DAE index |
|---|---|---|
FourTankProblem | Four-tank hydraulic network (4 differential, 5 algebraic, ) | 2 |
LeslieGowerProblem | Predator-prey ODE (2 differential, ) | ODE |
FedBatchBioreactorProblem | Fed-batch bioreactor with Monod kinetics (4 differential, ) | ODE |
- Lueg, L. R., Alves, V., Schicksnus, D., Kitchin, J. R., Laird, C. D., & Biegler, L. T. (2025). A simultaneous approach for training neural differential-algebraic systems of equations. arXiv Preprint arXiv:2504.04665. https://arxiv.org/abs/2504.04665
- Biegler, L. T. (2010). Nonlinear Programming: Concepts, Algorithms, and Applications to Chemical Processes.