feat(SR): complete article-grade symbolic regression evidence

Freeze the contract-audited discovery, closed-loop validation, robustness, plotting, and manuscript evidence so the SR section is reproducible and ready for paper development.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Frank14f
2026-07-21 20:06:13 +08:00
co-authored by Cursor
parent ca8ee5f238
commit eac8c0018e
1039 changed files with 292934 additions and 1496 deletions
+245 -72
View File
@@ -1,81 +1,254 @@
# SR_analysis: Symbolic Regression for DRL Flow Control
# SR analysis: agent entry point
Extracts interpretable control laws (obs -> act) from DRL-trained PPO policies
for the fluidic pinball using PySR symbolic regression. Validates all formulas
in CFD closed-loop and produces publication-quality figures.
This directory contains the active symbolic-regression analysis for extracting compact control laws from the legacy PPO policies of the fluidic pinball.
## Pipeline
**Start here, then read `PIPELINE.md`.** The active scientific workflow has exactly three entry points:
```
stage_1_infer.py -> stage_2_fit.py -> stage_3_validate.py -> stage_4_analyze.py
(PPO data) (PySR formula) (CFD closed-loop) (paper figures)
1. `stage_1_infer.py` — collect run-scoped PPO trajectories.
2. `stage_2_fit.py` — discover and refit symbolic structures.
3. `stage_3_validate.py` — evaluate formulas in closed-loop CFD with the legacy DTW metric.
The current article evidence is indexed in `results/README.md`. The manuscript-ready SR section is `../../docs/JFM_WYQ/SR_Draft.md`.
## Scientific question
SR is not used to maximize imitation of PPO actions. It is used to determine whether successful PPO control contains a compact, symmetric and physically interpretable feedback structure that remains effective when deployed in CFD.
The selection chain is therefore:
```text
PPO trajectories
-> broad per-case variable/topology discovery using R² and Pareto fronts
-> within-objective joint topology discovery
-> fixed-topology coefficient refit using all accepted rows
-> short and standard closed-loop CFD screening using legacy DTW
-> term-deletion and coefficient-scaling tests
-> physical interpretation and explicit limitations
```
## Quick Start
R² is a discovery diagnostic. It is not the acceptance criterion. Closed-loop stability and DTW decide whether a candidate is useful; deletion and scaling tests decide whether its terms are necessary.
## Current article scope
Two objectives are fitted separately:
- **Kármán cloaking:** `karman_re50`, `karman_re100`, `karman_re200`, `karman_re400`.
- **Illusion:** `illusion_0.75L`, `illusion_1L`, `illusion_1.5L`.
Kármán and Illusion are never pooled into one fit. The fitted evidence is limited to these seven training scenes. The coefficient-frozen 2026-07-20 extension tests additional Reynolds-number and target-size points, but those points did not participate in fitting or model selection. Vortex, V5 and historical figures remain outside the current article evidence.
Seven new 200-step PPO trajectories were collected in:
- `data/runs/article-joint-data-karman-20260718/`
- `data/runs/article-joint-data-illusion-20260718/`
All seven passed exact recorded-state policy replay. The accepted data inventory is:
- `results/runs/article-joint-data-audit-20260718/data_inventory.json`
Historical and round-one assets are retained, but are not silently pooled with the article data. The old `round1-legacy-v2-20260716-*` formulas are diagnostic only because they predate the final force-order contract.
## Non-negotiable contracts
### Native order
The canonical body, force and action order is:
```text
front, upper, lower
```
Sensors are ordered upper, centre, lower. Verify runtime binding with `checks/order_contract.py` before collecting data after any CFD change.
### Alignment
The article workflow uses:
```text
causal_post_state_to_next_action
```
Recorded post-state `i` predicts action `i+1`. Each trajectory is built independently so lag features and contiguous splits never cross trajectory boundaries.
### Action definition
Formula outputs are dimensionless cylinder surface velocities:
\[
\alpha_i = \omega_i/U_0.
\]
Normalized PPO actions are decoded with the scene action scale and bias before fitting.
### Exact reflection symmetry
The article candidate uses mapped-shared deployment:
\[
\alpha_F(x)=\frac{h_F(x)-h_F(Gx)}{2},\qquad
\alpha_U(x)=h_R(x),\qquad
\alpha_L(x)=-h_R(Gx).
\]
The front projection is exactly odd. The lower action is generated from the shared upper law. Three-head-independent fitting exists only as a PPO-structure diagnostic and is not the final physical architecture.
Fit augmentation and deployment architecture are separate choices:
- `--fit-augmentation none|G`
- `--deployment-architecture mapped_shared|three_head_independent`
Hard G symmetry is a deliberate physical symmetrization; it is not presented as a property that the legacy PPO was trained to satisfy.
### Metric
The closed-loop metric is:
```text
legacy_dtw_v1_abs_n_unclipped
```
Its exact window is named:
```text
legacy_reference_cycle_vs_last_recorded_cycle
```
There are not separate “full” and “tail” DTW algorithms. Lag is part of the legacy comparison procedure and is not interpreted as a physical observation/control delay.
## Physical labels and units
The Kármán scene names contain the historical code Reynolds label `re_code`, defined with reference length `2D`; the cylinder-diameter Reynolds number is therefore \(Re_D=\texttt{re\_code}/2\). The Illusion names `0.75L`, `1L` and `1.5L` are legacy target-size labels: the stored `target_diameter` value is passed to `LegacyCelerisLab.add_cylinder` as a radius. Paper text must not silently reinterpret these labels as physical diameters.
SR uses dimensionless velocities and force coefficients, not the clipped PPO observation. Rear symmetry coordinates are half-sums and half-differences, for example
\[
C_{d,\mathrm{rear},s}=\frac{C_{d,U}+C_{d,L}}{2},\qquad
C_{d,\mathrm{rear},a}=\frac{C_{d,U}-C_{d,L}}{2},
\]
with the same convention for rear lift.
## Feature strategy
Broad discovery starts from complete, dimensionless variable representations:
- `raw_complete`: six velocity components and six cylinder-force components.
- `symmetry`: symmetric/antisymmetric velocity and force coordinates.
- `physics_reduced`: compact diagnostics only; it is not the starting point for article discovery.
Illusion comparisons use non-overlapping profiles:
- `actual_only`
- `target_only`
- `actual_plus_target`
- `actual_plus_error`
Target/error derivatives or other temporal features are added only after static variables are shown insufficient. Cross-correlation is never used to select a lag.
## Current results
### Kármán joint candidate
\[
\alpha_F=\operatorname{odd}\!\left[-0.381391\,C_{d,\mathrm{rear},a}\right],
\]
\[
\alpha_U=1.307782\,C_{l,\mathrm{rear},s}-3.431209,
\qquad
\alpha_L=-\alpha_U(Gx).
\]
Standard 200-step legacy DTW:
- Re50: `0.9543`
- Re100: `0.9427`
- Re200: `0.8560`
- Re400: `0.7827`
Deletion tests support the ordering:
```text
rear constant > rear lift feedback > front drag-asymmetry feedback
```
This is consistent with the physical hypothesis that persistent rear counter-rotation provides the principal downstream velocity-deficit compensation. The SR evidence ranks controller terms but does not establish the spatial momentum correction or causality; those claims require OID/CCD. The law is not uniformly strong at Re400 and must not be called universal.
### Illusion joint numerical candidate
\[
\alpha_F=\operatorname{odd}\!\left[-1.826604\,C_{d,\mathrm{rear},a}+2.064493\,C_{l,F}\right],
\]
\[
\alpha_U=1.254440\,C_{d,\mathrm{rear},a}-1.528074\,C_{l,F},
\qquad
\alpha_L=-\alpha_U(Gx).
\]
Standard 200-step legacy DTW:
- 0.75L: `0.8749`
- 1.0L: `0.9217`
- 1.5L: `0.8306`
Scaling tests show that the `Cl_F` terms dominate action magnitude; the `Cd_rear,a` terms are weaker and partly replaceable. Every one-term deletion remained stable, so the current expression is not a unique mechanism law. Target/error variables were available but were not selected stably by low-complexity static joint discovery. This is a numerical joint reference, not proof of explicit target tracking.
## What can and cannot be claimed
Supported:
- A complete, reproducible discovery-to-CFD-to-ablation workflow.
- Strong Kármán evidence for dominant rear counter-rotation and secondary rear lift feedback.
- A symmetric Illusion joint family that remains finite across all three trained target-size labels.
- R² and formula appearance alone are insufficient predictors of closed-loop value.
Not supported:
- Global symbolic optimality or uniqueness.
- A universal Kármán law at Re400.
- An explicit target-tracking mechanism for Illusion.
- Necessity of every Illusion term.
- Physical delay inferred from DTW lag or cross-correlation.
- Distribution-wide or universal generalization. The Article2 extension supports only finite pointwise deployment at its explicitly sampled unseen conditions.
## Directory map
```text
SR_analysis/
├── README.md # this agent entry point
├── PIPELINE.md # exact method, commands and design decisions
├── configs.py # scene and action contracts
├── stage_1_infer.py # PPO data collection
├── stage_2_fit.py # discovery and fixed-topology refit
├── stage_3_validate.py # closed-loop CFD and legacy DTW
├── checks/ # pre-fit physical/wiring gates
├── diagnostics/ # diagnostic-only analyses
├── utils/ # feature, G, formula, data and provenance contracts
├── tests/ # SR CPU contract tests
├── results/README.md # evidence index and result status
├── tools/ # integrity audit; audit is not scientific promotion
├── experiments/v5/ # excluded experimental pipeline
└── archive/ # inactive Stage 4 and historical guides
```
`old/`, `archive/`, `experiments/v5/`, historical formula directories and old reports are context only. They are not authoritative sources for article numbers.
## Environments and resource discipline
- Stage 1, policy replay and Stage 3: `pycuda_3_10`; PPO inference defaults to CPU so physical GPU 2 remains dedicated to the PyCUDA CFD context.
- Stage 2/PySR and coefficient refit: `sr_env`.
- CFD uses physical GPU 2 and is strictly serial.
- When `CUDA_VISIBLE_DEVICES=2`, the process uses logical device `0`; provenance records both visibility and GPU UUID rather than mislabelling the physical ordinal.
- Every run ID is immutable; failed telemetry is retained.
## Verification
At the 2026-07-21 plotting-package revision, the SR contract suite contains 88 passing tests. Run from the repository root:
```bash
# Generate PPO inference data
conda run -n pycuda_3_10 python stage_1_infer.py --scene karman_re100 --device 2
# Fit symbolic formula
conda run -n sr_env python stage_2_fit.py --scenes illusion_0.75L,illusion_1L --mode joint --deep
# Validate in CFD
conda run -n pycuda_3_10 python stage_3_validate.py \
--scene illusion_1L --device 2 --mode pysr \
--formula-front results/formulas/illusion_joint_front.json \
--formula-top results/formulas/illusion_joint_top.json
# Generate figures
conda run -n pycuda_3_10 python stage_4_analyze.py
PYTHONPATH=src conda run -n sr_env python -m pytest \
src/SR_analysis/tests tests/test_stage_3_validate.py -q
```
## Directory Structure
```
SR_analysis/
stage_1_infer.py # PPO inference (all scenes)
stage_2_fit.py # PySR symbolic regression fitting
stage_3_validate.py # CFD closed-loop validation
stage_4_analyze.py # Publication figure generation
configs.py # All scene definitions (19 scenes)
scene_registry.json # Canonical results registry
utils/ # Shared library (features, CFD, fitting)
data/ # Runtime .npz data per scene
results/
formulas/ # Canonical formula JSONs
validations/ # CFD validation outputs
figures/ # Publication-quality PNG/PDF
FIGURE_INDEX.md # Figure catalog with captions
README.md # Formula + validation index
docs/
SR_analysis_report.md # Full analysis report
illusion_joint_formula_analysis.md
PIPELINE.md # Detailed reproduction guide
literature_note.md # Paper writing + literature positioning
old/ # Archived historical files
```
## Key Results
| Scene | Formula | CFD Similarity |
|-------|---------|:---:|
| Karman cross-Re (joint) | alpha_F = daF_dt - 14.95*mu*Cl_tot | avg 0.847 |
| Illusion joint (0.75L+1L) | alpha_F = Cd_tot - Cd_err - 5.43 + 0.01*(du_a_dt+u_a) | 0.978/0.970 |
| Vortex lamb (Karman formula) | Karman joint, zero retraining | 0.949 (exceeds PPO) |
## Environments
- `pycuda_3_10`: CFD + DRL model loading + visualization (stages 1, 3, 4)
- `sr_env`: PySR symbolic regression (stage 2)
- GPU: device 2 recommended
## Documentation
| File | Content |
|------|---------|
| `PIPELINE.md` | Full reproduction guide with all commands |
| `docs/SR_analysis_report.md` | Complete methodology + results + discussion |
| `results/figures/FIGURE_INDEX.md` | All figures with paper-ready captions |
| `literature_note.md` | Literature positioning + writing guidance |
| `results/README.md` | Formula + validation file index |
See `PIPELINE.md` for reproducible commands and `results/README.md` for the exact evidence chain.