Skip to content

Terms and equations

Refitting a set of terms on one dataset, checking that a term is well formed, and deciding whether two equations state the same law are the three jobs here. The term syntax is described under Equation representation, and what the numbers mean under Score conventions and comparability.

Name Summary
kd.evaluate_terms(dataset, terms[, ...]) Evaluate candidate terms against a dataset, fail-loud.
kd.validate_terms(dataset, terms[, ...]) Classify each term as valid / rejected WITHOUT fitting.
kd.verify_equation(eq, executor[, ...]) Verify an equation on a dataset using its reported coefficients unchanged.
kd.block_dispersion(dataset, terms[, ...]) Refit the terms on separate grid blocks and measure coefficient spread.
kd.forward_error(dataset, terms[, ...]) Integrate the equation from the data's first time slice and compare.
kd.ForwardError(value, reason[, ...]) Outcome of forward_error.
kd.law_signature(eq) Build a versioned signature from an equation's active law.
kd.format_pde(terms, coefficients[, ...]) Build a formatted PDE equation from term strings and coefficients.
kd.FormattedEquation(latex, unicode[, ...]) Rendered PDE equation plus the underlying SymPy objects.
kd.render_lhs_label(lhs_spec) Render an LHS spec to the legacy serialized lhs_label string.
kd.LhsSpec(field, axis[, ...]) Structured left-hand-side specification for an evolution equation.
kd.Sketch(lhs_spec, vocabulary[, ...]) A versioned evolution-law template with pinned, anchored, and hole clauses.
kd.EvaluationResult(mse, nmse[, ...]) Result from evaluating an expression or term list.
kd.TermValidationReport(results, valid[, ...]) Structured result of validate_terms (JSON-dumpable, no fitting).
kd.TermRejection(term, reason) A single rejected term and the reason it was rejected.
kd.VerificationReport(signature, form[, ...]) JSON-serializable measurements for one equation on one dataset.
kd.VerifyPolicy(nmse_max, coeff_atol[, ...]) Thresholds used when reporting and comparing empirical verification.
kd.SKETCH_EXIT_VERIFY —
kd.InvalidTermsError(rejected) Raised when one or more terms are rejected and cannot be fitted.
kd.EvaluationFailedError Raised when the final fit is invalid (solver failure / non-finite MSE).

evaluate_terms

evaluate_terms(
    dataset: PDEDataset,
    terms: Sequence[str],
    *,
    skip_invalid: bool = False,
    max_order: int = 2,
    lhs_order: int | None = None,
    rows: Tensor | None = None,
) -> EvaluationResult

Evaluate candidate terms against a dataset, fail-loud.

Parameters:

  • dataset (PDEDataset) –

    The PDE dataset to evaluate against (never mutated).

  • terms (Sequence[str]) –

    Candidate term strings (canonical funcall IR).

  • skip_invalid (bool, default: False ) –

    When False (default, strict), ANY rejected term raises InvalidTermsError carrying every rejection and nothing is fitted. When True (lenient), rejected terms are dropped with exactly one logger.warning and the survivors are fitted.

  • max_order (int, default: 2 ) –

    Maximum atomic derivative order (-> max_atomic_order).

  • lhs_order (int | None, default: None ) –

    LHS derivative order targeted by the fit (1 -> u_t, 2 -> u_tt; -> DerivativeReqs.lhs_order). Default None DERIVES from dataset.lhs_order (single source of truth).

  • rows (Tensor | None, default: None ) –

    Grid-shaped boolean mask or flat int32/int64 sample indices. Derivatives and term validation run on the complete grid first.

Returns:

  • EvaluationResult –

    An EvaluationResult with is_valid is True (honest metrics).

  • EvaluationResult –

    This entry always measures condition_number (candidate-library

  • EvaluationResult –

    collinearity). The measured matrix is the one the solver was handed:

  • EvaluationResult –

    under skip_invalid=True that is the SURVIVING columns, not every

  • EvaluationResult –

    string in terms — a term dropped as shape / all-zero /

  • EvaluationResult –

    tautology is not in the number. Strict mode fits every submitted

  • EvaluationResult –

    term or raises, so there the two coincide.

Raises:

  • ValueError –

    If terms is empty.

  • ValueError –

    Propagated from PlatformBuilder when the resolved LHS field/axis is absent from the dataset, when the resolved lhs_order > max_order (the LHS is read from the same precomputed derivative cache that max_order bounds), or when max_order > 3 (provider cap).

  • InvalidTermsError –

    If terms are rejected (see skip_invalid).

  • EvaluationFailedError –

    If the final fit is invalid (the penalty sentinel is never returned).

