Note
This page renders committed notebook outputs. The Read the Docs build does not execute notebook code.
Comparing fitted, finite-map, formula-backed, and failed candidates#
Current surface: V0.29.
Purpose#
Compare candidate representations under one empirical validation vocabulary instead of assuming every discovered-looking object is trustworthy.
What you will learn#
How known finite maps, fitted polynomial generators, and formula-backed records differ.
How conclusion labels
validated,partially_validated, andfailedshould be interpreted.How direct/fallback evidence labels and wrong-span failures appear in reports.
Required extras#
Core install is enough.
Expected runtime#
Under 1 minute.
Out of scope#
No learned detector, no callable generator, no proof of symmetry, no KS runtime promotion.
These notebooks are tutorials, not API contracts. Example outputs are runtime summaries, not canonical paper artifacts.
[1]:
from pathlib import Path
import sys
ROOT = Path.cwd()
if not (ROOT / "pyproject.toml").exists():
ROOT = ROOT.parent
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
import numpy as np
from notebooks._tutorial_utils import confidence_card, plot_singular_values, print_cards, pretty_json
from pdelie import GeneratorFamily, InvariantMapSpec
from pdelie.data import generate_heat_1d_field_batch
from pdelie.reporting import summarize_formula_generator_family, summarize_generator_fit_diagnostics
from pdelie.residuals import HeatResidualEvaluator
from pdelie.symmetry import FormulaGeneratorFamily, fit_translation_generator, validate_symmetry_candidate
CONFIG = {"fit_epsilon": 1e-4, "finite_shift": float(np.pi / 4.0)}
CONFIG
[1]:
{'fit_epsilon': 0.0001, 'finite_shift': 0.7853981633974483}
1. Fit a polynomial translation generator#
[2]:
field = generate_heat_1d_field_batch(batch_size=4, num_times=33, num_points=64, seed=640)
evaluator = HeatResidualEvaluator()
fitted = fit_translation_generator(field, evaluator, epsilon=CONFIG["fit_epsilon"])
fit_summary = summarize_generator_fit_diagnostics(fitted)
plot_singular_values(fit_summary, title="Fitted generator design spectrum")
fit_summary
[2]:
{'summary_schema_version': '0.1',
'summary_type': 'generator_fit_diagnostics',
'parameterization': 'polynomial_translation_affine',
'fit_mode': 'svd',
'training_epsilon': 0.0001,
'basis': ['1', 't', 'x', 'u'],
'basis_delta_norms': {'1': 0.004296394298193215,
't': 174.57692166784753,
'x': 3567.3412985986092,
'u': 126.76115865877486},
'design_column_norms': {'1': 0.004296394298193215,
't': 174.57692166784753,
'x': 3567.3412985986092,
'u': 126.76115865877486},
'singular_values': [3567.342339962003,
174.60620587941526,
126.69149930872412,
0.0038731770687536362],
'condition_number': 921037.7621878132,
'fit_residual': 0.0038731770687536362,
'min_delta_basis': '1',
'selected_coefficients': [0.9999999999415194,
1.0381394087638847e-05,
-7.176322837209081e-09,
-3.0311445954099065e-06],
'svd_coefficients': [0.9999999999415194,
1.0381394087638847e-05,
-7.176322837209081e-09,
-3.0311445954099065e-06],
'selected_span_distance': 1.0814861638697691e-05,
'svd_span_distance': 1.0814861638697691e-05,
'reference_fallback_used': False,
'fallback_reason': None,
'evidence_label': 'direct_svd_in_tolerance'}
2. Build alternative candidate representations#
The finite-map candidate is an InvariantMapSpec. The formula candidate stores safe JSON expression metadata, not executable code.
[3]:
spec = InvariantMapSpec(
generator_metadata=fitted.to_dict(),
construction_method="uniform_translation",
parameters={"axis": "x", "shift": CONFIG["finite_shift"]},
domain_validity="global",
inverse_available=True,
diagnostics={},
)
formula = FormulaGeneratorFamily(
formula_generators=[
{
"name": "formula_translation",
"components": {
"tau": {"node": "const", "value": 0.0},
"xi": {"node": "const", "value": 1.0},
"phi": {"node": "const", "value": 0.0},
},
}
],
finite_transform_spec=spec.to_dict(),
)
wrong = GeneratorFamily(
parameterization=fitted.parameterization,
coefficients=np.asarray([[0.0, 0.0, 1.0, 0.0]], dtype=float),
basis_spec=fitted.basis_spec,
normalization=fitted.normalization,
diagnostics={},
)
print(pretty_json(summarize_formula_generator_family(formula)))
{
"component_names": [
"tau",
"xi",
"phi"
],
"component_nodes": {
"phi": [
"const"
],
"tau": [
"const"
],
"xi": [
"const"
]
},
"diagnostics": {},
"finite_transform_available": true,
"finite_transform_construction_method": "uniform_translation",
"formula_kinds": {
"const": 3
},
"generator_count": 1,
"generator_names": [
"formula_translation"
],
"parameterization": "formula_generator_family",
"reciprocal_denominator_floor": 1e-12,
"schema_version": "0.1",
"summary_schema_version": "0.1",
"summary_type": "formula_generator_family",
"symbolic_references": [],
"variables": [
"t",
"x",
"u"
]
}
3. Validate every candidate under the same field and residual target#
[4]:
cases = {
"fitted_generator_family": fitted,
"finite_translation_spec": spec.to_dict(),
"formula_with_finite_transform": formula,
"wrong_span_generator": wrong,
}
reports = {
name: validate_symmetry_candidate(
field,
candidate,
residual_evaluator=evaluator,
source_candidate_id=name,
)
for name, candidate in cases.items()
}
cards = [
confidence_card(
label=name,
fit=fit_summary if name == "fitted_generator_family" else None,
validation=report,
)
for name, report in reports.items()
]
print_cards(cards)
[
{
"candidate_kind": "generator_family",
"condition_number": 921037.7621878132,
"evidence_label": "direct_svd_in_tolerance",
"fit_mode": "svd",
"label": "fitted_generator_family",
"reference_fallback_used": false,
"selected_span_distance": 1.0814861638697691e-05,
"singular_value_count": 4,
"svd_span_distance": 1.0814861638697691e-05,
"validation_conclusion": "validated"
},
{
"candidate_kind": "invariant_map_spec",
"label": "finite_translation_spec",
"validation_conclusion": "validated"
},
{
"candidate_kind": "formula_generator_family",
"label": "formula_with_finite_transform",
"validation_conclusion": "validated"
},
{
"candidate_kind": "generator_family",
"label": "wrong_span_generator",
"validation_conclusion": "failed"
}
]
4. Inspect failure as a first-class outcome#
A failed candidate is useful: it shows that validation is empirical and configured, not a rubber stamp.
[5]:
print(pretty_json({name: report["conclusion"] for name, report in reports.items()}))
print(pretty_json(reports["wrong_span_generator"], max_chars=3500))
{
"finite_translation_spec": "validated",
"fitted_generator_family": "validated",
"formula_with_finite_transform": "validated",
"wrong_span_generator": "failed"
}
{
"candidate_kind": "generator_family",
"candidate_summary": {
"coefficient_shape": [
1,
4
],
"coefficients": [
[
0.0,
0.0,
1.0,
0.0
]
],
"diagnostics": {},
"fallback_reason": null,
"fit_mode": null,
"generator_names": null,
"normalization": "l2_unit",
"parameterization": "polynomial_translation_affine",
"reference_fallback_used": null,
"summary_schema_version": "0.1",
"summary_type": "generator_family",
"translation_span_distance": 1.4142135623730951
},
"check_reports": {
"finite_transform_verification": {
"report": {
"classification": "failed",
"diagnostics": {
"batch_errors": [
[
0.003680206784620462,
0.004729281486696321,
0.0016744306242292603,
0.0005985977258368695
],
[
0.01163783569982316,
0.014955301194045612,
0.005295014556513332,
0.0018929322158421373
],
[
0.03680206784624526,
0.04729281486700312,
0.016744306242317295,
0.005985977258370113
],
[
0.11637835699818891,
0.14955301194040524,
0.05295014556510434,
0.018929322158419058
],
[
0.3680206784624749,
0.4729281486700427,
0.16744306242319326,
0.05985977258370071
],
[
1.0969944869114534,
1.268019583468842,
0.6130436149426347,
0.14249826325632717
],
[
2.261515580065275,
0.8910920410809624,
2.889891586564692,
0.5750800053038561
]
],
"heldout_initial_conditions": 4,
"span_distance": 1.4142135623730951,
"span_tolerance": 0.05,
"transform_mode": "pointwise_translation"
},
"epsilon_values": [
0.0001,
0.00031622776601683794,
0.001,
0.0031622776601683794,
0.01,
0.03162277660168379,
0.1
],
"error_curve": [
0.002677318704424861,
0.008466425128168246,
0.026773187044281277,
0.08466425128164662,
0.2677318704428341,
0.8550190509270441,
1.5763038105731186
],
"first_epsilon": 0.0001,
"first_error": 0.002677318704424861,
"max_error": 1.5763038105731186,
"norm": "relative_l2",
"summary_schema_version": "0.1",
"summary_type": "verification_report"
},
"required": true,
"status": "failed",
"threshold": "classification != 'failed'"
},
"schema": {
"report": {
"object": "GeneratorFamily"
},
"required": true,
"status": "passed"
}
},
"closure_required": true,
"conclusion": "failed",
"configured_validation_checks": [
"schema",
"finite_transform_verification"
],
"empirical_interpretation": "configured_validation_not_mathematical_proof",
"equation": null,
"field_shape": [
4,
33,
64,
1
],
"finite_transform_epsilons": [
0.0001,
0.00031622776601683794,
0.001,
0.0031622776601683794,
0.01,
0.0316227766016
... <truncated 524 chars>
Recap#
Different candidate types can be compared with one vocabulary: candidate_kind, configured checks, evidence labels, and validated / partially_validated / failed conclusions.
Common failure modes#
Fallback-backed evidence rather than direct residual-based fitting.
Wrong generator span despite valid schema.
Finite transform unavailable, producing only partial validation.
Formula-only finite evaluation without residual-preservation evidence.
Empirical validation being mistaken for proof.
Extension ideas#
Add a Fisher-KPP fitted generator as another candidate.
Compare reference-generator span diagnostics when a trusted reference exists.
Use the same report structure for outputs from an external symmetry method.
What to read/run next#
Run 05_closure_algebra_diagnostics.ipynb to separate algebra diagnostics from residual preservation.