Physics-Informed Equilibria, DAEs, and Residual Objectives
Physics can enter SILVA through the equilibrium transition, the training loss, an implicit time-step root, or an auxiliary residual objective. These choices are related but not interchangeable. This page develops a physics-informed deep equilibrium for ODEs [51], an implicit Runge-Kutta layer motivated by DAE-PINNs [52], and an optional adversarial equation-residual objective [53].
Construction Matrix
| Construction | Implicit unknown | Physics location | Public object |
|---|---|---|---|
| physics-informed equilibrium | latent representation | transition and ODE loss | SILVAPhysicsInformedEquilibrium |
| implicit DAE step | stage and endpoint variables | root equations | SILVAImplicitDAEStep |
| adversarial residual objective | none by itself | loss over equation residuals | silva_adversarial_residual_loss |
Only the first row is a deep-equilibrium family. The second is an implicit numerical layer. The third is a training objective.
Physics-Informed Deep Equilibrium
ODE initial-value problem
Given
define
Time is the SILVA source. The latent recurrence is the self-interaction. Spatial problems can add local or global field operators.
Implicit time derivative
Set
Differentiation gives
Therefore
and
implicit_time_derivative exposes three modes. dense forms the latent
Jacobian and solves the displayed system directly. matrix_free evaluates
\(\left(I-J_zf_\theta\right)v\) with JVPs and solves with GMRES. auto selects the dense
path only up to dense_derivative_threshold, then switches to the matrix-free
path. Both modes differentiate the same equation and avoid storing forward
solver iterations.
Three-term objective
The initial-condition term is
At collocation times, the physical residual is
The transition-Jacobian term is
Together,
The package estimates the Jacobian term with Hutchinson probes [6] [14]. It conditions the learned equilibrium and does not replace the ODE residual.
from silva_networks import (
SILVAPhysicsInformedEquilibrium,
SolverConfig,
make_linear_ivp_dataset,
)
data = make_linear_ivp_dataset(points=21, rate=-0.5)
model = SILVAPhysicsInformedEquilibrium(
state_dim=8,
output_dim=1,
config=SolverConfig(
solver="anderson",
max_iter=40,
tol=1e-6,
backward_mode="implicit",
backward_solver="gmres",
anderson_batch_dims=1,
),
)
terms = model.physics_loss(
data.times,
data.dynamics,
initial_time=data.times[:1],
initial_state=data.initial_state,
jacobian_weight=1e-3,
)
terms.total.backward()
print(terms.initial, terms.residual, terms.jacobian)
The ordinary prediction path uses SILVA's implicit adjoint. The physical time derivative uses the implicit-function formula above. Memory is independent of the number of forward iterations. Dense derivative memory grows with latent dimension; the matrix-free path replaces that matrix with repeated products and a separately controlled linear-solver tolerance.
Define the internal architecture
The built-in transition is
It is a compact default, not a restriction on the physics-informed family. A custom transition may contain residual MLPs, temporal convolutions, graph operators, Fourier operators, U-Nets, or coupled known/learned fields. It must implement
import torch
from torch import nn
from silva_networks import SILVAPhysicsInformedEquilibrium, SolverConfig
class ReactionDiffusionTransition(nn.Module):
time_dim = 1
state_dim = 64
def __init__(self):
super().__init__()
self.time_source = nn.Sequential(
nn.Linear(1, 64),
nn.Tanh(),
nn.Linear(64, 64),
)
self.learned_field = nn.Sequential(
nn.Linear(64, 128),
nn.GELU(),
nn.Linear(128, 64),
)
def forward(self, state, times):
source = self.time_source(times)
return torch.tanh(source + 0.15 * self.learned_field(state))
model = SILVAPhysicsInformedEquilibrium(
state_dim=64,
output_dim=2,
transition=ReactionDiffusionTransition(),
readout=nn.Linear(64, 2),
derivative_mode="matrix_free",
derivative_max_iter=100,
derivative_tol=1e-7,
config=SolverConfig(
solver="anderson",
max_iter=60,
tol=1e-7,
backward_mode="implicit",
backward_solver="gmres",
anderson_batch_dims=1,
),
)
The two callables have separate mathematical roles. For each sampled time \(t_i\), the transition and readout produce
implicit_time_derivative(times, state) differentiates that equilibrium to
obtain \(dD_\theta/dt\). The user-supplied
dynamics(times, prediction) callable evaluates the physical right-hand side
\(N(t_i,D_\theta(t_i))\) with the same shape as the prediction. Consequently,
physics_loss forms the pointwise ODE residual
The transition therefore defines how SILVA represents a trajectory, while
dynamics defines which differential equation that trajectory must satisfy.
Keeping these roles separate allows known physics, partially known physics,
and learned closure terms to be combined without hard-coding one differential
equation into the wrapper.
Verify a custom transition
For a scalar affine transition
the exact equilibrium and derivative are
Retain this manufactured case as a unit test for every derivative implementation. On small latent states, compare dense and matrix-free results; on larger states, report the GMRES residual and iteration count separately from the forward fixed-point residual and ODE residual.
Differential-Algebraic Equations
Semi-explicit form
An index-1 semi-explicit DAE has differential state \(y\) and algebraic state \(z\):
The algebraic state must satisfy the constraint at every time.
Implicit Runge-Kutta stages
For \(s\) stages with Butcher coefficients \(A=(a_{ji})\), \(b\), and \(c\),
for \(j=1,\ldots,s\). The endpoint is
Pack every unknown into
The stage equations define a square residual \(R(u)=0\). The package applies
This is an implicit SILVA layer because its output is defined by a root. It is not a globally weight-tied deep-equilibrium architecture. DAE-PINNs combine implicit Runge-Kutta structure with learned physics-informed surrogates [52]; SILVA exposes the stage root so known, learned, or hybrid dynamics can be supplied.
Backward Euler
For \(A=[1]\), \(b=[1]\), and \(c=[1]\),
from silva_networks import SILVAImplicitDAEStep, make_linear_dae_dataset
data = make_linear_dae_dataset(steps=10, step_size=0.1)
layer = SILVAImplicitDAEStep(max_iter=8, tol=1e-8)
result = layer(
data.differential[:1],
data.algebraic[:1],
data.step_size,
data.dynamics,
data.constraint,
)
print(result.differential, result.algebraic)
print(result.residual, result.converged)
The two-stage Gauss-Legendre method can be selected with
Report the tableau, step size, Newton damping, stage residual, endpoint constraint, and trajectory error. A low root residual proves only that the discrete equations were solved, not that the chosen discretization is accurate.
Adversarial Equation-Residual Objective
Naming collision
In the 2022 DEQGAN paper, “DEQ” means Differential Equation, not Deep Equilibrium [53]. The mechanism is therefore not registered as a SILVA equilibrium family. Its loss is exposed as an optional residual-training utility.
Losses
Let \(r_\theta\) be an equation residual and \(r_0\) a near-zero reference. A discriminator is trained with
The physical model is trained with
silva_adversarial_residual_loss returns the losses separately. The
discriminator term detaches the physical residual; the generator term retains
the gradient path to the physical model.
import torch
from silva_networks import (
SILVAResidualDiscriminator,
silva_adversarial_residual_loss,
)
residual = torch.randn(32, 2, requires_grad=True)
discriminator = SILVAResidualDiscriminator(2)
terms = silva_adversarial_residual_loss(
discriminator,
residual,
reference=torch.zeros_like(residual),
instance_noise=0.01,
)
print(terms.generator, terms.discriminator)
An adversarial objective does not guarantee a low pointwise residual, solved DAE root, or stable equilibrium. Report direct residuals alongside it.
Matrix-Free Scaling
For the physics-informed equilibrium, derivative_mode="matrix_free" solves
with the JVP operator
GMRES receives that operator without a dense latent Jacobian. The readout
derivative is another JVP [57].
derivative_mode="auto" retains a dense solve for modest states so the
matrix-free result can be checked against it before increasing width.
For DAE stages, linear_solver="gmres" applies Newton-Krylov to the packed
stage residual. Its matrix-vector product is
Increasing state dimension no longer requires a stored square Jacobian, but it does require reporting Krylov tolerance, iteration budget, Newton damping, stage residual, endpoint constraint, and step-size study. The full-scale notebook compares both matrix-free paths with their dense equations and differentiates through the physics solve.
Choosing a Construction
| Need | Use |
|---|---|
| one equilibrium representation over continuous time | physics-informed equilibrium |
| strict implicit stage constraints at each time step | implicit DAE layer |
| learned distributional penalty over equation residuals | adversarial residual objective |
| known PDE inside a graph fixed point | physics-guided graph equilibrium |
| positive Poisson inverse geometry | Burg mirror equilibrium |
Executable Labs
| Topic | Notebook |
|---|---|
| ODE equilibrium, implicit derivative, three-term loss | Physics-Informed Equilibrium |
| DAE stages, rollout, and residual objective | Implicit DAE and Residuals |
Backward Policy Is an Experimental Axis
The PIDEQ transition and physics objective do not force one backward method. For a task loss with equilibrium adjoint source \(g\), the exact route solves
JFB uses \(u\approx g\) [88].
SHINE initializes \(u\) from the limited-memory inverse accumulated by a Broyden
forward solve [89]. These choices
change the training gradient, while derivative_mode separately controls how
the physical time derivative is evaluated.
| Question | Exact implicit | JFB | SHINE |
|---|---|---|---|
| forward physical state | same declared equilibrium solve | same | Broyden root with reusable factors |
| parameter gradient | matrix-free adjoint solve | one final transition | shared inverse with optional refinement |
| physical derivative | dense or matrix-free IFT solve | unchanged | unchanged |
| evidence to report | forward and backward residuals | forward residual and gradient comparison | forward residual, inverse rank, refinement, gradient comparison |
from silva_networks import SolverConfig
exact = SolverConfig(backward_mode="implicit", backward_solver="gmres")
jfb = SolverConfig(backward_mode="jfb")
shine = SolverConfig(
solver="broyden",
backward_mode="shine",
shine_refine_steps=2,
)
Notebook 49 checks these gradients against an analytic equilibrium. Notebook 51 then applies JFB to a compact PIDEQ and keeps the transition, dynamics callable, and physics terms visibly separate.
Where to Go Next
| Question | Page |
|---|---|
| How are the analytic ODE and DAE batches generated? | Advanced Equilibrium Datasets |
| Which classes implement these equations? | Physics-Informed API |
| How do implicit ODE and PDE steps work generally? | Neural Operators, ODEs, PDEs, and SILVA |
| How are implicit gradients derived? | Mathematical Foundations |