solver – ODE, Difference, and PDE Solving Engine

ODE, difference, and PDE solving engine.

solver.solve_difference(recur_func, n_min, n_max, y0, order)[source]

Solve a difference equation by iterating the recurrence.

The recurrence has the form y_{n+order} = f(n, [y_n, y_{n+1}, …, y_{n+order-1}]). State vector at step n: y[0]=y_n, y[1]=y_{n+1}, …, y[order-1]=y_{n+order-1}.

Parameters:
  • recur_func (Callable[[int, ndarray], float]) – Function (n, y) -> next value y_{n+order}.

  • n_min (int) – Start index (inclusive).

  • n_max (int) – End index (inclusive).

  • y0 (list[float]) – Initial conditions [y_0, y_1, …, y_{order-1}].

  • order (int) – Order of the recurrence.

Return type:

DifferenceSolution

Returns:

A DifferenceSolution with n and y arrays. y has shape (order, n_points) for compatibility with ODE pipeline.

solver.get_difference_function(*, expression=None, function_name=None, order, parameters=None)[source]

Resolve a difference equation function from expression or Python function.

Exactly one of expression or function_name must be provided.

Parameters:
  • expression (str | None) – Python expression for y_{n+order}.

  • function_name (str | None) – Name of a function in config.difference_equations to import.

  • order (int) – Recurrence order (1, 2, …).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[[int, ndarray], float]

Returns:

A callable f(n, y) that returns the next value (scalar).

Raises:
  • EquationParseError – If expression is invalid or function cannot be resolved.

  • ValueError – If neither or both expression and function_name are provided.

solver.get_ode_function(*, expression=None, function_name=None, order, parameters=None)[source]

Resolve an ODE function from either an expression string or a Python function.

Exactly one of expression or function_name must be provided.

Parameters:
  • expression (str | None) – Python expression for the highest derivative.

  • function_name (str | None) – Name of a function in config.equations to import.

  • order (int) – ODE order (1, 2, …).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[[float, ndarray], ndarray]

Returns:

A callable f(x, y) that returns dy/dx as a 1-D array.

Raises:
  • EquationParseError – If expression is invalid or function cannot be resolved.

  • ValueError – If neither or both expression and function_name are provided.

solver.get_vector_ode_function(*, vector_expressions, function_name=None, order, vector_components, parameters=None)[source]

Resolve a vector ODE function from expressions or Python function.

Exactly one of vector_expressions or function_name must be provided.

Parameters:
  • vector_expressions (list[str]) – List of expressions for each component’s highest derivative.

  • function_name (str | None) – Name of function in config.equations (returns full dydt).

  • order (int) – Order of each ODE component.

  • vector_components (int) – Number of components (f_0, f_1, …).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[[float, ndarray], ndarray]

Returns:

A callable f(x, y) that returns dy/dx.

Raises:
  • ValueError – If both or neither of vector_expressions and function_name provided.

  • EquationParseError – If expressions are invalid or function not found.

solver.parse_pde_rhs_expression(expression, variables, parameters=None)[source]

Parse a PDE RHS expression into a callable f(x, y, …) -> float.

The expression can use variable names (x, y, z, …) or indexed notation (x[0], x[1], …) and parameters. Used for the RHS of Poisson-type equations -u_xx - u_yy = f(x,y).

Parameters:
  • expression (str) – Python expression string (e.g. "k" or "x[0] * x[1]").

  • variables (list[str]) – List of variable names (e.g. ["x", "y"] or ["x[0]", "x[1]"]).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[..., float]

Returns:

A callable that takes (x, y, …) and returns the RHS value.

Raises:

EquationParseError – If the expression is invalid.

solver.compute_ode_residual_error(ode_func, x, y)[source]

Compute residual error: how well does y satisfy dy/dx = f(x, y)?

Compares the ODE right-hand side f(x,y) with the numerical derivative of the solution. Large residuals indicate the solution may not satisfy the ODE well (e.g. coarse tolerances, stiff problem).

Parameters:
  • ode_func (Callable[[float, ndarray], ndarray]) – Right-hand side f(x, y) of the ODE dy/dx = f(x, y).

  • x (ndarray) – Independent variable values.

  • y (ndarray) – Solution array of shape (n_vars, n_points).

Return type:

dict[str, float]

Returns:

Dict with residual_max, residual_mean, residual_rms (L2 norm per point).

