adcd 2.1.2__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adcd-2.2.0/PKG-INFO +278 -0
- adcd-2.2.0/README.md +237 -0
- {adcd-2.1.2 → adcd-2.2.0}/pyproject.toml +4 -1
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/__init__.py +10 -1
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/anomaly_scenarios.py +216 -4
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/api.py +1 -2
- adcd-2.2.0/src/adcd/bayesian_ranker.py +161 -0
- adcd-2.2.0/src/adcd/buckingham_pi.py +113 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/correction_orchestrator.py +72 -5
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/dimensional_checker.py +101 -2
- adcd-2.2.0/src/adcd/grammar_proposer.py +364 -0
- adcd-2.2.0/src/adcd/identifiability.py +164 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/llm_proposer.py +73 -12
- adcd-2.2.0/src/adcd/multivar_orchestrator.py +268 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/pipeline.py +28 -3
- adcd-2.2.0/src/adcd/product_grammar.py +157 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/residual_analyzer.py +78 -2
- adcd-2.2.0/src/adcd/residual_factorizer_v2.py +70 -0
- adcd-2.2.0/src/adcd/sequential_arc.py +76 -0
- adcd-2.2.0/src/adcd.egg-info/PKG-INFO +278 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd.egg-info/SOURCES.txt +12 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd.egg-info/entry_points.txt +1 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd.egg-info/requires.txt +2 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_api.py +0 -1
- adcd-2.2.0/tests/test_bayesian_ranker.py +87 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_correction_discovery.py +12 -5
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_dimensional_checker.py +21 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_gate_telemetry.py +0 -2
- adcd-2.2.0/tests/test_grammar_proposer.py +59 -0
- adcd-2.2.0/tests/test_identifiability.py +116 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_integration.py +0 -1
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_jax_optimizer.py +3 -4
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_metrics_scale.py +0 -1
- adcd-2.2.0/tests/test_multivar_arc.py +45 -0
- adcd-2.2.0/tests/test_phase2_components.py +124 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_real_data.py +0 -1
- adcd-2.1.2/PKG-INFO +0 -295
- adcd-2.1.2/README.md +0 -256
- adcd-2.1.2/src/adcd.egg-info/PKG-INFO +0 -295
- adcd-2.1.2/tests/test_multivar_arc.py +0 -45
- {adcd-2.1.2 → adcd-2.2.0}/LICENSE +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/setup.cfg +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/arc_scorer.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/coarse_evaluator.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/feynman_dataset.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/jax_optimizer.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/metrics.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/mode_detection.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/orchestrator.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/real_data_loader.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/real_scenarios.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd/result.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd.egg-info/dependency_links.txt +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/src/adcd.egg-info/top_level.txt +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_arc_scorer.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_coarse_evaluator.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_paper_claims.py +0 -0
- {adcd-2.1.2 → adcd-2.2.0}/tests/test_pipeline.py +0 -0
adcd-2.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adcd
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: Anomaly-Driven Correction Discovery: Physics-Constrained Symbolic Regression for Evolutionary Scientific Discovery
|
|
5
|
+
Author-email: Muhammad Afif Erdita <maeapip10@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://zenodo.org/records/20534940
|
|
8
|
+
Project-URL: Repository, https://github.com/apiprdt/PhysicsPaper
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/apiprdt/PhysicsPaper/issues
|
|
10
|
+
Project-URL: DOI, https://doi.org/10.5281/zenodo.20534940
|
|
11
|
+
Keywords: symbolic regression,physics,machine learning,scientific discovery,JAX
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: numpy>=1.24
|
|
24
|
+
Requires-Dist: scipy>=1.11
|
|
25
|
+
Requires-Dist: sympy>=1.12
|
|
26
|
+
Requires-Dist: jax>=0.4.20
|
|
27
|
+
Requires-Dist: jaxlib>=0.4.20
|
|
28
|
+
Requires-Dist: matplotlib>=3.7
|
|
29
|
+
Requires-Dist: scikit-learn>=1.3
|
|
30
|
+
Requires-Dist: pandas>=1.5
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=4.1; extra == "dev"
|
|
34
|
+
Requires-Dist: flake8>=6.1; extra == "dev"
|
|
35
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
36
|
+
Provides-Extra: llm
|
|
37
|
+
Requires-Dist: google-generativeai>=0.3; extra == "llm"
|
|
38
|
+
Provides-Extra: all
|
|
39
|
+
Requires-Dist: adcd[dev,llm]; extra == "all"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# ADCD — Anomaly-Driven Correction Discovery
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<img src="docs/assets/adcd_logo.svg" alt="ADCD Logo" width="160">
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<p align="center">
|
|
49
|
+
<strong>Physics-Constrained Symbolic Regression for Evolutionary Scientific Discovery</strong>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<a href="https://github.com/apiprdt/PhysicsPaper/actions/workflows/ci.yml"><img src="https://github.com/apiprdt/PhysicsPaper/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
|
|
54
|
+
<a href="https://pypi.org/project/adcd/"><img src="https://img.shields.io/pypi/v/adcd?color=teal" alt="PyPI Version"></a>
|
|
55
|
+
<a href="https://doi.org/10.5281/zenodo.20534940"><img src="https://img.shields.io/badge/DOI-10.5281%2Fzenodo.20534940-blue" alt="DOI"></a>
|
|
56
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
57
|
+
<a href="https://github.com/apiprdt/PhysicsPaper/actions"><img src="https://img.shields.io/badge/tests-95%20passing-brightgreen" alt="Tests Status"></a>
|
|
58
|
+
<a href="https://pypi.org/project/adcd/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python Support"></a>
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
<p align="center">
|
|
62
|
+
<a href="https://apiprdt.github.io/PhysicsPaper/"><strong>Explore the Documentation »</strong></a>
|
|
63
|
+
<br>
|
|
64
|
+
<br>
|
|
65
|
+
<a href="#quick-start">Quick Start</a>
|
|
66
|
+
·
|
|
67
|
+
<a href="#key-features">Key Features</a>
|
|
68
|
+
·
|
|
69
|
+
<a href="#benchmark-results">Benchmarks</a>
|
|
70
|
+
·
|
|
71
|
+
<a href="https://colab.research.google.com/github/apiprdt/PhysicsPaper/blob/main/notebooks/adcd_demo.ipynb">Run in Colab</a>
|
|
72
|
+
</p>
|
|
73
|
+
|
|
74
|
+
> **Science rarely discovers from a blank slate — it corrects.**
|
|
75
|
+
> ADCD automates the step between *anomaly* and *theory correction*, the same step that led from Newtonian gravity to General Relativity, from Dirac to QED, and from Rayleigh-Jeans to Planck.
|
|
76
|
+
|
|
77
|
+
<p align="center">
|
|
78
|
+
<img src="docs/adcd_discovery.gif" alt="ADCD discovery pipeline animation" width="85%">
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## ⚡ Key Features
|
|
84
|
+
|
|
85
|
+
- **Correction-First Paradigm** — Starts from a known classical law, not a blank slate. Focuses the search space on the discrepancy $\Delta$ between theory and experiment.
|
|
86
|
+
- **Cascaded Physics Gates** — AST complexity, dimensional homogeneity, transcendental guardrails, and asymptotic consistency (ARC) gates screen out unphysical candidates *before* running parameter-fitting.
|
|
87
|
+
- **JAX-Traced L-BFGS-B Optimizer** — Highly optimized parameter-scaled differentiable fitting with multi-restart log-uniform initialization.
|
|
88
|
+
- **BIC Model Selection** — Employs the Bayesian Information Criterion (BIC) to rank models, favoring simpler physical theories over overly complex numerical fits.
|
|
89
|
+
- **Residual Feature Intelligence** — Extracts mathematical features (monotonicity, curvature, oscillation, decay) from residuals to bias proposal templates.
|
|
90
|
+
- **Phase 2: Multivariable Discovery** — Buckingham Π group decomposition + per-variable Sequential ARC + variance-factorization separability detection for multi-input physical laws.
|
|
91
|
+
- **Real-World Validated** — Successfully identifies correct structural classes on Mercury's perihelion (GR), Lamb Shift (QED), Muon g-2 (Schwinger), and Blackbody (Planck).
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 📦 Installation
|
|
96
|
+
|
|
97
|
+
Install the stable package from PyPI:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install adcd
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Or install from source:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git clone https://github.com/apiprdt/PhysicsPaper.git
|
|
107
|
+
cd PhysicsPaper
|
|
108
|
+
pip install -e ".[dev]"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Verify your installation:
|
|
112
|
+
```bash
|
|
113
|
+
pytest tests/
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 💻 Quick Start
|
|
119
|
+
|
|
120
|
+
### 1. High-Level Scientific API
|
|
121
|
+
|
|
122
|
+
Running ADCD on predefined physics benchmarks is extremely simple:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
import adcd
|
|
126
|
+
|
|
127
|
+
# 1. Load a pre-defined benchmark scenario (e.g. Relativistic Kinetic Energy)
|
|
128
|
+
scenarios = adcd.get_all_scenarios()
|
|
129
|
+
scenario = scenarios[0]
|
|
130
|
+
|
|
131
|
+
# 2. Run discovery in a single line!
|
|
132
|
+
result = adcd.discover_correction(scenario, max_iterations=5, proposer="mock")
|
|
133
|
+
|
|
134
|
+
# 3. View the best fit
|
|
135
|
+
print(f"Discovered correction: {result.best_expr}") # θ₀ * (v/c)**2
|
|
136
|
+
print(f"LaTeX representation: {result.export_latex()}") # \theta_0 \left(\frac{v}{c}\right)^2
|
|
137
|
+
print(f"Parameters: {result.best_theta}")
|
|
138
|
+
print(f"BIC Score: {result.best_bic:.2f}")
|
|
139
|
+
|
|
140
|
+
# 4. Plot residuals
|
|
141
|
+
result.plot_residuals()
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 2. Custom Experimental Datasets
|
|
145
|
+
|
|
146
|
+
For custom datasets, use the `adcd.fit` function:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
import numpy as np
|
|
150
|
+
import adcd
|
|
151
|
+
|
|
152
|
+
# Your custom data
|
|
153
|
+
x = np.linspace(1.0, 5.0, 100)
|
|
154
|
+
X = {"x": x}
|
|
155
|
+
y_classical = 2.0 * x
|
|
156
|
+
y_observed = 2.0 * x + 0.5 * x**2 # True correction is 0.5 * x^2
|
|
157
|
+
|
|
158
|
+
# Run ADCD
|
|
159
|
+
result = adcd.fit(
|
|
160
|
+
X=X,
|
|
161
|
+
y_obs=y_observed,
|
|
162
|
+
y_classical=y_classical,
|
|
163
|
+
limit_variable="x",
|
|
164
|
+
limit_direction="0",
|
|
165
|
+
correction_mode="additive"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
result.summary()
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 📊 Benchmark Results
|
|
174
|
+
|
|
175
|
+
### 1. Standard Benchmark (seed=42, Mock Proposer)
|
|
176
|
+
|
|
177
|
+
| Scenario | Tier | 0% Noise | 1% Noise | 5% Noise | 10% Noise |
|
|
178
|
+
|----------|------|:--------:|:--------:|:--------:|:---------:|
|
|
179
|
+
| Relativistic KE | Textbook | ✓ | ✓ | ✓ | ✓ |
|
|
180
|
+
| Yukawa Gravity | Textbook | ✓ | ✓ | ✓ | ✓ |
|
|
181
|
+
| Anharmonic Spring | Textbook | ✓ | ✓ | ✓ | ✓ |
|
|
182
|
+
| Screened Coulomb | Cross-Domain | ✓ | ✓ | ✗ | ✗ |
|
|
183
|
+
| Net Radiation | Cross-Domain | ✓ | ✓ | ✓ | ✓ |
|
|
184
|
+
| Nonlinear Drag | Cross-Domain | ✓ | ✓ | ✓ | ✓ |
|
|
185
|
+
| Mystery-A (tanh²) | Synthetic | ✓ | ✓ | ✓ | ✓ |
|
|
186
|
+
| Mystery-B (sinc) | Synthetic | ✓ | ✓ | ✓ | ✓ |
|
|
187
|
+
| Mystery-C (log-quotient) | Synthetic | ✓ | ✓ | ✓ | ✓ |
|
|
188
|
+
| **Overall** | | **100%** | **100%** | **88.9%** | **88.9%** |
|
|
189
|
+
|
|
190
|
+
### 2. PySR Comparison (fair profile: 100 iterations, 60s timeout)
|
|
191
|
+
|
|
192
|
+
| Method | 0% Noise | 1% Noise | 5% Noise | 10% Noise |
|
|
193
|
+
|--------|:--------:|:--------:|:--------:|:---------:|
|
|
194
|
+
| **ADCD** (ours, seed=42) | **9/9 (100%)** | **9/9 (100%)** | **8/9 (88.9%)** | **8/9 (88.9%)** |
|
|
195
|
+
| PySR fair | 4/9 (44.4%) | 5/9 (55.6%) | 1/9 (11.1%) | 5/9 (55.6%) |
|
|
196
|
+
|
|
197
|
+
ADCD outperforms PySR by **+77.8 percentage points** at 5% noise.
|
|
198
|
+
|
|
199
|
+
### 3. Phase 2: Multivariable Benchmark (v2.2.0)
|
|
200
|
+
|
|
201
|
+
| Scenario | Variables | ADCD Solved | Notes |
|
|
202
|
+
|----------|-----------|:-----------:|-------|
|
|
203
|
+
| Yukawa Mass-Ratio | m, M, r, r₀ | ✓ | Π groups: m/M, r/r₀ |
|
|
204
|
+
| Turbulent Drag | v, ρ, A, C_D | ✓ | Separable multiplicative |
|
|
205
|
+
| Coupled Oscillator | k, m, Ω, ω₀ | ✗ | Mixed functional form |
|
|
206
|
+
| Van der Waals MV | a, b, P, V, T | ✗ | Requires 3rd Π group |
|
|
207
|
+
| **Overall** | | **2/4 (50%)** | Baseline: 0/4 |
|
|
208
|
+
|
|
209
|
+
### 4. Real-World Physical Constants
|
|
210
|
+
|
|
211
|
+
Validation on historical anomalies using physical constants from JPL DE440, NIST, and CODATA:
|
|
212
|
+
|
|
213
|
+
| Physical Scenario | Discovered Correction | Converged | Class Match | NMSE |
|
|
214
|
+
|---|---|:---:|:---:|:---:|
|
|
215
|
+
| Mercury Perihelion (GR) | `θ₀·vc²` | — | ✓ polynomial | 1.11e-05 |
|
|
216
|
+
| Hydrogen Lamb Shift (QED) | `θ₀(n/θ₁)^(-θ₂)` | ✓ | ✓ power_law | 1.82e-18 |
|
|
217
|
+
| Muon g-2 (Schwinger) | `θ₀(α/π)^θ₁` | ✓ | ✓ polynomial | 7.94e-07 |
|
|
218
|
+
| Blackbody (Planck) | `-1 + e^(-f/θ₁)` | — | ✓ exponential | 2.59e-02 |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 📁 Project Structure
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
PhysicsPaper/
|
|
226
|
+
├── src/adcd/ # Installable package
|
|
227
|
+
│ ├── __init__.py # Public API (fit, discover_correction)
|
|
228
|
+
│ ├── anomaly_scenarios.py # 9 standard + 3 blind + 4 multivariable scenarios
|
|
229
|
+
│ ├── arc_scorer.py # Asymptotic consistency gate (ARC)
|
|
230
|
+
│ ├── buckingham_pi.py # [Phase 2] Buckingham Π group engine
|
|
231
|
+
│ ├── coarse_evaluator.py # Coarse numerical pre-filter
|
|
232
|
+
│ ├── correction_orchestrator.py # Main multi-iteration discovery loop
|
|
233
|
+
│ ├── dimensional_checker.py # Dimensional homogeneity + transcendental gate
|
|
234
|
+
│ ├── jax_optimizer.py # JAX L-BFGS-B optimizer
|
|
235
|
+
│ ├── llm_proposer.py # Mock + Gemini + OpenAI proposers
|
|
236
|
+
│ ├── metrics.py # NMSE, BIC, structural classification
|
|
237
|
+
│ ├── multivar_orchestrator.py # [Phase 2] Multivariable correction pipeline
|
|
238
|
+
│ ├── pipeline.py # Stage 1 filter cascade
|
|
239
|
+
│ ├── real_data_loader.py # Real-world data loading (JPL, NIST, CODATA)
|
|
240
|
+
│ ├── residual_factorizer_v2.py # [Phase 2] Variance-decomposition separability
|
|
241
|
+
│ ├── result.py # CorrectionResult object
|
|
242
|
+
│ └── sequential_arc.py # [Phase 2] Per-variable Sequential ARC checker
|
|
243
|
+
├── tests/ # 95 unit + integration tests
|
|
244
|
+
├── paper/ # LaTeX source (main.tex) + figures
|
|
245
|
+
├── run_correction_discovery.py # Benchmark runner
|
|
246
|
+
└── README.md # This file
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 📖 Citing This Work
|
|
252
|
+
|
|
253
|
+
If you use ADCD in your research, please cite:
|
|
254
|
+
|
|
255
|
+
```bibtex
|
|
256
|
+
@software{erdita2026adcd,
|
|
257
|
+
author = {Erdita, Muhammad Afif},
|
|
258
|
+
title = {{Anomaly-Driven Correction Discovery (ADCD): Physics-Constrained
|
|
259
|
+
Symbolic Regression for Evolutionary Scientific Discovery}},
|
|
260
|
+
year = {2026},
|
|
261
|
+
publisher = {Zenodo},
|
|
262
|
+
version = {2.1.3},
|
|
263
|
+
doi = {10.5281/zenodo.20534940},
|
|
264
|
+
url = {https://doi.org/10.5281/zenodo.20534940}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## 👥 AI Disclosure
|
|
271
|
+
|
|
272
|
+
This project was developed with assistance from Google DeepMind's Antigravity AI assistant. AI was used as a pair-programming and writing tool. All scientific content, experimental design decisions, and intellectual contributions are the author's own.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 📄 License
|
|
277
|
+
|
|
278
|
+
This project is licensed under the [MIT License](LICENSE).
|
adcd-2.2.0/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# ADCD — Anomaly-Driven Correction Discovery
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="docs/assets/adcd_logo.svg" alt="ADCD Logo" width="160">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Physics-Constrained Symbolic Regression for Evolutionary Scientific Discovery</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://github.com/apiprdt/PhysicsPaper/actions/workflows/ci.yml"><img src="https://github.com/apiprdt/PhysicsPaper/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
|
|
13
|
+
<a href="https://pypi.org/project/adcd/"><img src="https://img.shields.io/pypi/v/adcd?color=teal" alt="PyPI Version"></a>
|
|
14
|
+
<a href="https://doi.org/10.5281/zenodo.20534940"><img src="https://img.shields.io/badge/DOI-10.5281%2Fzenodo.20534940-blue" alt="DOI"></a>
|
|
15
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
16
|
+
<a href="https://github.com/apiprdt/PhysicsPaper/actions"><img src="https://img.shields.io/badge/tests-95%20passing-brightgreen" alt="Tests Status"></a>
|
|
17
|
+
<a href="https://pypi.org/project/adcd/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python Support"></a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="https://apiprdt.github.io/PhysicsPaper/"><strong>Explore the Documentation »</strong></a>
|
|
22
|
+
<br>
|
|
23
|
+
<br>
|
|
24
|
+
<a href="#quick-start">Quick Start</a>
|
|
25
|
+
·
|
|
26
|
+
<a href="#key-features">Key Features</a>
|
|
27
|
+
·
|
|
28
|
+
<a href="#benchmark-results">Benchmarks</a>
|
|
29
|
+
·
|
|
30
|
+
<a href="https://colab.research.google.com/github/apiprdt/PhysicsPaper/blob/main/notebooks/adcd_demo.ipynb">Run in Colab</a>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
> **Science rarely discovers from a blank slate — it corrects.**
|
|
34
|
+
> ADCD automates the step between *anomaly* and *theory correction*, the same step that led from Newtonian gravity to General Relativity, from Dirac to QED, and from Rayleigh-Jeans to Planck.
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<img src="docs/adcd_discovery.gif" alt="ADCD discovery pipeline animation" width="85%">
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ⚡ Key Features
|
|
43
|
+
|
|
44
|
+
- **Correction-First Paradigm** — Starts from a known classical law, not a blank slate. Focuses the search space on the discrepancy $\Delta$ between theory and experiment.
|
|
45
|
+
- **Cascaded Physics Gates** — AST complexity, dimensional homogeneity, transcendental guardrails, and asymptotic consistency (ARC) gates screen out unphysical candidates *before* running parameter-fitting.
|
|
46
|
+
- **JAX-Traced L-BFGS-B Optimizer** — Highly optimized parameter-scaled differentiable fitting with multi-restart log-uniform initialization.
|
|
47
|
+
- **BIC Model Selection** — Employs the Bayesian Information Criterion (BIC) to rank models, favoring simpler physical theories over overly complex numerical fits.
|
|
48
|
+
- **Residual Feature Intelligence** — Extracts mathematical features (monotonicity, curvature, oscillation, decay) from residuals to bias proposal templates.
|
|
49
|
+
- **Phase 2: Multivariable Discovery** — Buckingham Π group decomposition + per-variable Sequential ARC + variance-factorization separability detection for multi-input physical laws.
|
|
50
|
+
- **Real-World Validated** — Successfully identifies correct structural classes on Mercury's perihelion (GR), Lamb Shift (QED), Muon g-2 (Schwinger), and Blackbody (Planck).
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 📦 Installation
|
|
55
|
+
|
|
56
|
+
Install the stable package from PyPI:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install adcd
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or install from source:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/apiprdt/PhysicsPaper.git
|
|
66
|
+
cd PhysicsPaper
|
|
67
|
+
pip install -e ".[dev]"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Verify your installation:
|
|
71
|
+
```bash
|
|
72
|
+
pytest tests/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 💻 Quick Start
|
|
78
|
+
|
|
79
|
+
### 1. High-Level Scientific API
|
|
80
|
+
|
|
81
|
+
Running ADCD on predefined physics benchmarks is extremely simple:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import adcd
|
|
85
|
+
|
|
86
|
+
# 1. Load a pre-defined benchmark scenario (e.g. Relativistic Kinetic Energy)
|
|
87
|
+
scenarios = adcd.get_all_scenarios()
|
|
88
|
+
scenario = scenarios[0]
|
|
89
|
+
|
|
90
|
+
# 2. Run discovery in a single line!
|
|
91
|
+
result = adcd.discover_correction(scenario, max_iterations=5, proposer="mock")
|
|
92
|
+
|
|
93
|
+
# 3. View the best fit
|
|
94
|
+
print(f"Discovered correction: {result.best_expr}") # θ₀ * (v/c)**2
|
|
95
|
+
print(f"LaTeX representation: {result.export_latex()}") # \theta_0 \left(\frac{v}{c}\right)^2
|
|
96
|
+
print(f"Parameters: {result.best_theta}")
|
|
97
|
+
print(f"BIC Score: {result.best_bic:.2f}")
|
|
98
|
+
|
|
99
|
+
# 4. Plot residuals
|
|
100
|
+
result.plot_residuals()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 2. Custom Experimental Datasets
|
|
104
|
+
|
|
105
|
+
For custom datasets, use the `adcd.fit` function:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import numpy as np
|
|
109
|
+
import adcd
|
|
110
|
+
|
|
111
|
+
# Your custom data
|
|
112
|
+
x = np.linspace(1.0, 5.0, 100)
|
|
113
|
+
X = {"x": x}
|
|
114
|
+
y_classical = 2.0 * x
|
|
115
|
+
y_observed = 2.0 * x + 0.5 * x**2 # True correction is 0.5 * x^2
|
|
116
|
+
|
|
117
|
+
# Run ADCD
|
|
118
|
+
result = adcd.fit(
|
|
119
|
+
X=X,
|
|
120
|
+
y_obs=y_observed,
|
|
121
|
+
y_classical=y_classical,
|
|
122
|
+
limit_variable="x",
|
|
123
|
+
limit_direction="0",
|
|
124
|
+
correction_mode="additive"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
result.summary()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 📊 Benchmark Results
|
|
133
|
+
|
|
134
|
+
### 1. Standard Benchmark (seed=42, Mock Proposer)
|
|
135
|
+
|
|
136
|
+
| Scenario | Tier | 0% Noise | 1% Noise | 5% Noise | 10% Noise |
|
|
137
|
+
|----------|------|:--------:|:--------:|:--------:|:---------:|
|
|
138
|
+
| Relativistic KE | Textbook | ✓ | ✓ | ✓ | ✓ |
|
|
139
|
+
| Yukawa Gravity | Textbook | ✓ | ✓ | ✓ | ✓ |
|
|
140
|
+
| Anharmonic Spring | Textbook | ✓ | ✓ | ✓ | ✓ |
|
|
141
|
+
| Screened Coulomb | Cross-Domain | ✓ | ✓ | ✗ | ✗ |
|
|
142
|
+
| Net Radiation | Cross-Domain | ✓ | ✓ | ✓ | ✓ |
|
|
143
|
+
| Nonlinear Drag | Cross-Domain | ✓ | ✓ | ✓ | ✓ |
|
|
144
|
+
| Mystery-A (tanh²) | Synthetic | ✓ | ✓ | ✓ | ✓ |
|
|
145
|
+
| Mystery-B (sinc) | Synthetic | ✓ | ✓ | ✓ | ✓ |
|
|
146
|
+
| Mystery-C (log-quotient) | Synthetic | ✓ | ✓ | ✓ | ✓ |
|
|
147
|
+
| **Overall** | | **100%** | **100%** | **88.9%** | **88.9%** |
|
|
148
|
+
|
|
149
|
+
### 2. PySR Comparison (fair profile: 100 iterations, 60s timeout)
|
|
150
|
+
|
|
151
|
+
| Method | 0% Noise | 1% Noise | 5% Noise | 10% Noise |
|
|
152
|
+
|--------|:--------:|:--------:|:--------:|:---------:|
|
|
153
|
+
| **ADCD** (ours, seed=42) | **9/9 (100%)** | **9/9 (100%)** | **8/9 (88.9%)** | **8/9 (88.9%)** |
|
|
154
|
+
| PySR fair | 4/9 (44.4%) | 5/9 (55.6%) | 1/9 (11.1%) | 5/9 (55.6%) |
|
|
155
|
+
|
|
156
|
+
ADCD outperforms PySR by **+77.8 percentage points** at 5% noise.
|
|
157
|
+
|
|
158
|
+
### 3. Phase 2: Multivariable Benchmark (v2.2.0)
|
|
159
|
+
|
|
160
|
+
| Scenario | Variables | ADCD Solved | Notes |
|
|
161
|
+
|----------|-----------|:-----------:|-------|
|
|
162
|
+
| Yukawa Mass-Ratio | m, M, r, r₀ | ✓ | Π groups: m/M, r/r₀ |
|
|
163
|
+
| Turbulent Drag | v, ρ, A, C_D | ✓ | Separable multiplicative |
|
|
164
|
+
| Coupled Oscillator | k, m, Ω, ω₀ | ✗ | Mixed functional form |
|
|
165
|
+
| Van der Waals MV | a, b, P, V, T | ✗ | Requires 3rd Π group |
|
|
166
|
+
| **Overall** | | **2/4 (50%)** | Baseline: 0/4 |
|
|
167
|
+
|
|
168
|
+
### 4. Real-World Physical Constants
|
|
169
|
+
|
|
170
|
+
Validation on historical anomalies using physical constants from JPL DE440, NIST, and CODATA:
|
|
171
|
+
|
|
172
|
+
| Physical Scenario | Discovered Correction | Converged | Class Match | NMSE |
|
|
173
|
+
|---|---|:---:|:---:|:---:|
|
|
174
|
+
| Mercury Perihelion (GR) | `θ₀·vc²` | — | ✓ polynomial | 1.11e-05 |
|
|
175
|
+
| Hydrogen Lamb Shift (QED) | `θ₀(n/θ₁)^(-θ₂)` | ✓ | ✓ power_law | 1.82e-18 |
|
|
176
|
+
| Muon g-2 (Schwinger) | `θ₀(α/π)^θ₁` | ✓ | ✓ polynomial | 7.94e-07 |
|
|
177
|
+
| Blackbody (Planck) | `-1 + e^(-f/θ₁)` | — | ✓ exponential | 2.59e-02 |
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## 📁 Project Structure
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
PhysicsPaper/
|
|
185
|
+
├── src/adcd/ # Installable package
|
|
186
|
+
│ ├── __init__.py # Public API (fit, discover_correction)
|
|
187
|
+
│ ├── anomaly_scenarios.py # 9 standard + 3 blind + 4 multivariable scenarios
|
|
188
|
+
│ ├── arc_scorer.py # Asymptotic consistency gate (ARC)
|
|
189
|
+
│ ├── buckingham_pi.py # [Phase 2] Buckingham Π group engine
|
|
190
|
+
│ ├── coarse_evaluator.py # Coarse numerical pre-filter
|
|
191
|
+
│ ├── correction_orchestrator.py # Main multi-iteration discovery loop
|
|
192
|
+
│ ├── dimensional_checker.py # Dimensional homogeneity + transcendental gate
|
|
193
|
+
│ ├── jax_optimizer.py # JAX L-BFGS-B optimizer
|
|
194
|
+
│ ├── llm_proposer.py # Mock + Gemini + OpenAI proposers
|
|
195
|
+
│ ├── metrics.py # NMSE, BIC, structural classification
|
|
196
|
+
│ ├── multivar_orchestrator.py # [Phase 2] Multivariable correction pipeline
|
|
197
|
+
│ ├── pipeline.py # Stage 1 filter cascade
|
|
198
|
+
│ ├── real_data_loader.py # Real-world data loading (JPL, NIST, CODATA)
|
|
199
|
+
│ ├── residual_factorizer_v2.py # [Phase 2] Variance-decomposition separability
|
|
200
|
+
│ ├── result.py # CorrectionResult object
|
|
201
|
+
│ └── sequential_arc.py # [Phase 2] Per-variable Sequential ARC checker
|
|
202
|
+
├── tests/ # 95 unit + integration tests
|
|
203
|
+
├── paper/ # LaTeX source (main.tex) + figures
|
|
204
|
+
├── run_correction_discovery.py # Benchmark runner
|
|
205
|
+
└── README.md # This file
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 📖 Citing This Work
|
|
211
|
+
|
|
212
|
+
If you use ADCD in your research, please cite:
|
|
213
|
+
|
|
214
|
+
```bibtex
|
|
215
|
+
@software{erdita2026adcd,
|
|
216
|
+
author = {Erdita, Muhammad Afif},
|
|
217
|
+
title = {{Anomaly-Driven Correction Discovery (ADCD): Physics-Constrained
|
|
218
|
+
Symbolic Regression for Evolutionary Scientific Discovery}},
|
|
219
|
+
year = {2026},
|
|
220
|
+
publisher = {Zenodo},
|
|
221
|
+
version = {2.1.3},
|
|
222
|
+
doi = {10.5281/zenodo.20534940},
|
|
223
|
+
url = {https://doi.org/10.5281/zenodo.20534940}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 👥 AI Disclosure
|
|
230
|
+
|
|
231
|
+
This project was developed with assistance from Google DeepMind's Antigravity AI assistant. AI was used as a pair-programming and writing tool. All scientific content, experimental design decisions, and intellectual contributions are the author's own.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 📄 License
|
|
236
|
+
|
|
237
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "adcd"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.2.0"
|
|
8
8
|
description = "Anomaly-Driven Correction Discovery: Physics-Constrained Symbolic Regression for Evolutionary Scientific Discovery"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -30,6 +30,8 @@ dependencies = [
|
|
|
30
30
|
"jax>=0.4.20",
|
|
31
31
|
"jaxlib>=0.4.20",
|
|
32
32
|
"matplotlib>=3.7",
|
|
33
|
+
"scikit-learn>=1.3",
|
|
34
|
+
"pandas>=1.5",
|
|
33
35
|
]
|
|
34
36
|
|
|
35
37
|
[project.optional-dependencies]
|
|
@@ -51,6 +53,7 @@ Repository = "https://github.com/apiprdt/PhysicsPaper"
|
|
|
51
53
|
DOI = "https://doi.org/10.5281/zenodo.20534940"
|
|
52
54
|
|
|
53
55
|
[project.scripts]
|
|
56
|
+
adcd = "adcd.cli:main"
|
|
54
57
|
adcd-discover = "adcd.correction_orchestrator:main_cli"
|
|
55
58
|
|
|
56
59
|
[tool.setuptools.packages.find]
|
|
@@ -14,7 +14,7 @@ Quick Start
|
|
|
14
14
|
>>> print(result.best_expr)
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
-
__version__ = "2.
|
|
17
|
+
__version__ = "2.2.0"
|
|
18
18
|
__author__ = "Muhammad Afif Erdita"
|
|
19
19
|
__email__ = "maeapip10@gmail.com"
|
|
20
20
|
__license__ = "MIT"
|
|
@@ -54,6 +54,10 @@ from adcd.jax_optimizer import JAXOptimizer, OptimizationResult
|
|
|
54
54
|
from adcd.dimensional_checker import ASTValidator, DimensionalChecker
|
|
55
55
|
from adcd.arc_scorer import ARCScorer, AsymptoticRegime, build_arc_regimes
|
|
56
56
|
|
|
57
|
+
# Bayesian output (Phase 3)
|
|
58
|
+
from adcd.bayesian_ranker import BayesianReranker, BayesianCorrectionOutput
|
|
59
|
+
from adcd.identifiability import IdentifiabilityAnalyzer, IdentifiabilityReport
|
|
60
|
+
|
|
57
61
|
__all__ = [
|
|
58
62
|
# High-level API
|
|
59
63
|
"fit",
|
|
@@ -81,6 +85,11 @@ __all__ = [
|
|
|
81
85
|
"ARCScorer",
|
|
82
86
|
"AsymptoticRegime",
|
|
83
87
|
"build_arc_regimes",
|
|
88
|
+
# Bayesian output (Phase 3)
|
|
89
|
+
"BayesianReranker",
|
|
90
|
+
"BayesianCorrectionOutput",
|
|
91
|
+
"IdentifiabilityAnalyzer",
|
|
92
|
+
"IdentifiabilityReport",
|
|
84
93
|
# Metadata
|
|
85
94
|
"__version__",
|
|
86
95
|
]
|