From 88d9fe6668b2b7a2b5a86601f93cb4f94502a458 Mon Sep 17 00:00:00 2001 From: "Jorge A. Garcia" <681013+jagg-ix@users.noreply.github.com> Date: Wed, 29 Jul 2026 23:13:41 -0600 Subject: [PATCH] feat(M11.1): add exact pointwise soliton carrier --- .github/workflows/m11-cat-ept-models.yml | 45 ++++ .../m11_cat_ept_soliton_qdo/__init__.py | 9 + .../formal/pointwise_soliton_carrier.v1.json | 18 ++ .../pointwise_soliton_carrier_m111.py | 213 ++++++++++++++++++ .../zil/m11_pointwise_soliton_m111.zc | 6 + tests/test_m11_pointwise_soliton_m111.py | 6 + 6 files changed, 297 insertions(+) create mode 100644 .github/workflows/m11-cat-ept-models.yml create mode 100644 openwave/xperiments/m11_cat_ept_soliton_qdo/__init__.py create mode 100644 openwave/xperiments/m11_cat_ept_soliton_qdo/formal/pointwise_soliton_carrier.v1.json create mode 100644 openwave/xperiments/m11_cat_ept_soliton_qdo/pointwise_soliton_carrier_m111.py create mode 100644 openwave/xperiments/m11_cat_ept_soliton_qdo/research/zil/m11_pointwise_soliton_m111.zc create mode 100644 tests/test_m11_pointwise_soliton_m111.py diff --git a/.github/workflows/m11-cat-ept-models.yml b/.github/workflows/m11-cat-ept-models.yml new file mode 100644 index 00000000..d2927a3f --- /dev/null +++ b/.github/workflows/m11-cat-ept-models.yml @@ -0,0 +1,45 @@ +name: M11 CAT-EPT soliton-QDO model + +on: + pull_request: + paths: + - "openwave/xperiments/m11_cat_ept_soliton_qdo/**" + - "tests/test_m11_*.py" + - "MODELS.md" + - "MODELS_M11.md" + - ".github/workflows/m11-cat-ept-models.yml" + push: + branches: [main] + paths: + - "openwave/xperiments/m11_cat_ept_soliton_qdo/**" + - "tests/test_m11_*.py" + - "MODELS.md" + - "MODELS_M11.md" + - ".github/workflows/m11-cat-ept-models.yml" + +permissions: + contents: read + +jobs: + m11-models: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + - name: Install focused dependencies + run: python -m pip install --upgrade pip "numpy>=2.3,<3.0" "pytest>=8,<10" + - name: Compile M11 modules + run: python -m compileall -q openwave/xperiments/m11_cat_ept_soliton_qdo + - name: Validate formal ledgers + run: | + for ledger in openwave/xperiments/m11_cat_ept_soliton_qdo/formal/*.json; do + python -m json.tool "$ledger" >/dev/null + done + - name: Run M11 tests + env: + PYTHONPATH: . + run: pytest -q tests/test_m11_*.py diff --git a/openwave/xperiments/m11_cat_ept_soliton_qdo/__init__.py b/openwave/xperiments/m11_cat_ept_soliton_qdo/__init__.py new file mode 100644 index 00000000..fa547d56 --- /dev/null +++ b/openwave/xperiments/m11_cat_ept_soliton_qdo/__init__.py @@ -0,0 +1,9 @@ +"""M11 CAT/EPT pointwise soliton--Liouville--QDO particle model.""" +from .pointwise_soliton_carrier_m111 import ( + PointwiseSolitonConfig, PointwiseSolitonState, + construct_pointwise_soliton, run_pointwise_soliton_study, +) +__all__ = [ + "PointwiseSolitonConfig", "PointwiseSolitonState", + "construct_pointwise_soliton", "run_pointwise_soliton_study", +] diff --git a/openwave/xperiments/m11_cat_ept_soliton_qdo/formal/pointwise_soliton_carrier.v1.json b/openwave/xperiments/m11_cat_ept_soliton_qdo/formal/pointwise_soliton_carrier.v1.json new file mode 100644 index 00000000..afc9a906 --- /dev/null +++ b/openwave/xperiments/m11_cat_ept_soliton_qdo/formal/pointwise_soliton_carrier.v1.json @@ -0,0 +1,18 @@ +{ + "schema": "openwave.m11.pointwise-soliton-carrier-ledger.v1", + "model_id": "M11", + "milestone": "M11.1", + "formal_repository": "jagg-ix/entropic-physlib-private", + "formal_branch": "entropic-physlib-linear-full", + "formal_head": "8bafa9ab93cbb39e85909fc3837bb4b6e0dec748", + "equations": [ + {"id": "bright-soliton", "equation": "-D psi_xx-g psi^3=mu psi", "numerical_source": "construct_pointwise_soliton"}, + {"id": "standing-wave", "equation": "Psi(t,x)=exp(-i mu t/hbar) psi(x)", "numerical_source": "PointwiseSolitonState.wave"}, + {"id": "bps-control", "equation": "phi'=2 sinh(phi/2) => phi''=sinh(phi)", "formal_theorem": "bps_implies_sinhGordon"} + ], + "formal_sources": [ + {"path": "Physlib/QuantumMechanics/ComplexAction/SinhGordonSoliton.lean", "sha": "b2eb056dd4d66d224adf2d118da874e48a4a63cc", "theorem": "bps_implies_sinhGordon"}, + {"path": "Physlib/QuantumMechanics/ComplexAction/EntropicTime/SelfBoundSchrodingerNewtonPDE.lean", "sha": "d84c06718e292dd18e03653efb34d237a4e2899a", "theorem": "standingWave_solves_full_schrodingerNewton"}, + {"path": "Physlib/QuantumMechanics/ComplexAction/EntropicTime/CubicQuinticOrbitalStability.lean", "sha": "fb47b98296a771eee44570ce42b5c2ab03d450a3", "theorem": "cubicQuinticDensity_coercive"} + ] +} diff --git a/openwave/xperiments/m11_cat_ept_soliton_qdo/pointwise_soliton_carrier_m111.py b/openwave/xperiments/m11_cat_ept_soliton_qdo/pointwise_soliton_carrier_m111.py new file mode 100644 index 00000000..e580665f --- /dev/null +++ b/openwave/xperiments/m11_cat_ept_soliton_qdo/pointwise_soliton_carrier_m111.py @@ -0,0 +1,213 @@ +"""M11.1 exact pointwise CAT/EPT bright-soliton carrier. + +The executable carrier uses the normalized one-dimensional cubic-NLS bright +soliton as an exact pointwise control model. The nonlinear coefficient is +calibrated from the finite-domain normalization, so the analytic second +spatial derivative closes the stationary equation at machine precision. +""" +from __future__ import annotations + +from dataclasses import asdict, dataclass +from hashlib import sha256 +import json +import math +from typing import Any, Mapping + +import numpy as np + +MILESTONE = "M11.1" +SCHEMA = "openwave.m11.pointwise-soliton-carrier.v1" +FORMAL_HEAD = "8bafa9ab93cbb39e85909fc3837bb4b6e0dec748" +FORMAL_SOURCES = ( + { + "path": "Physlib/QuantumMechanics/ComplexAction/SinhGordonSoliton.lean", + "sha": "b2eb056dd4d66d224adf2d118da874e48a4a63cc", + "theorem": "bps_implies_sinhGordon", + }, + { + "path": "Physlib/QuantumMechanics/ComplexAction/EntropicTime/SelfBoundSchrodingerNewtonPDE.lean", + "sha": "d84c06718e292dd18e03653efb34d237a4e2899a", + "theorem": "standingWave_solves_full_schrodingerNewton", + }, + { + "path": "Physlib/QuantumMechanics/ComplexAction/EntropicTime/CubicQuinticOrbitalStability.lean", + "sha": "fb47b98296a771eee44570ce42b5c2ab03d450a3", + "theorem": "cubicQuinticDensity_coercive", + }, +) + + +def _canonical_json(value: Mapping[str, Any]) -> str: + return json.dumps(value, sort_keys=True, separators=(",", ":"), default=str) + + +def sech(value: np.ndarray) -> np.ndarray: + return 1.0 / np.cosh(value) + + +@dataclass(frozen=True) +class PointwiseSolitonConfig: + grid_points: int = 1025 + half_length: float = 12.0 + inverse_width: float = 1.0 + dispersion: float = 0.5 + hbar: float = 1.0 + winding: int = 1 + sample_time: float = 0.37 + + def validate(self) -> None: + if self.grid_points < 129 or self.grid_points % 2 == 0: + raise ValueError("an odd grid with at least 129 points is required") + if self.half_length <= 0 or self.inverse_width <= 0: + raise ValueError("positive length and inverse width are required") + if self.dispersion <= 0 or self.hbar <= 0: + raise ValueError("positive dispersion and hbar are required") + + +@dataclass(frozen=True) +class PointwiseSolitonState: + config: PointwiseSolitonConfig + x: np.ndarray + psi: np.ndarray + second_derivative: np.ndarray + chemical_potential: float + cubic_coupling: float + amplitude: float + dx: float + + @property + def density(self) -> np.ndarray: + return np.abs(self.psi) ** 2 + + def wave(self, time: float) -> np.ndarray: + phase = np.exp(-1.0j * self.chemical_potential * time / self.config.hbar) + return np.asarray(phase * self.psi, dtype=np.complex128) + + def stationary_residual(self) -> np.ndarray: + cfg = self.config + return np.asarray( + -cfg.dispersion * self.second_derivative + - self.cubic_coupling * self.psi**3 + - self.chemical_potential * self.psi, + dtype=np.float64, + ) + + +def construct_pointwise_soliton( + config: PointwiseSolitonConfig | None = None, +) -> PointwiseSolitonState: + cfg = PointwiseSolitonConfig() if config is None else config + cfg.validate() + x = np.linspace(-cfg.half_length, cfg.half_length, cfg.grid_points) + dx = float(x[1] - x[0]) + shape = sech(cfg.inverse_width * x) + amplitude = float(1.0 / math.sqrt(np.trapezoid(shape**2, x))) + psi = np.asarray(amplitude * shape, dtype=np.float64) + second = np.asarray( + cfg.inverse_width**2 * psi * (1.0 - 2.0 * shape**2), + dtype=np.float64, + ) + chemical_potential = -cfg.dispersion * cfg.inverse_width**2 + cubic_coupling = 2.0 * cfg.dispersion * cfg.inverse_width**2 / amplitude**2 + return PointwiseSolitonState( + config=cfg, + x=x, + psi=psi, + second_derivative=second, + chemical_potential=chemical_potential, + cubic_coupling=cubic_coupling, + amplitude=amplitude, + dx=dx, + ) + + +def sinh_gordon_bps_control(sample_count: int = 257) -> dict[str, float]: + phi = np.linspace(-1.5, 1.5, sample_count) + first = 2.0 * np.sinh(phi / 2.0) + second_from_chain = np.cosh(phi / 2.0) * first + second_exact = np.sinh(phi) + energy = 0.5 * first**2 - np.cosh(phi) + return { + "bps_second_order_error": float(np.max(np.abs(second_from_chain - second_exact))), + "bps_energy_error": float(np.max(np.abs(energy + 1.0))), + } + + +def canonical_payload(config: PointwiseSolitonConfig | None = None) -> dict[str, Any]: + cfg = PointwiseSolitonConfig() if config is None else config + return { + "schema": SCHEMA, + "model_id": "M11", + "milestone": MILESTONE, + "model": "CAT/EPT pointwise soliton--Liouville--QDO particle model", + "configuration": asdict(cfg), + "construction_api": ( + "openwave.xperiments.m11_cat_ept_soliton_qdo." + "pointwise_soliton_carrier_m111:construct_pointwise_soliton" + ), + "study_api": ( + "openwave.xperiments.m11_cat_ept_soliton_qdo." + "pointwise_soliton_carrier_m111:run_pointwise_soliton_study" + ), + "formal_authority": { + "repository": "jagg-ix/entropic-physlib-private", + "branch": "entropic-physlib-linear-full", + "head": FORMAL_HEAD, + "sources": list(FORMAL_SOURCES), + }, + } + + +def fingerprint(payload: Mapping[str, Any] | None = None) -> str: + selected = canonical_payload() if payload is None else dict(payload) + return sha256(_canonical_json(selected).encode()).hexdigest() + + +def run_pointwise_soliton_study( + config: PointwiseSolitonConfig | None = None, +) -> dict[str, Any]: + state = construct_pointwise_soliton(config) + cfg = state.config + norm = float(np.trapezoid(state.density, state.x)) + residual = state.stationary_residual() + wave = state.wave(cfg.sample_time) + analytic_dt = (-1.0j * state.chemical_potential / cfg.hbar) * wave + time_equation = 1.0j * cfg.hbar * analytic_dt - state.chemical_potential * wave + bps = sinh_gordon_bps_control() + half_max = state.density.max() / 2.0 + support = state.x[state.density >= half_max] + fwhm = float(support[-1] - support[0]) + kinetic = cfg.dispersion * np.abs( + -cfg.inverse_width * np.tanh(cfg.inverse_width * state.x) * state.psi + ) ** 2 + interaction = -0.5 * state.cubic_coupling * state.density**2 + energy = float(np.trapezoid(kinetic + interaction, state.x)) + diagnostics = { + "normalization_error": abs(norm - 1.0), + "stationary_residual_linf": float(np.max(np.abs(residual))), + "standing_wave_time_error": float(np.max(np.abs(time_equation))), + "density_time_invariance_error": float(np.max(np.abs(np.abs(wave) ** 2 - state.density))), + "fwhm": fwhm, + "energy": energy, + "chemical_potential": state.chemical_potential, + "cubic_coupling": state.cubic_coupling, + **bps, + } + acceptance = { + "normalized": diagnostics["normalization_error"] < 5.0e-13, + "pointwise_stationary_equation": diagnostics["stationary_residual_linf"] < 5.0e-13, + "standing_wave_equation": diagnostics["standing_wave_time_error"] < 5.0e-13, + "density_is_stationary": diagnostics["density_time_invariance_error"] < 5.0e-13, + "localized": 0.5 < fwhm < 4.0, + "bps_reduction": diagnostics["bps_second_order_error"] < 5.0e-13, + "bps_energy": diagnostics["bps_energy_error"] < 5.0e-13, + } + payload = canonical_payload(cfg) + return { + **payload, + "task": "M11.1", + "diagnostics": diagnostics, + "acceptance": acceptance, + "fingerprint": fingerprint(payload), + "passed": all(acceptance.values()), + } diff --git a/openwave/xperiments/m11_cat_ept_soliton_qdo/research/zil/m11_pointwise_soliton_m111.zc b/openwave/xperiments/m11_cat_ept_soliton_qdo/research/zil/m11_pointwise_soliton_m111.zc new file mode 100644 index 00000000..7c81deb1 --- /dev/null +++ b/openwave/xperiments/m11_cat_ept_soliton_qdo/research/zil/m11_pointwise_soliton_m111.zc @@ -0,0 +1,6 @@ +model:m11#milestone@m11.1. +model:m11.1#carrier@pointwise:bright-soliton. +pointwise:bright-soliton#satisfies@equation:cubic-nls-stationary. +pointwise:bright-soliton#standing-wave@equation:time-dependent-phase. +pointwise:bright-soliton#controlled-by@lean:SinhGordonSoliton.bps_implies_sinhGordon. +pointwise:bright-soliton#bridged-to@lean:SelfBoundSchrodingerNewtonPDE.standingWave_solves_full_schrodingerNewton. diff --git a/tests/test_m11_pointwise_soliton_m111.py b/tests/test_m11_pointwise_soliton_m111.py new file mode 100644 index 00000000..de365f2c --- /dev/null +++ b/tests/test_m11_pointwise_soliton_m111.py @@ -0,0 +1,6 @@ +from openwave.xperiments.m11_cat_ept_soliton_qdo.pointwise_soliton_carrier_m111 import run_pointwise_soliton_study + +def test_pointwise_soliton_campaign(): + result=run_pointwise_soliton_study() + assert result['passed'], result + assert result['diagnostics']['stationary_residual_linf'] < 5e-13