class solver.FNotation(kind, n_components=1, order=1, n_independent_vars=1, component_orders=())[source]

Bases: object

Describes the notation context for a particular equation.

Variables:
  • kind – One of "ode", "vector_ode", "difference", "pde".

  • n_components – Number of components (1 for scalar ODE / PDE / difference).

  • order – ODE order per component, or max derivative order for PDE.

  • n_independent_vars – Number of independent variables (1 for ODE, >=1 for PDE).

Parameters:
  • kind (Literal['ode', 'vector_ode', 'difference', 'pde'])

  • n_components (int)

  • order (int)

  • n_independent_vars (int)

  • component_orders (tuple[int, ...])

kind: Literal['ode', 'vector_ode', 'difference', 'pde']
n_components: int = 1
order: int = 1
n_independent_vars: int = 1
component_orders: tuple[int, ...] = ()
state_size()[source]

Total number of entries in the flat state vector.

Return type:

int

Returns:

Number of entries in the flat y array.

solver.generate_derivative_labels(notation)[source]

Generate labels for every entry in the flat state vector.

Parameters:

notation (FNotation) – Equation context.

Return type:

list[str]

Returns:

List of human-readable labels, length == notation.state_size().

class solver.ODESolution(x, y, success, message, method_used, n_eval=0, raw=None)[source]

Bases: object

Container for ODE solution data.

Variables:
  • x – Independent variable values.

  • y – Solution array — shape (n_vars, n_points).

  • success – Whether the solver converged.

  • message – Solver status message.

  • method_used – Name of the integration method.

  • n_eval – Number of function evaluations (if available).

  • raw – The original OdeResult from SciPy.

Parameters:
x: ndarray
y: ndarray
success: bool
message: str
method_used: str
n_eval: int = 0
raw: Any = None
solver.solve_multipoint(ode_func, conditions, order, x_min, x_max, method=None, t_eval=None, max_step=None, rtol=None, atol=None)[source]

Solve an ODE with initial conditions specified at possibly different x points.

Uses a shooting method: the full state at x_min is found via root-finding so that all given conditions y^(k)(x_i) = a_i are satisfied.

Parameters:
  • ode_func (Callable[[float, ndarray], ndarray]) – Right-hand side of the ODE system dy/dx = f(x, y).

  • conditions (list[tuple[int, float, float]]) – List of (k, x_i, a_i) meaning y^(k)(x_i) = a_i.

  • order (int) – ODE order (equals number of conditions).

  • x_min (float) – Domain start.

  • x_max (float) – Domain end.

  • method (str | None) – Integration method name.

  • t_eval (ndarray | None) – Points at which to store the final solution.

  • max_step (float | None) – Maximum step size.

  • rtol (float | None) – Relative tolerance.

  • atol (float | None) – Absolute tolerance.

Return type:

ODESolution

Returns:

An ODESolution with the results.

Raises:

SolverFailedError – If the solver or shooting method fails.

solver.solve_ode(ode_func, t_span, y0, method=None, t_eval=None, max_step=None, rtol=None, atol=None)[source]

Solve an initial-value ODE problem using scipy.integrate.solve_ivp.

Parameters:
  • ode_func (Callable[[float, ndarray], ndarray]) – Right-hand side of the ODE system dy/dx = f(x, y).

  • t_span (tuple[float, float]) – Integration interval (x_min, x_max).

  • y0 (list[float]) – Initial conditions vector.

  • method (str | None) – Integration method name. Falls back to env default.

  • t_eval (ndarray | None) – Times at which to store the solution. If None, a uniform grid is generated from env settings.

  • max_step (float | None) – Maximum allowed step size (0 → np.inf).

  • rtol (float | None) – Relative tolerance.

  • atol (float | None) – Absolute tolerance.

Return type:

ODESolution

Returns:

An ODESolution with the results.

Raises:

SolverFailedError – If the solver reports failure.

solver.solve_pde_2d(residual_func, x_min, x_max, y_min, y_max, nx, ny, bc_values=None, parameters=None, mask=None, bc_type=None, bc_neumann_value=None)[source]

Solve a general 2D linear elliptic PDE using finite differences.

The residual_func is called as residual_func(x, y, f, f_x, f_y, f_xx, f_xy, f_yy, **params) and should return the value that must be zero at the solution.