validate_terms

validate_terms(
    dataset: PDEDataset,
    terms: Sequence[str],
    *,
    max_order: int = 2,
    lhs_order: int | None = None,
) -> TermValidationReport

Classify each term as valid / rejected WITHOUT fitting.

Parameters:

  • dataset (PDEDataset) –

    The PDE dataset to evaluate against (never mutated).

  • terms (Sequence[str]) –

    Candidate term strings (canonical funcall IR).

  • max_order (int, default: 2 ) –

    Maximum atomic derivative order made resolvable (-> DerivativeReqs.max_atomic_order). Gates terminal tokens such as u_xx; open-form diff*_x calls are not gated.

  • lhs_order (int | None, default: None ) –

    LHS derivative order the tautology guard compares against (1 -> u_t, 2 -> u_tt). Default None DERIVES the order from dataset.lhs_order (the single source of truth).

Returns:

  • TermValidationReport –

    A TermValidationReport partitioning the terms into valid / rejected, JSON-dumpable via to_dict().

Raises:

  • ValueError –

    If terms is empty.

  • ValueError –

    Propagated from PlatformBuilder when the resolved LHS field/axis is absent from the dataset, when the resolved lhs_order > max_order (the LHS is read from the same precomputed derivative cache that max_order bounds), or when max_order > 3 (provider cap).

verify_equation

verify_equation(
    eq: Equation,
    *,
    executor: PythonExecutor,
    context: ExecutionContext,
    policy: VerifyPolicy = VerifyPolicy(),
) -> VerificationReport

Verify an equation on a dataset using its reported coefficients unchanged.

block_dispersion

block_dispersion(
    dataset: PDEDataset,
    terms: Sequence[str],
    *,
    n_blocks: int = 4,
    axis: str | None = None,
    max_order: int = 2,
    lhs_order: int | None = None,
) -> float

Refit the terms on separate grid blocks and measure coefficient spread.

Parameters:

  • dataset (PDEDataset) –

    A GRID PDEDataset (never mutated).

  • terms (Sequence[str]) –

    Candidate term strings (canonical funcall IR).

  • n_blocks (int, default: 4 ) –

    Number of blocks; 1 gives 0.0.

  • axis (str | None, default: None ) –

    Axis name to split along; default dataset.spatial_axes[0].

  • max_order (int, default: 2 ) –

    As in evaluate_terms.

  • lhs_order (int | None, default: None ) –

    As in evaluate_terms.

Returns:

  • float –

    The mean coefficient of variation across blocks.

Raises:

  • ValueError –

    If the dataset is not GRID, the resolved LHS field/axis is absent, or the result is non-finite.

  • InvalidTermsError –

    Propagated from evaluate_terms.

  • EvaluationFailedError –

    Propagated from evaluate_terms when the fit on any block is invalid.

forward_error

forward_error(
    dataset: PDEDataset,
    terms: Sequence[str],
    coefficients: Sequence[float],
    *,
    method: str = "Radau",
    max_step: float | None = None,
) -> ForwardError

Integrate the equation from the data's first time slice and compare.

Parameters:

  • dataset (PDEDataset) –

    The dataset providing the grid, initial field and target (never mutated).

  • terms (Sequence[str]) –

    RHS term strings of a first-order evolution law.

  • coefficients (Sequence[float]) –

    One coefficient per term.

  • method (str, default: 'Radau' ) –

    scipy.integrate.solve_ivp method.

  • max_step (float | None, default: None ) –

    Maximum solver step; None lets the solver choose.

Returns:

  • ForwardError –

    A ForwardError with value set, or with reason set when the equation diverged, the solver failed, or integration was refused (for example a non-GRID dataset, unsupported LHS order or a time-derivative term).

Raises:

  • ValueError –

    If terms and coefficients differ in length, a coefficient is non-finite, the error is non-finite, or the resolved LHS field/axis is absent from a GRID dataset.

ForwardError dataclass

Outcome of forward_error.

Attributes:

  • value (float | None) –

    ||pred - u||_2 / ||u||_2 over the full grid, or None when the equation could not be integrated.

  • reason (str | None) –

    None when value is set; otherwise "diverged", "solve-failed" (scipy solve_ivp failed) or "refused" (the equation or dataset is unsupported).

  • warning (str) –

    Why integration was refused or failed, empty on a clean run.

law_signature

law_signature(eq: Equation) -> LawSignature

Build a versioned signature from an equation's active law.

format_pde

