anypinn.problems.ode
ODE constraint types, properties, and the ODEInverseProblem convenience class.
PredictDataFn: TypeAlias = Callable[[Tensor, FieldsRegistry, ParamsRegistry], Tensor]
module-attribute
DataConstraint
Bases: Constraint
Constraint enforcing fit to observed data.
Minimizes ||y_hat - y||^2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fields
|
FieldsRegistry
|
Fields registry. |
required |
params
|
ParamsRegistry
|
Parameters registry. |
required |
predict_data
|
PredictDataFn
|
Function to predict data values from fields. |
required |
weight
|
float
|
Weight for this loss term. |
1.0
|
Source code in src/anypinn/problems/ode.py
fields = fields
instance-attribute
params = params
instance-attribute
predict_data = predict_data
instance-attribute
weight = weight
instance-attribute
__init__(fields: FieldsRegistry, params: ParamsRegistry, predict_data: PredictDataFn, weight: float = 1.0)
Source code in src/anypinn/problems/ode.py
loss(batch: TrainingBatch, criterion: nn.Module, log: LogFn | None = None) -> Tensor
Compute the data-fitting loss.
Source code in src/anypinn/problems/ode.py
ICConstraint
Bases: Constraint
Constraint enforcing Initial Conditions (IC).
Minimizes ||y(t0) - Y0||^2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fields
|
FieldsRegistry
|
Fields registry. |
required |
weight
|
float
|
Weight for this loss term. |
1.0
|
Source code in src/anypinn/problems/ode.py
Y0 = props.y0.clone().reshape(-1, 1, 1)
instance-attribute
dY0 = [(dy.clone().reshape(-1, 1, 1)) for dy in (props.dy0)]
instance-attribute
fields = fields
instance-attribute
order = props.order
instance-attribute
weight = weight
instance-attribute
__init__(props: ODEProperties, fields: FieldsRegistry, weight: float = 1.0)
Source code in src/anypinn/problems/ode.py
inject_context(context: InferredContext) -> None
Inject the context into the constraint.
loss(batch: TrainingBatch, criterion: nn.Module, log: LogFn | None = None) -> Tensor
Compute the initial-condition loss.
Source code in src/anypinn/problems/ode.py
ODECallable
Bases: Protocol
Protocol for ODE right-hand side callables.
First-order callables (ODEProperties.order == 1) receive three
positional arguments and must match this Protocol exactly::
def my_ode(x: Tensor, y: Tensor, args: ArgsRegistry) -> Tensor: ...
Higher-order callables (order >= 2) receive a fourth positional
argument derivs: list[Tensor], where derivs[k] is the
(k+1)-th derivative of all fields stacked as (n_fields, m, 1)::
def my_ode(x: Tensor, y: Tensor, args: ArgsRegistry,
derivs: list[Tensor] = []) -> Tensor: ...
The Protocol is intentionally kept to three arguments so that existing
first-order callables remain valid ODECallable implementations.
ResidualsConstraint uses _ODECallableN internally to call
higher-order functions with the correct signature.
Source code in src/anypinn/problems/ode.py
__call__(x: Tensor, y: Tensor, args: ArgsRegistry) -> Tensor
Source code in src/anypinn/problems/ode.py
ODEHyperparameters
dataclass
Bases: PINNHyperparameters
Hyperparameters for ODE inverse problems.
Extends PINNHyperparameters with per-constraint loss weights
used by ODEInverseProblem.
Attributes:
| Name | Type | Description |
|---|---|---|
pde_weight |
float
|
Weight for the ODE residual loss term. |
ic_weight |
float
|
Weight for the initial-condition loss term. |
data_weight |
float
|
Weight for the data-fitting loss term. |
Source code in src/anypinn/problems/ode.py
data_weight: float = 1.0
class-attribute
instance-attribute
ic_weight: float = 1.0
class-attribute
instance-attribute
pde_weight: float = 1.0
class-attribute
instance-attribute
__init__(*, lr: float, training_data: IngestionConfig | GenerationConfig, fields_config: MLPConfig, params_config: MLPConfig | ScalarConfig, max_epochs: int | None = None, gradient_clip_val: float | None = None, criterion: Criteria = 'mse', optimizer: AdamConfig | LBFGSConfig | None = None, scheduler: ReduceLROnPlateauConfig | CosineAnnealingConfig | None = None, early_stopping: EarlyStoppingConfig | None = None, smma_stopping: SMMAStoppingConfig | None = None, pde_weight: float = 1.0, ic_weight: float = 1.0, data_weight: float = 1.0) -> None
ODEInverseProblem
Bases: Problem
Convenience class composing Residuals + IC + Data constraints.
Wires together ResidualsConstraint, ICConstraint, and
DataConstraint with the loss criterion from hyperparameters.
For forward-only problems (no data fitting), compose the constraints
manually instead.
Example
problem = ODEInverseProblem( ... props=props, ... hp=ODEHyperparameters(...), ... fields={"S": field_s, "I": field_i, "R": field_r}, ... params={"beta": Parameter(ScalarConfig(init_value=0.3))}, ... predict_data=lambda t, f, p: torch.stack( ... [f"S", f"I", f"R"], dim=1 ... ).squeeze(-1), ... )
Source code in src/anypinn/problems/ode.py
__init__(props: ODEProperties, hp: ODEHyperparameters, fields: FieldsRegistry, params: ParamsRegistry, predict_data: PredictDataFn) -> None
Source code in src/anypinn/problems/ode.py
ODEProperties
dataclass
Properties defining an Ordinary Differential Equation problem.
Attributes:
| Name | Type | Description |
|---|---|---|
ode |
ODECallable
|
The ODE function (callable). |
args |
ArgsRegistry
|
Arguments/Parameters for the ODE. |
y0 |
Tensor
|
Initial conditions. |
order |
int
|
Order of the ODE (default 1). For order=n, the ODE callable receives derivs as its last argument: derivs[k] is the (k+1)-th derivative. |
dy0 |
list[Tensor]
|
Initial conditions for lower-order derivatives, length = order-1. dy0[k] is the IC for the (k+1)-th derivative, shape (n_fields,). |
expected_args |
frozenset[str] | None
|
Optional set of arg keys the ODE function accesses. When provided, validated against the merged args+params at construction time. |
Example
def sir_ode(t, y, args): ... S, I, R = y ... beta, gamma = args"beta", args"gamma" ... N = S + I + R ... dS = -beta * S * I / N ... dI = beta * S * I / N - gamma * I ... dR = gamma * I ... return torch.stack([dS, dI, dR]) props = ODEProperties( ... ode=sir_ode, ... args={"beta": Argument(0.3), "gamma": Argument(0.1)}, ... y0=torch.tensor([0.99, 0.01, 0.0]), ... )
Source code in src/anypinn/problems/ode.py
args: ArgsRegistry
instance-attribute
dy0: list[Tensor] = dc_field(default_factory=list)
class-attribute
instance-attribute
expected_args: frozenset[str] | None = None
class-attribute
instance-attribute
ode: ODECallable
instance-attribute
order: int = 1
class-attribute
instance-attribute
y0: Tensor
instance-attribute
__init__(ode: ODECallable, args: ArgsRegistry, y0: Tensor, order: int = 1, dy0: list[Tensor] = list(), expected_args: frozenset[str] | None = None) -> None
__post_init__() -> None
ResidualsConstraint
Bases: Constraint
Constraint enforcing the ODE residuals.
Minimizes ||dy/dt - f(t, y)||^2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
props
|
ODEProperties
|
ODE properties. |
required |
fields
|
FieldsRegistry
|
List of fields. |
required |
params
|
ParamsRegistry
|
List of parameters. |
required |
weight
|
float
|
Weight for this loss term. |
1.0
|
Source code in src/anypinn/problems/ode.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
args = props.args.copy()
instance-attribute
fields = fields
instance-attribute
ode = props.ode
instance-attribute
order = props.order
instance-attribute
weight = weight
instance-attribute
__init__(props: ODEProperties, fields: FieldsRegistry, params: ParamsRegistry, weight: float = 1.0)
Source code in src/anypinn/problems/ode.py
loss(batch: TrainingBatch, criterion: nn.Module, log: LogFn | None = None) -> Tensor
Compute the ODE residual loss over collocation points.