For example, for the equation -f_xx - f_yy = sin(pi*x)*sin(pi*y), the residual is -f_xx - f_yy - sin(pi*x)*sin(pi*y).

Parameters:
  • residual_func (Callable[..., float]) – Callable returning residual at (x,y) with derivatives.

  • x_min (float) – Domain x start.

  • x_max (float) – Domain x end.

  • y_min (float) – Domain y start.

  • y_max (float) – Domain y end.

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

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

  • bc_values (ndarray | None) – Dirichlet boundary values, shape (ny, nx). Default: zeros.

  • parameters (dict[str, float] | None) – Optional dict of parameters for residual_func.

  • mask (ndarray | None) – Boolean array (ny, nx). True = inside domain. None = full rectangle.

  • bc_type (ndarray | None) – String array (ny, nx) with “dirichlet” or “neumann” per point. Only boundary points are used. Default: all Dirichlet.

  • bc_neumann_value (ndarray | None) – Float array (ny, nx) with normal derivative values for Neumann boundary points. Default: zeros.

Return type:

PDESolution

Returns:

PDESolution with grid, solution array, and mask.

solver.is_multivariate(variables)[source]

Return True if the equation has more than one independent variable.

Parameters:

variables (list[str] | None) – List of variable names (e.g. [“x”] or [“x”,”y”]).

Return type:

bool

Returns:

True if len(variables) > 1.

solver.load_predefined_equations()[source]

Load all predefined equations from the YAML file.

Results are cached after the first successful load to avoid redundant disk I/O on repeated calls.

Return type:

dict[str, PredefinedEquation]

Returns:

Ordered dict mapping equation key to PredefinedEquation.

Raises:

FileNotFoundError – If the YAML file is missing.

solver.compute_statistics(x, y, selected=None)[source]

Compute requested statistics for the primary solution component.

Parameters:
  • x (ndarray) – Independent variable values (1D) or tuple of grids for 2D.

  • y (ndarray) – Solution array — shape (n_vars, n_points) or (n_points,) for 1D, or (ny, nx) for 2D PDE.

  • selected (set[str] | None) – Set of statistic keys to compute. None means all.

Return type:

dict[str, Any]

Returns:

Dictionary mapping statistic names to their computed values.

solver.compute_statistics_2d(x_grid, y_grid, u, selected=None)[source]

Compute statistics for a 2D scalar field u(x,y).

Parameters:
  • x_grid (ndarray) – 1D array of x values.

  • y_grid (ndarray) – 1D array of y values.

  • u (ndarray) – 2D array of shape (len(y_grid), len(x_grid)).

  • selected (set[str] | None) – Set of statistic keys. None means all 2D stats.

Return type:

dict[str, Any]

Returns:

Dictionary with mean, std, max, min, integral_2d.

solver.validate_all_inputs(*, expression=None, function_name=None, order, x_min, x_max, y0, num_points, method, params=None, x0_list=None, equation_type='ode', vector_expressions=None, vector_components=1)[source]

Run all validations and return accumulated errors.

Either expression or function_name must be provided.

Parameters:
  • expression (str | None) – ODE/difference expression (optional).

  • function_name (str | None) – Name of function in config (optional).

  • order (int) – Equation order.

  • x_min (float) – Domain start (n_min for difference).

  • x_max (float) – Domain end (n_max for difference).

  • y0 (list[float]) – Initial conditions.

  • num_points (int) – Grid points (ODE only).

  • method (str) – Solver method (ODE only).

  • params (dict[str, float] | None) – Named parameters.

  • x0_list (list[float] | None) – Per-derivative initial condition points (ODE only).

  • equation_type (str) – "ode" or "difference".

  • vector_expressions (list[str] | None)

  • vector_components (int)

Return type:

list[str]

Returns:

List of all error messages (empty if everything is valid).

solver.equation_parser

Safe parsing and evaluation of user-written ODE expressions.

Expressions may use either the legacy y[k] notation or the unified f[...] notation. When f tokens are present they are automatically rewritten to y[...] via solver.notation before compilation.

solver.equation_parser.get_ode_function(*, expression=None, function_name=None, order, parameters=None)[source]

Resolve an ODE function from either an expression string or a Python function.

Exactly one of expression or function_name must be provided.

Parameters:
  • expression (str | None) – Python expression for the highest derivative.

  • function_name (str | None) – Name of a function in config.equations to import.

  • order (int) – ODE order (1, 2, …).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[[float, ndarray], ndarray]

