Score-based Levenberg Marquardt
#12
by odunbar - opened
- .cache/known_methods_snapshot.json +28 -0
- CLAUDE.md +7 -1
- data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l63_2026-08-12.nc +3 -0
- data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_const-force_2026-08-12.nc +3 -0
- data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_flux-force_2026-08-12.nc +3 -0
- data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_vec-force_2026-08-12.nc +3 -0
- data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l63_2026-08-12.nc +3 -0
- data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_const-force_2026-08-12.nc +3 -0
- data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_flux-force_2026-08-12.nc +3 -0
- data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_vec-force_2026-08-12.nc +3 -0
- src/common/leaderboard.py +17 -9
- src/common/method_registry.py +68 -6
- src/data_store.py +8 -0
- src/pages/MethodDetails.py +14 -0
- src/streamlit_app.py +4 -0
.cache/known_methods_snapshot.json
CHANGED
|
@@ -137,6 +137,32 @@
|
|
| 137 |
"gboed",
|
| 138 |
"boed"
|
| 139 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
}
|
| 141 |
},
|
| 142 |
"observed_methods": [
|
|
@@ -146,6 +172,8 @@
|
|
| 146 |
"hm",
|
| 147 |
"iekf",
|
| 148 |
"lm",
|
|
|
|
|
|
|
| 149 |
"teki",
|
| 150 |
"uki"
|
| 151 |
],
|
|
|
|
| 137 |
"gboed",
|
| 138 |
"boed"
|
| 139 |
]
|
| 140 |
+
},
|
| 141 |
+
"lm-kgmm": {
|
| 142 |
+
"abbreviation": "LM-KGMM",
|
| 143 |
+
"Method": "Score-based Levenberg-Marquardt (KGMM)",
|
| 144 |
+
"parallelism": "serial",
|
| 145 |
+
"update_type": "gradient",
|
| 146 |
+
"method_goal": "optimization",
|
| 147 |
+
"emulator_use": "none",
|
| 148 |
+
"aliases": [
|
| 149 |
+
"lm-kgmm",
|
| 150 |
+
"score-based lm (gfdt, kgmm) (extended window)",
|
| 151 |
+
"score-based lm (gfdt, kgmm) (parallel branches)"
|
| 152 |
+
]
|
| 153 |
+
},
|
| 154 |
+
"lm-dsm": {
|
| 155 |
+
"abbreviation": "LM-DSM",
|
| 156 |
+
"Method": "Score-based Levenberg-Marquardt (DSM)",
|
| 157 |
+
"parallelism": "serial",
|
| 158 |
+
"update_type": "gradient",
|
| 159 |
+
"method_goal": "optimization",
|
| 160 |
+
"emulator_use": "none",
|
| 161 |
+
"aliases": [
|
| 162 |
+
"lm-dsm",
|
| 163 |
+
"score-based lm (gfdt, dsm) (extended window)",
|
| 164 |
+
"score-based lm (gfdt, dsm) (parallel branches)"
|
| 165 |
+
]
|
| 166 |
}
|
| 167 |
},
|
| 168 |
"observed_methods": [
|
|
|
|
| 172 |
"hm",
|
| 173 |
"iekf",
|
| 174 |
"lm",
|
| 175 |
+
"lm-dsm",
|
| 176 |
+
"lm-kgmm",
|
| 177 |
"teki",
|
| 178 |
"uki"
|
| 179 |
],
|
CLAUDE.md
CHANGED
|
@@ -51,7 +51,9 @@ calibration_benchmark/
|
|
| 51 |
│ ├── common/
|
| 52 |
│ │ ├── leaderboard.py render_leaderboard() — shared scored-table + chart pipeline
|
| 53 |
│ │ │ _render_suitability_table() — method × benchmark suitability grid
|
| 54 |
-
│ │ │ optional budget_store param adds budget/iters chart section
|
|
|
|
|
|
|
| 55 |
│ │ └── method_registry.py KNOWN_METHODS registry + name canonicalization
|
| 56 |
│ └── pages/
|
| 57 |
│ ├── UQLeaderboard.py 🎯 UQ Leaderboard — calls render_leaderboard(load_uq_store())
|
|
@@ -63,6 +65,8 @@ calibration_benchmark/
|
|
| 63 |
│ ├── UKI_results/ UKI results
|
| 64 |
│ ├── adam_results/ ADAM gradient optimizer results (per-benchmark files)
|
| 65 |
│ ├── levenberg_marquardt_results/ LM gradient optimizer results (per-benchmark files)
|
|
|
|
|
|
|
| 66 |
│ ├── ces-eki-dmc_results/ CES-EKI-DMC ensemble-results files (UQ source)
|
| 67 |
│ ├── gboed-uq_results/ GBOED ensemble-results files (UQ source)
|
| 68 |
│ └── gnki-uq_results/ IEKF (a.k.a GNKI) ensemble-results files (UQ source)
|
|
@@ -182,6 +186,8 @@ A quick taxonomy tree is rendered on the home page (`src/streamlit_app.py`).
|
|
| 182 |
| `adam` | ADAM | serial | gradient | optimization | none | — |
|
| 183 |
| `lm` | LM | serial | gradient | optimization | none | gradient_descent |
|
| 184 |
| `gboed` | GBOED | parallel-interacting | general | uq | within-optimize | boed |
|
|
|
|
|
|
|
| 185 |
|
| 186 |
## How to extend
|
| 187 |
|
|
|
|
| 51 |
│ ├── common/
|
| 52 |
│ │ ├── leaderboard.py render_leaderboard() — shared scored-table + chart pipeline
|
| 53 |
│ │ │ _render_suitability_table() — method × benchmark suitability grid
|
| 54 |
+
│ │ │ optional budget_store param adds budget/iters chart section (UQ)
|
| 55 |
+
│ │ │ when budget_store is None (Optimization board), instead renders a
|
| 56 |
+
│ │ │ "Mean Iterations to Reach Target" chart derived as metric/ensemble_size
|
| 57 |
│ │ └── method_registry.py KNOWN_METHODS registry + name canonicalization
|
| 58 |
│ └── pages/
|
| 59 |
│ ├── UQLeaderboard.py 🎯 UQ Leaderboard — calls render_leaderboard(load_uq_store())
|
|
|
|
| 65 |
│ ├── UKI_results/ UKI results
|
| 66 |
│ ├── adam_results/ ADAM gradient optimizer results (per-benchmark files)
|
| 67 |
│ ├── levenberg_marquardt_results/ LM gradient optimizer results (per-benchmark files)
|
| 68 |
+
│ ├── opt_kgmm_score_lm/ Score-based LM (KGMM score estimator) results (per-benchmark files)
|
| 69 |
+
│ ├── opt_dsm_score_lm/ Score-based LM (DSM score estimator) results (per-benchmark files)
|
| 70 |
│ ├── ces-eki-dmc_results/ CES-EKI-DMC ensemble-results files (UQ source)
|
| 71 |
│ ├── gboed-uq_results/ GBOED ensemble-results files (UQ source)
|
| 72 |
│ └── gnki-uq_results/ IEKF (a.k.a GNKI) ensemble-results files (UQ source)
|
|
|
|
| 186 |
| `adam` | ADAM | serial | gradient | optimization | none | — |
|
| 187 |
| `lm` | LM | serial | gradient | optimization | none | gradient_descent |
|
| 188 |
| `gboed` | GBOED | parallel-interacting | general | uq | within-optimize | boed |
|
| 189 |
+
| `lm-kgmm` | LM-KGMM | serial | gradient | optimization | none | — |
|
| 190 |
+
| `lm-dsm` | LM-DSM | serial | gradient | optimization | none | — |
|
| 191 |
|
| 192 |
## How to extend
|
| 193 |
|
data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l63_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2feffae1f04a93b97a272ccd5a988fd8fbfea82000584c5ef990ff355e910329
|
| 3 |
+
size 14296
|
data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_const-force_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c88062bfa5fc7430d9792cc33558356042947971dfe7f0901e540ad2ed4609b2
|
| 3 |
+
size 14296
|
data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_flux-force_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d8bd767510a24bd7a8d316752b3dc08f39e9eb7a66fd978cfb213574256667d1
|
| 3 |
+
size 14296
|
data/opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_vec-force_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e5846b68470f28ff4b94fe910bba4017b03486ed71a396c6e41dd9218bbc641d
|
| 3 |
+
size 14296
|
data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l63_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8210335c139334983b3499ed7a2f626194cabf5904991e8b5eeadfcc04403d68
|
| 3 |
+
size 14296
|
data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_const-force_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:018c3f7b5d59d661cb62c7f4f861ecd38f39c7d8eaf0c172dd57e35cfe780a3b
|
| 3 |
+
size 14296
|
data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_flux-force_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3c0f44cfcc8107a42a91e71d6cdace8ae718ab83663f84d3c1300bf11b9104f1
|
| 3 |
+
size 14296
|
data/opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_vec-force_2026-08-12.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8038e2250cd08ee938beb19e883a8b29ebcd829a3a03059337b7154c4eff2235
|
| 3 |
+
size 14296
|
src/common/leaderboard.py
CHANGED
|
@@ -370,27 +370,35 @@ def render_leaderboard(
|
|
| 370 |
else:
|
| 371 |
scored_df["ensemble_score"] = 100.0
|
| 372 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
if scoring_mode == "Mean Forward Model Runs":
|
| 374 |
scored_df["Score"] = scored_df["mean_runs_score"]
|
| 375 |
-
sort_columns = ["Mean Forward Model Runs", "Optimal Ensemble Size", "abbreviation"]
|
| 376 |
-
ascending = [True, True, True]
|
| 377 |
elif scoring_mode == "Minimum Forward Model Runs":
|
| 378 |
scored_df["Score"] = scored_df["minimum_runs_score"]
|
| 379 |
-
sort_columns = ["Minimum Forward Model Runs", "Optimal Ensemble Size", "abbreviation"]
|
| 380 |
-
ascending = [True, True, True]
|
| 381 |
elif scoring_mode == "Smallest Optimal Ensemble Size":
|
| 382 |
scored_df["Score"] = scored_df["ensemble_score"]
|
| 383 |
-
sort_columns = ["Optimal Ensemble Size", "Mean Forward Model Runs", "abbreviation"]
|
| 384 |
-
ascending = [True, True, True]
|
| 385 |
else:
|
| 386 |
scored_df["Score"] = (
|
| 387 |
fwdruns_weight * scored_df["mean_runs_score"]
|
| 388 |
+ ensemble_weight * scored_df["ensemble_score"]
|
| 389 |
)
|
| 390 |
-
sort_columns = ["Score", "Mean Forward Model Runs", "Optimal Ensemble Size", "abbreviation"]
|
| 391 |
-
ascending = [False, True, True, True]
|
| 392 |
|
| 393 |
-
scored_df =
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
|
| 395 |
if add_rank:
|
| 396 |
scored_df["Rank"] = scored_df.index + 1
|
|
|
|
| 370 |
else:
|
| 371 |
scored_df["ensemble_score"] = 100.0
|
| 372 |
|
| 373 |
+
scored_df["_unreliable"] = (
|
| 374 |
+
scored_df["Mean Failure Rate (%)"].fillna(0.0) >= _RELIABLE_FAILURE_THRESHOLD
|
| 375 |
+
)
|
| 376 |
+
|
| 377 |
if scoring_mode == "Mean Forward Model Runs":
|
| 378 |
scored_df["Score"] = scored_df["mean_runs_score"]
|
| 379 |
+
sort_columns = ["_unreliable", "Mean Forward Model Runs", "Optimal Ensemble Size", "abbreviation"]
|
| 380 |
+
ascending = [True, True, True, True]
|
| 381 |
elif scoring_mode == "Minimum Forward Model Runs":
|
| 382 |
scored_df["Score"] = scored_df["minimum_runs_score"]
|
| 383 |
+
sort_columns = ["_unreliable", "Minimum Forward Model Runs", "Optimal Ensemble Size", "abbreviation"]
|
| 384 |
+
ascending = [True, True, True, True]
|
| 385 |
elif scoring_mode == "Smallest Optimal Ensemble Size":
|
| 386 |
scored_df["Score"] = scored_df["ensemble_score"]
|
| 387 |
+
sort_columns = ["_unreliable", "Optimal Ensemble Size", "Mean Forward Model Runs", "abbreviation"]
|
| 388 |
+
ascending = [True, True, True, True]
|
| 389 |
else:
|
| 390 |
scored_df["Score"] = (
|
| 391 |
fwdruns_weight * scored_df["mean_runs_score"]
|
| 392 |
+ ensemble_weight * scored_df["ensemble_score"]
|
| 393 |
)
|
| 394 |
+
sort_columns = ["_unreliable", "Score", "Mean Forward Model Runs", "Optimal Ensemble Size", "abbreviation"]
|
| 395 |
+
ascending = [True, False, True, True, True]
|
| 396 |
|
| 397 |
+
scored_df = (
|
| 398 |
+
scored_df.sort_values(sort_columns, ascending=ascending)
|
| 399 |
+
.drop(columns="_unreliable")
|
| 400 |
+
.reset_index(drop=True)
|
| 401 |
+
)
|
| 402 |
|
| 403 |
if add_rank:
|
| 404 |
scored_df["Rank"] = scored_df.index + 1
|
src/common/method_registry.py
CHANGED
|
@@ -143,19 +143,81 @@ KNOWN_METHODS = {
|
|
| 143 |
"emulator_use": "within-optimize",
|
| 144 |
"aliases": ["gboed", "boed"],
|
| 145 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
}
|
| 147 |
|
| 148 |
|
| 149 |
-
#
|
| 150 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
_METHOD_PALETTE = [
|
| 152 |
-
"#
|
| 153 |
-
"#
|
| 154 |
-
"#
|
|
|
|
|
|
|
| 155 |
]
|
| 156 |
|
| 157 |
# Stable abbreviation → hex color mapping. Import this wherever Altair charts are built
|
| 158 |
-
# so every plot in the app assigns the same color to each method.
|
|
|
|
|
|
|
|
|
|
| 159 |
METHOD_COLORS: dict[str, str] = {
|
| 160 |
meta["abbreviation"]: _METHOD_PALETTE[i % len(_METHOD_PALETTE)]
|
| 161 |
for i, meta in enumerate(KNOWN_METHODS.values())
|
|
|
|
| 143 |
"emulator_use": "within-optimize",
|
| 144 |
"aliases": ["gboed", "boed"],
|
| 145 |
},
|
| 146 |
+
"lm-kgmm": {
|
| 147 |
+
"abbreviation": "LM-KGMM",
|
| 148 |
+
"Method": "Score-based Levenberg-Marquardt (KGMM)",
|
| 149 |
+
"parallelism": "serial",
|
| 150 |
+
"update_type": "gradient",
|
| 151 |
+
"method_goal": "optimization",
|
| 152 |
+
"emulator_use": "none",
|
| 153 |
+
"aliases": [
|
| 154 |
+
"lm-kgmm",
|
| 155 |
+
"score-based lm (gfdt, kgmm) (extended window)",
|
| 156 |
+
"score-based lm (gfdt, kgmm) (parallel branches)",
|
| 157 |
+
],
|
| 158 |
+
},
|
| 159 |
+
"lm-dsm": {
|
| 160 |
+
"abbreviation": "LM-DSM",
|
| 161 |
+
"Method": "Score-based Levenberg-Marquardt (DSM)",
|
| 162 |
+
"parallelism": "serial",
|
| 163 |
+
"update_type": "gradient",
|
| 164 |
+
"method_goal": "optimization",
|
| 165 |
+
"emulator_use": "none",
|
| 166 |
+
"aliases": [
|
| 167 |
+
"lm-dsm",
|
| 168 |
+
"score-based lm (gfdt, dsm) (extended window)",
|
| 169 |
+
"score-based lm (gfdt, dsm) (parallel branches)",
|
| 170 |
+
],
|
| 171 |
+
},
|
| 172 |
}
|
| 173 |
|
| 174 |
|
| 175 |
+
# One slot per method in KNOWN_METHODS declaration order. New methods appended
|
| 176 |
+
# to KNOWN_METHODS get the next slot.
|
| 177 |
+
#
|
| 178 |
+
# Generated by a greedy farthest-point search in OKLab: each slot was chosen to
|
| 179 |
+
# maximize its minimum distance to every slot before it, simultaneously under
|
| 180 |
+
# normal vision and simulated protan/deutan color-vision deficiency (Machado,
|
| 181 |
+
# Oliveira & Fernandes 2009 severity-1.0 transforms — the same model used by
|
| 182 |
+
# the dataviz skill's validate_palette.js). Because this optimizes the running
|
| 183 |
+
# ALL-PAIRS minimum (not just adjacent-slot pairs), the printed ΔE at slot k
|
| 184 |
+
# below is a genuine worst-case guarantee for any subset of the first k slots
|
| 185 |
+
# shown together — relevant here because any subset of methods can appear
|
| 186 |
+
# together via the "Methods to display in charts" multiselect, not just
|
| 187 |
+
# neighbors in this list.
|
| 188 |
+
#
|
| 189 |
+
# Honest limits (OKLab ΔE x100; CVD = min(protan, deutan)):
|
| 190 |
+
# - Slots 0-15 (16 colors): CVD >= 8.0 — clears the full colorblind-safety
|
| 191 |
+
# target for every pair among any subset of these.
|
| 192 |
+
# - Slots 16-27 : CVD in [6.0, 8.0) — the legal "floor" band per
|
| 193 |
+
# the skill (secondary encoding required). This app already provides it:
|
| 194 |
+
# every legend and tooltip in leaderboard.py shows the method abbreviation
|
| 195 |
+
# as text, so identity is never color-alone even where hue alone is weak.
|
| 196 |
+
# - Slots 28-29 : CVD ~5.8, just under the 6.0 floor for their
|
| 197 |
+
# closest pair — weakest two slots, kept only for the requested headroom.
|
| 198 |
+
# - Normal-vision floor (>=15, a hard gate when checked in isolation): holds
|
| 199 |
+
# for the first ~6 slots against ALL other slots; beyond that, some pairs
|
| 200 |
+
# among 30 simultaneously-distinguishable colors are close even for
|
| 201 |
+
# full-color vision. This is a geometry limit of a finite perceptual
|
| 202 |
+
# space, not a search-quality issue — the reference palette in the dataviz
|
| 203 |
+
# skill's own docs states plainly that no ordering clears all-pairs floors
|
| 204 |
+
# past ~8 categories. 30 slots were requested anyway for growth headroom;
|
| 205 |
+
# rely on the legend/tooltip text labels (already present) for identity,
|
| 206 |
+
# not on hue alone, especially past slot ~16.
|
| 207 |
+
# Re-run the search (seeded with all prior slots fixed) if extending further.
|
| 208 |
_METHOD_PALETTE = [
|
| 209 |
+
"#d80065", "#007fff", "#ff9700", "#00cae4", "#6d00b8", "#970f00",
|
| 210 |
+
"#007ca4", "#de8580", "#00a0d7", "#fa0000", "#0100ff", "#90006d",
|
| 211 |
+
"#e500a0", "#007656", "#008200", "#006dd1", "#00b7ad", "#47b3ff",
|
| 212 |
+
"#0087d2", "#e97e00", "#ec9f72", "#4b4589", "#00d0ae", "#c87181",
|
| 213 |
+
"#5194ff", "#9c5683", "#0058ff", "#892348", "#e2003d", "#00b5d5",
|
| 214 |
]
|
| 215 |
|
| 216 |
# Stable abbreviation → hex color mapping. Import this wherever Altair charts are built
|
| 217 |
+
# so every plot in the app assigns the same color to each method. With 30 palette
|
| 218 |
+
# slots and 14 registered methods, every method gets a unique color — the modulo
|
| 219 |
+
# below only matters as a defensive fallback if KNOWN_METHODS grows past 30 without
|
| 220 |
+
# the palette being extended first (see comment above).
|
| 221 |
METHOD_COLORS: dict[str, str] = {
|
| 222 |
meta["abbreviation"]: _METHOD_PALETTE[i % len(_METHOD_PALETTE)]
|
| 223 |
for i, meta in enumerate(KNOWN_METHODS.values())
|
src/data_store.py
CHANGED
|
@@ -35,6 +35,8 @@ DATASET_FILES = {
|
|
| 35 |
"bayesian/l63_hm.nc",
|
| 36 |
"adam_results/leaderboard_adam_l63_2026-06-26.nc",
|
| 37 |
"levenberg_marquardt_results/leaderboard_lm_l63_2026-06-29.nc",
|
|
|
|
|
|
|
| 38 |
],
|
| 39 |
"L96": [
|
| 40 |
"l96_ensemble_results.nc",
|
|
@@ -42,10 +44,14 @@ DATASET_FILES = {
|
|
| 42 |
"bayesian/l96_abc.nc",
|
| 43 |
"adam_results/leaderboard_adam_l96_const-force_2026-06-26.nc",
|
| 44 |
"levenberg_marquardt_results/leaderboard_lm_l96_const-force_2026-06-29.nc",
|
|
|
|
|
|
|
| 45 |
],
|
| 46 |
"L96_NN_FORCING": [
|
| 47 |
"l96_nn_forcing_ensemble_results.nc",
|
| 48 |
"UKI_results/uki_l96_nn_forcing_ensemble_results.nc",
|
|
|
|
|
|
|
| 49 |
],
|
| 50 |
"L96_SPATIAL_FORCING": [
|
| 51 |
"l96_spatial_forcing_ensemble_results.nc",
|
|
@@ -53,6 +59,8 @@ DATASET_FILES = {
|
|
| 53 |
"bayesian/l96_varying_abc.nc",
|
| 54 |
"adam_results/leaderboard_adam_l96_vec-force_2026-06-26.nc",
|
| 55 |
"levenberg_marquardt_results/leaderboard_lm_l96_vec-force_2026-06-29.nc",
|
|
|
|
|
|
|
| 56 |
],
|
| 57 |
}
|
| 58 |
|
|
|
|
| 35 |
"bayesian/l63_hm.nc",
|
| 36 |
"adam_results/leaderboard_adam_l63_2026-06-26.nc",
|
| 37 |
"levenberg_marquardt_results/leaderboard_lm_l63_2026-06-29.nc",
|
| 38 |
+
"opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l63_2026-08-12.nc",
|
| 39 |
+
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l63_2026-08-12.nc",
|
| 40 |
],
|
| 41 |
"L96": [
|
| 42 |
"l96_ensemble_results.nc",
|
|
|
|
| 44 |
"bayesian/l96_abc.nc",
|
| 45 |
"adam_results/leaderboard_adam_l96_const-force_2026-06-26.nc",
|
| 46 |
"levenberg_marquardt_results/leaderboard_lm_l96_const-force_2026-06-29.nc",
|
| 47 |
+
"opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_const-force_2026-08-12.nc",
|
| 48 |
+
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_const-force_2026-08-12.nc",
|
| 49 |
],
|
| 50 |
"L96_NN_FORCING": [
|
| 51 |
"l96_nn_forcing_ensemble_results.nc",
|
| 52 |
"UKI_results/uki_l96_nn_forcing_ensemble_results.nc",
|
| 53 |
+
"opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_flux-force_2026-08-12.nc",
|
| 54 |
+
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_flux-force_2026-08-12.nc",
|
| 55 |
],
|
| 56 |
"L96_SPATIAL_FORCING": [
|
| 57 |
"l96_spatial_forcing_ensemble_results.nc",
|
|
|
|
| 59 |
"bayesian/l96_varying_abc.nc",
|
| 60 |
"adam_results/leaderboard_adam_l96_vec-force_2026-06-26.nc",
|
| 61 |
"levenberg_marquardt_results/leaderboard_lm_l96_vec-force_2026-06-29.nc",
|
| 62 |
+
"opt_kgmm_score_lm/leaderboard_sblm_kgmm_parallel_l96_vec-force_2026-08-12.nc",
|
| 63 |
+
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_vec-force_2026-08-12.nc",
|
| 64 |
],
|
| 65 |
}
|
| 66 |
|
src/pages/MethodDetails.py
CHANGED
|
@@ -22,6 +22,10 @@ st.sidebar.page_link("pages/RawData.py", label="Get Data", icon="🧾")
|
|
| 22 |
|
| 23 |
st.title("Method Details")
|
| 24 |
st.caption("Method-level view from NetCDF forward-model-run metrics averaged over random seeds")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
# Read selected method from query params
|
| 27 |
abbr = st.query_params.get("method")
|
|
@@ -99,6 +103,16 @@ method_meta = {
|
|
| 99 |
"url": "https://arxiv.org/abs/2508.13071",
|
| 100 |
"summary": "Goal-oriented Bayesian Optimal Experimental Design — selects each batch of forward-model evaluations by maximizing an expected-information-gain criterion targeted at the quantity of interest, refitting the surrogate used by the criterion at every iteration.",
|
| 101 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
}
|
| 103 |
|
| 104 |
# Selection UI (defaults to query param if valid)
|
|
|
|
| 22 |
|
| 23 |
st.title("Method Details")
|
| 24 |
st.caption("Method-level view from NetCDF forward-model-run metrics averaged over random seeds")
|
| 25 |
+
st.markdown(
|
| 26 |
+
"For the exact implementation of each algorithm, see "
|
| 27 |
+
"[CalibrationLeaderboard.jl](https://github.com/odunbar/CalibrationLeaderboard.jl)."
|
| 28 |
+
)
|
| 29 |
|
| 30 |
# Read selected method from query params
|
| 31 |
abbr = st.query_params.get("method")
|
|
|
|
| 103 |
"url": "https://arxiv.org/abs/2508.13071",
|
| 104 |
"summary": "Goal-oriented Bayesian Optimal Experimental Design — selects each batch of forward-model evaluations by maximizing an expected-information-gain criterion targeted at the quantity of interest, refitting the surrogate used by the criterion at every iteration.",
|
| 105 |
},
|
| 106 |
+
"LM-KGMM": {
|
| 107 |
+
"citation": "Giorgini, Bischoff & Souza, arXiv:2503.18054, 2025",
|
| 108 |
+
"url": "https://arxiv.org/abs/2503.18054",
|
| 109 |
+
"summary": "Score-based Levenberg-Marquardt using a K-means Gaussian Mixture Model to estimate the score function, which drives the gradient via the generalized fluctuation-dissipation theorem (GFDT).",
|
| 110 |
+
},
|
| 111 |
+
"LM-DSM": {
|
| 112 |
+
"citation": "Giorgini, Bischoff & Souza, arXiv:2509.19660, 2025",
|
| 113 |
+
"url": "https://arxiv.org/abs/2509.19660",
|
| 114 |
+
"summary": "Score-based Levenberg-Marquardt using Denoising Score Matching to estimate the score function, which drives the gradient via the generalized fluctuation-dissipation theorem (GFDT).",
|
| 115 |
+
},
|
| 116 |
}
|
| 117 |
|
| 118 |
# Selection UI (defaults to query param if valid)
|
src/streamlit_app.py
CHANGED
|
@@ -28,6 +28,10 @@ st.markdown(
|
|
| 28 |
"Methods are ranked by **forward-model run efficiency** — how many forward-model "
|
| 29 |
"evaluations are needed, on average across random seeds, to reach a target accuracy."
|
| 30 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
st.divider()
|
| 33 |
|
|
|
|
| 28 |
"Methods are ranked by **forward-model run efficiency** — how many forward-model "
|
| 29 |
"evaluations are needed, on average across random seeds, to reach a target accuracy."
|
| 30 |
)
|
| 31 |
+
st.markdown(
|
| 32 |
+
"The exact implementations of every algorithm benchmarked here are available at "
|
| 33 |
+
"[CalibrationLeaderboard.jl](https://github.com/odunbar/CalibrationLeaderboard.jl)."
|
| 34 |
+
)
|
| 35 |
|
| 36 |
st.divider()
|
| 37 |
|