format_pde(
    terms: Sequence[str],
    coefficients: Tensor | Sequence[float],
    *,
    lhs: str = "u_t",
    selected_indices: Sequence[int] | None = None,
    sig_figs: int = 4,
) -> FormattedEquation

Build a formatted PDE equation from term strings and coefficients.

Parameters:

  • sig_figs (int, default: 4 ) –

    Significant figures for coefficient display (0 = full precision).

FormattedEquation dataclass

Rendered PDE equation plus the underlying SymPy objects.

render_lhs_label

render_lhs_label(lhs_spec: LhsSpec) -> str

Render an LHS spec to the legacy serialized lhs_label string.

LhsSpec dataclass

Structured left-hand-side specification for an evolution equation.

Sketch dataclass

A versioned evolution-law template with pinned, anchored, and hole clauses.

matches

matches(eq: Equation) -> SketchVerdict

Match an EVOLUTION law using the policy's exact coefficient band.

EvaluationResult dataclass

Result from evaluating an expression or term list.

Attributes:

  • mse (float) –

    Mean squared error between prediction and target.

  • nmse (float) –

    Normalized MSE (MSE / variance of target).

  • r2 (float) –

    R-squared (coefficient of determination).

  • score (float | None) –

    Score from the configured scorer (if computed).

  • complexity (int) –

    Number of active terms for AIC. Selected count for sparse solvers, total for dense.

  • coefficients (Tensor | None) –

    Fitted coefficients (one per term).

  • is_valid (bool) –

    Whether evaluation succeeded.

  • error_message (str) –

    Error description if is_valid is False.

  • invalid_reason (str | None) –

    Schema-owned invalid category supplied by the producer; None for valid or legacy results.

  • selected_indices (list[int] | None) –

    Indices of terms selected by sparse solver (None for dense solvers). Relative to terms.

  • residuals (Tensor | None) –

    Detached residual tensor (predicted - actual), shape (n_samples,). Sign convention: positive means over-prediction.

  • terms (list[str] | None) –

    Term strings used for evaluation (defensive copy).

  • expression (str) –

    Original expression string, set only by evaluate_expression().

  • lhs_name (str | None) –

    Optional plugin-reported LHS label for result assembly.

  • condition_number (float | None) –

    Condition number of the FULL candidate term library Theta (all submitted columns, float64 upcast, exactly the matrix handed to the solver) — computed BEFORE any sparse selection or column normalization.

  • form (Form) –

    Transient equation-form dispatch signal for result assembly.

to_dict

to_dict(
    *, include_residuals: bool = True
) -> dict[str, Any]

Return a JSON-safe dict of this result (single serialization source).

Parameters:

  • include_residuals (bool, default: True ) –

    When False, the "residuals" key is kept (schema-stable) but its value is None — for MCP-boundary use where a 50k-float list is unwanted. All other keys are identical to the include_residuals=True output.

Returns:

  • dict[str, Any] –

    A json.dumps-safe dictionary.

TermValidationReport dataclass

Structured result of validate_terms (JSON-dumpable, no fitting).

Attributes:

  • results (list[TermValidation]) –

    Per-term validation outcomes in input order.

  • valid (list[str]) –

    Term strings that passed validation, in input order.

  • rejected (list[TermRejection]) –

    TermRejection entries for the failed terms.

  • ok (bool) –

    True iff every term passed (rejected is empty).

to_dict

to_dict() -> dict[str, Any]

Return a JSON-safe dict of the full report (MCP-boundary contract).

TermRejection dataclass

A single rejected term and the reason it was rejected.

Attributes:

  • term (str) –

    The offending term string.

  • reason (str) –

    Human-readable rejection reason. Distinguishable across the rejection categories; for execution errors it surfaces the original failure message (including the offending token/op name).

to_dict

to_dict() -> dict[str, str]

Return a JSON-safe dict of this rejection.

VerificationReport dataclass

JSON-serializable measurements for one equation on one dataset.

to_dict

to_dict() -> dict[str, object]

Return a JSON-safe representation of this report.

VerifyPolicy dataclass

Thresholds used when reporting and comparing empirical verification.

SKETCH_EXIT_VERIFY module-attribute

SKETCH_EXIT_VERIFY = VerifyPolicy(nmse_max=0.05)

Default residual gate of the sketch exit (1b promise P1).

InvalidTermsError

Bases: ValueError

Raised when one or more terms are rejected and cannot be fitted.

Attributes:

  • rejected –

    Every rejected term with its classification.

EvaluationFailedError

Bases: RuntimeError

Raised when the final fit is invalid (solver failure / non-finite MSE).