Returns:

A callable f(x, y) that returns dy/dx as a 1-D array.

Raises:
  • EquationParseError – If expression is invalid or function cannot be resolved.

  • ValueError – If neither or both expression and function_name are provided.

solver.equation_parser.get_difference_function(*, expression=None, function_name=None, order, parameters=None)[source]

Resolve a difference equation function from expression or Python function.

Exactly one of expression or function_name must be provided.

Parameters:
  • expression (str | None) – Python expression for y_{n+order}.

  • function_name (str | None) – Name of a function in config.difference_equations to import.

  • order (int) – Recurrence order (1, 2, …).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[[int, ndarray], float]

Returns:

A callable f(n, y) that returns the next value (scalar).

Raises:
  • EquationParseError – If expression is invalid or function cannot be resolved.

  • ValueError – If neither or both expression and function_name are provided.

solver.equation_parser.parse_pde_rhs_expression(expression, variables, parameters=None)[source]

Parse a PDE RHS expression into a callable f(x, y, …) -> float.

The expression can use variable names (x, y, z, …) or indexed notation (x[0], x[1], …) and parameters. Used for the RHS of Poisson-type equations -u_xx - u_yy = f(x,y).

Parameters:
  • expression (str) – Python expression string (e.g. "k" or "x[0] * x[1]").

  • variables (list[str]) – List of variable names (e.g. ["x", "y"] or ["x[0]", "x[1]"]).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[..., float]

Returns:

A callable that takes (x, y, …) and returns the RHS value.

Raises:

EquationParseError – If the expression is invalid.

solver.equation_parser.get_vector_ode_function(*, vector_expressions, function_name=None, order, vector_components, parameters=None)[source]

Resolve a vector ODE function from expressions or Python function.

Exactly one of vector_expressions or function_name must be provided.

Parameters:
  • vector_expressions (list[str]) – List of expressions for each component’s highest derivative.

  • function_name (str | None) – Name of function in config.equations (returns full dydt).

  • order (int) – Order of each ODE component.

  • vector_components (int) – Number of components (f_0, f_1, …).

  • parameters (dict[str, float] | None) – Named parameter values.

Return type:

Callable[[float, ndarray], ndarray]

Returns:

A callable f(x, y) that returns dy/dx.

Raises:
  • ValueError – If both or neither of vector_expressions and function_name provided.

  • EquationParseError – If expressions are invalid or function not found.

solver.ode_solver

Core ODE solving wrappers around SciPy integrators.

class solver.ode_solver.ODESolution(x, y, success, message, method_used, n_eval=0, raw=None)[source]

Bases: object

Container for ODE solution data.

Variables:
  • x – Independent variable values.

  • y – Solution array — shape (n_vars, n_points).

  • success – Whether the solver converged.

  • message – Solver status message.

  • method_used – Name of the integration method.

  • n_eval – Number of function evaluations (if available).

  • raw – The original OdeResult from SciPy.

Parameters:
x: ndarray
y: ndarray
success: bool
message: str
method_used: str
n_eval: int = 0
raw: Any = None
solver.ode_solver.solve_ode(ode_func, t_span, y0, method=None, t_eval=None, max_step=None, rtol=None, atol=None)[source]

Solve an initial-value ODE problem using scipy.integrate.solve_ivp.

Parameters:
  • ode_func (Callable[[float, ndarray], ndarray]) – Right-hand side of the ODE system dy/dx = f(x, y).

  • t_span (tuple[float, float]) – Integration interval (x_min, x_max).

  • y0 (list[float]) – Initial conditions vector.

  • method (str | None) – Integration method name. Falls back to env default.

  • t_eval (ndarray | None) – Times at which to store the solution. If None, a uniform grid is generated from env settings.

  • max_step (float | None) – Maximum allowed step size (0 → np.inf).

  • rtol (float | None) – Relative tolerance.

  • atol (float | None) – Absolute tolerance.

Return type:

ODESolution

Returns:

An ODESolution with the results.

Raises:

SolverFailedError – If the solver reports failure.

solver.ode_solver.solve_multipoint(ode_func, conditions, order, x_min, x_max, method=None, t_eval=None, max_step=None, rtol=None, atol=None)[source]

Solve an ODE with initial conditions specified at possibly different x points.

Uses a shooting method: the full state at x_min is found via root-finding so that all given conditions y^(k)(x_i) = a_i are satisfied.

Parameters:
  • ode_func (Callable[[float, ndarray], ndarray]) – Right-hand side of the ODE system dy/dx = f(x, y).

  • conditions (list[tuple[int, float, float]]) – List of (k, x_i, a_i) meaning y^(k)(x_i) = a_i.

  • order (int) – ODE order (equals number of conditions).

  • x_min (float) – Domain start.

  • x_max (float) – Domain end.

  • method (str | None) – Integration method name.

  • t_eval (ndarray | None) – Points at which to store the final solution.

  • max_step (float | None) – Maximum step size.

  • rtol (float | None) – Relative tolerance.

  • atol (float | None) – Absolute tolerance.

Return type:

ODESolution

Returns:

An ODESolution with the results.

Raises:

SolverFailedError – If the solver or shooting method fails.

solver.difference_solver

Solver for difference equations (recurrence relations).

class solver.difference_solver.DifferenceSolution(n, y, success, message)[source]

Bases: object

Container for difference equation solution data.

Variables:
  • n – Discrete index values (0, 1, 2, …).

  • y – Solution array — shape (n_vars, n_points).

  • success – Whether the iteration completed without error.

  • message – Status message.

Parameters:
n: ndarray
y: ndarray
success: bool
message: str
solver.difference_solver.solve_difference(recur_func, n_min, n_max, y0, order)[source]

Solve a difference equation by iterating the recurrence.

The recurrence has the form y_{n+order} = f(n, [y_n, y_{n+1}, …, y_{n+order-1}]). State vector at step n: y[0]=y_n, y[1]=y_{n+1}, …, y[order-1]=y_{n+order-1}.

Parameters:
  • recur_func (Callable[[int, ndarray], float]) – Function (n, y) -> next value y_{n+order}.

  • n_min (int) – Start index (inclusive).

  • n_max (int) – End index (inclusive).

  • y0 (list[float]) – Initial conditions [y_0, y_1, …, y_{order-1}].

  • order (int) – Order of the recurrence.

Return type:

DifferenceSolution

Returns:

A DifferenceSolution with n and y arrays. y has shape (order, n_points) for compatibility with ODE pipeline.

solver.pde_solver

PDE solver for multivariate scalar fields using finite differences.

Supports 2D elliptic PDEs of the general form:

a(x,y)*f_xx + b(x,y)*f_xy + c(x,y)*f_yy + d(x,y)*f_x + e(x,y)*f_y + g(x,y)*f = rhs(x,y)

The solver probes the user-supplied residual function at each grid point to extract local coefficients, then assembles a sparse linear system using central differences (5-point stencil for the Laplacian, central differences for first derivatives and mixed derivative).

Supports: - Arbitrary domain shapes via boolean masks - Dirichlet and Neumann boundary conditions

class solver.pde_solver.PDESolution(grid, u, success, message, n_eval=0, mask=None)[source]

Bases: object

Container for PDE solution data.

Variables:
  • grid – Tuple of 1D arrays, one per variable (e.g. (x_vals, y_vals)).

  • u – Solution array. For 2D: shape (ny, nx). Exterior points are NaN.

  • success – Whether the solver converged.

  • message – Solver status message.

  • n_eval – Number of iterations (if applicable).

  • mask – Optional boolean mask (ny, nx). True = inside domain.

Parameters:
grid: tuple[ndarray, ...]
u: ndarray
success: bool
message: str
n_eval: int = 0
mask: ndarray | None = None
solver.pde_solver.solve_pde_2d(residual_func, x_min, x_max, y_min, y_max, nx, ny, bc_values=None, parameters=None, mask=None, bc_type=None, bc_neumann_value=None)[source]

Solve a general 2D linear elliptic PDE using finite differences.

The residual_func is called as residual_func(x, y, f, f_x, f_y, f_xx, f_xy, f_yy, **params) and should return the value that must be zero at the solution.

For example, for the equation -f_xx - f_yy = sin(pi*x)*sin(pi*y), the residual is -f_xx - f_yy - sin(pi*x)*sin(pi*y).

Parameters:
  • residual_func (Callable[..., float]) – Callable returning residual at (x,y) with derivatives.

  • x_min (float) – Domain x start.

  • x_max (float) – Domain x end.

  • y_min (float) – Domain y start.

  • y_max (float) – Domain y end.

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

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

  • bc_values (ndarray | None) – Dirichlet boundary values, shape (ny, nx). Default: zeros.

  • parameters (dict[str, float] | None) – Optional dict of parameters for residual_func.

  • mask (ndarray | None) – Boolean array (ny, nx). True = inside domain. None = full rectangle.

  • bc_type (ndarray | None) – String array (ny, nx) with “dirichlet” or “neumann” per point. Only boundary points are used. Default: all Dirichlet.

  • bc_neumann_value (ndarray | None) – Float array (ny, nx) with normal derivative values for Neumann boundary points. Default: zeros.

Return type:

PDESolution

Returns:

PDESolution with grid, solution array, and mask.

solver.error_metrics

Compute error and quality metrics for ODE solutions.

solver.error_metrics.compute_ode_residual_error(ode_func, x, y)[source]

Compute residual error: how well does y satisfy dy/dx = f(x, y)?

Compares the ODE right-hand side f(x,y) with the numerical derivative of the solution. Large residuals indicate the solution may not satisfy the ODE well (e.g. coarse tolerances, stiff problem).

Parameters:
  • ode_func (Callable[[float, ndarray], ndarray]) – Right-hand side f(x, y) of the ODE dy/dx = f(x, y).

  • x (ndarray) – Independent variable values.

  • y (ndarray) – Solution array of shape (n_vars, n_points).

Return type:

dict[str, float]

Returns:

Dict with residual_max, residual_mean, residual_rms (L2 norm per point).

solver.predefined

Load and manage predefined ODE equations from YAML.

class solver.predefined.PredefinedEquation(key, name, formula, description, order, parameters, expression, function_name, default_initial_conditions, default_domain=<factory>, vector_expressions=None, vector_components=1, equation_type='ode', category='Oscillators', variables=<factory>, partial_derivatives=None)[source]

Bases: object

Predefined equation (ODE, difference, PDE, or vector ODE) loaded from YAML.

formula is always required for display. Either expression or function_name must be set for execution. If function_name is set, the equation is resolved by importing the function from config.equations; otherwise expression is used. For vector ODEs, use vector_expressions or function_name.

Variables:
  • key – Unique identifier (YAML key).

  • name – Human-readable name.

  • formula – Compact human-readable equation string (e.g. "y'' + ω²y = 0").

  • description – Multi-line description with formula and context.

  • order – Equation order (1, 2, …) for ODE/difference. For vector: order per component.

  • parameters – Mapping of param name to {default, description}.

  • expression – Python expression for execution (optional if function_name set).

  • function_name – Name of function in config.equations to import (optional).

  • vector_expressions – For vector ODEs, list of expressions (one per component).

  • vector_components – Number of components [f_0, f_1, …] for vector ODEs.

  • default_initial_conditions – Default y0 vector.

  • default_domain – Default [x_min, x_max] for ODE or [n_min, n_max] for difference. For PDE: [x_min, x_max, y_min, y_max, ...] per variable.

  • equation_type"ode" (differential), "difference", "pde", or "vector_ode".

  • category – Display category (e.g. "Oscillators", "Population") for UI grouping.

  • variables – Independent variable names, e.g. ["x"] for 1D, ["x","y"] for 2D. If absent or ["x"], treated as 1D ODE.

  • partial_derivatives – For PDEs, maps derivative keys (e.g. "f_xx", "f_xy") to expression strings. Only needed for PDE type.

Parameters:
key: str
name: str
formula: str
description: str
order: int
parameters: dict[str, dict[str, Any]]
expression: str | None
function_name: str | None
default_initial_conditions: list[float]
default_domain: list[float]
vector_expressions: list[str] | None = None
vector_components: int = 1
equation_type: Literal['ode', 'difference', 'pde', 'vector_ode'] = 'ode'
category: str = 'Oscillators'
variables: list[str]
partial_derivatives: dict[str, str] | None = None
solver.predefined.load_predefined_equations()[source]

Load all predefined equations from the YAML file.

Results are cached after the first successful load to avoid redundant disk I/O on repeated calls.

Return type:

dict[str, PredefinedEquation]

Returns:

Ordered dict mapping equation key to PredefinedEquation.

Raises:

FileNotFoundError – If the YAML file is missing.

solver.predefined.is_multivariate(variables)[source]

Return True if the equation has more than one independent variable.

Parameters:

variables (list[str] | None) – List of variable names (e.g. [“x”] or [“x”,”y”]).

Return type:

bool

Returns:

True if len(variables) > 1.

solver.notation

Notation translation between user-facing f[…] and internal flat y[j] arrays.

The user writes expressions using f[i,k] (vector ODE), f[k] (scalar ODE / difference), or f[a,b,...] (PDE derivatives). Internally, scipy’s solve_ivp operates on a flat state vector y. This module bridges the two representations.

class solver.notation.FNotation(kind, n_components=1, order=1, n_independent_vars=1, component_orders=())[source]

Bases: object

Describes the notation context for a particular equation.

Variables:
  • kind – One of "ode", "vector_ode", "difference", "pde".

  • n_components – Number of components (1 for scalar ODE / PDE / difference).

  • order – ODE order per component, or max derivative order for PDE.

  • n_independent_vars – Number of independent variables (1 for ODE, >=1 for PDE).

Parameters:
  • kind (Literal['ode', 'vector_ode', 'difference', 'pde'])

  • n_components (int)

  • order (int)

  • n_independent_vars (int)

  • component_orders (tuple[int, ...])

kind: Literal['ode', 'vector_ode', 'difference', 'pde']
n_components: int = 1
order: int = 1
n_independent_vars: int = 1
component_orders: tuple[int, ...] = ()
state_size()[source]

Total number of entries in the flat state vector.

Return type:

int

Returns:

Number of entries in the flat y array.

solver.notation.generate_derivative_labels(notation)[source]

Generate labels for every entry in the flat state vector.

Parameters:

notation (FNotation) – Equation context.

Return type:

list[str]

Returns:

List of human-readable labels, length == notation.state_size().

solver.notation.generate_phase_space_options(notation)[source]

Generate options for phase-space axis selectors.

Each option is (label, flat_index) where flat_index is None for the independent variable x.

Parameters:

notation (FNotation) – Equation context.

Return type:

list[tuple[str, int | None]]

Returns:

List of (label, flat_index_or_None) pairs.

solver.statistics

Compute statistics and physical magnitudes from ODE solutions.

solver.statistics.compute_statistics(x, y, selected=None)[source]

Compute requested statistics for the primary solution component.

Parameters:
  • x (ndarray) – Independent variable values (1D) or tuple of grids for 2D.

  • y (ndarray) – Solution array — shape (n_vars, n_points) or (n_points,) for 1D, or (ny, nx) for 2D PDE.

  • selected (set[str] | None) – Set of statistic keys to compute. None means all.

Return type:

dict[str, Any]

Returns:

Dictionary mapping statistic names to their computed values.

solver.statistics.compute_statistics_2d(x_grid, y_grid, u, selected=None)[source]

Compute statistics for a 2D scalar field u(x,y).

Parameters:
  • x_grid (ndarray) – 1D array of x values.

  • y_grid (ndarray) – 1D array of y values.

  • u (ndarray) – 2D array of shape (len(y_grid), len(x_grid)).

  • selected (set[str] | None) – Set of statistic keys. None means all 2D stats.

Return type:

dict[str, Any]

Returns:

Dictionary with mean, std, max, min, integral_2d.

solver.validators

Input validation for DifferentialLab solver parameters.

solver.validators.validate_all_inputs(*, expression=None, function_name=None, order, x_min, x_max, y0, num_points, method, params=None, x0_list=None, equation_type='ode', vector_expressions=None, vector_components=1)[source]

Run all validations and return accumulated errors.

Either expression or function_name must be provided.

Parameters:
  • expression (str | None) – ODE/difference expression (optional).

  • function_name (str | None) – Name of function in config (optional).

  • order (int) – Equation order.

  • x_min (float) – Domain start (n_min for difference).

  • x_max (float) – Domain end (n_max for difference).

  • y0 (list[float]) – Initial conditions.

  • num_points (int) – Grid points (ODE only).

  • method (str) – Solver method (ODE only).

  • params (dict[str, float] | None) – Named parameters.

  • x0_list (list[float] | None) – Per-derivative initial condition points (ODE only).

  • equation_type (str) – "ode" or "difference".

  • vector_expressions (list[str] | None)

  • vector_components (int)

Return type:

list[str]

Returns:

List of all error messages (empty if everything is valid).