File size: 6,712 Bytes
53f9f3e
43604b6
53f9f3e
43604b6
53f9f3e
ad36a58
fce6c09
 
43604b6
 
fce6c09
 
 
43604b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ad36a58
43604b6
 
 
 
 
 
 
 
fce6c09
43604b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d60772
43604b6
3d60772
 
 
 
 
 
 
 
 
 
 
4bcf26d
 
 
3d60772
 
 
4bcf26d
 
3d60772
 
 
 
 
4bcf26d
 
 
 
3d60772
 
 
 
 
4bcf26d
 
 
3d60772
 
 
 
 
 
43604b6
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import streamlit as st
from pathlib import Path

st.set_page_config(page_title="Calibration Benchmark", page_icon="🏠", layout="wide")

# Sidebar navigation
st.sidebar.title("Navigation")
st.sidebar.page_link("streamlit_app.py", label="Home", icon="🏠")
st.sidebar.page_link("pages/OptimizationLeaderboard.py", label="Optimization Leaderboard", icon="πŸ“Š")
st.sidebar.page_link("pages/UQLeaderboard.py", label="UQ Leaderboard", icon="🎯")
st.sidebar.page_link("pages/MethodDetails.py", label="Methods", icon="πŸ“˜")
st.sidebar.page_link("pages/RawData.py", label="Get Data", icon="🧾")

st.title("Calibration Benchmark")
st.markdown(
    "A benchmark comparing parameter-calibration methods on chaotic dynamical systems. "
    "Methods are ranked by **forward-model run efficiency** β€” how many forward-model "
    "evaluations are needed, on average across random seeds, to reach a target accuracy."
)

st.divider()

col1, col2 = st.columns(2, gap="large")

with col1:
    st.subheader("πŸ“Š Optimization Leaderboard")
    st.markdown(
        "Ranks methods by mean forward-model runs to reach an **RMSE target** on "
        "Lorenz-63 and Lorenz-96 benchmarks. "
        "Lower is better; failed runs are tracked separately as a failure rate."
    )
    st.page_link("pages/OptimizationLeaderboard.py", label="Go to Optimization Leaderboard β†’")

with col2:
    st.subheader("🎯 UQ Leaderboard")
    st.markdown(
        "Ranks methods by mean forward-model runs to reach an **uncertainty quantification "
        "target**. Same metric and benchmarks as the Optimization Leaderboard, evaluated "
        "at a UQ-specific convergence criterion."
    )
    st.page_link("pages/UQLeaderboard.py", label="Go to UQ Leaderboard β†’")

st.divider()

st.subheader("Benchmarks")
st.markdown(
    "Results are reported on four benchmark configurations of the [Lorenz system]"
    "(https://en.wikipedia.org/wiki/Lorenz_system), a standard testbed for "
    "data-assimilation and calibration algorithms:"
)

_media = Path(__file__).parent / "media"

st.markdown("- **L63** β€” Lorenz-63 β€” 3-variable chaotic attractor; learn 2 parameters, strongly nonlinear.")
st.image(
    str(_media / "posterior_ribbons_20_13_k5.png"),
    caption="Example prior-posterior & truth. L: Difference to true parameter. R: data-sample/output predictived distribution (state-mean [1:3],  state-covariance (diag [4:6] and off-diag [7:9]))",
    width=800,
)


st.markdown("- **L96** β€” Lorenz-96 (40-variable); learn 1-parameter constant forcing.")
st.image(
    str(_media / "posterior_ribbons_const-force_12_1_k3.png"),
    caption="Example prior-posterior & truth. L: Difference to true parameter. C: parameter-induced forcing of the L96 system. R: data-sample/output predictived distribution ([1:40] state-mean [41:80] state-std)",
    width=1200,
)

st.markdown("- **L96_SPATIAL_FORCING** β€” Lorenz-96 (40-variable) with spatially-varying forcing; learn 40 parameters; moderately correlated prior.")
st.image(
    str(_media / "posterior_ribbons_vec-force_65_1_k3.png"),
    caption="Example prior-posterior & truth. L: Difference to true parameters. C: parameter-induced forcing of the L96 system. R: data-sample/output predictived distribution ([1:40] state-mean [41:80] state-std)",
    width=1200,
)


st.markdown("- **L96_NN_FORCING** β€” Lorenz-96 (100-variable) with a neural-network forcing; Learn 61 parameters (weights and biases of the network). Reasonable prior given.")
st.image(
    str(_media / "posterior_ribbons_flux-force_80_1_k3.png"),
    caption="Example prior-posterior & truth. L: Difference to true parameters (weights). C: parameter-induced forcing of the L96 system. R: data-sample/output predictived distribution ([1:100] state-mean [101:200] state-std)",
    width=1200,
)

st.subheader("Method taxonomy")
st.markdown(
    "Every method carries four independent tags β€” how it searches, what update "
    "mechanism drives each step, what it's built to report, and whether/when it uses "
    "a surrogate model. See the **πŸ“˜ Methods** page for citations and per-method "
    "performance charts."
)
st.markdown(
    """
- **Parallelism** β€” how the search explores parameter space
    - **Serial** β€” `ADAM`, `LM` β€” a single point estimate advanced step by step.
    - **Parallel-independent** β€” `ABC`, `HM` β€” a population of candidates updated
      with no coupling between members (accepted samples / per-wave resampling).
    - **Parallel-interacting** β€” `TEKI`, `ETKI`, `IEKF`, `UKI`, `CES-EKI-DMC`, `CES-EKI-CONST`,
      `CES-IEKF-CONST` β€” an ensemble whose members are coupled through a shared update
      each iteration.
- **Update type** β€” the mechanism driving each update step
    - **Gradient** β€” `ADAM`, `LM` β€” follow the loss gradient (or a Gauss-Newton
      approximation of it) directly.
    - **Kalman** β€” `TEKI`, `ETKI`, `IEKF`, `UKI`, `CES-EKI-DMC`, `CES-EKI-CONST`,
      `CES-IEKF-CONST` β€” a (possibly linearized or unscented) Kalman-style ensemble update.
    - **General** β€” `ABC`, `HM` β€” neither gradient- nor Kalman-based (rejection
      sampling, implausibility cuts).
- **Method goal** β€” what the method is built to report
    - **Optimization** β€” `TEKI`, `ETKI`, `UKI`, `ADAM`, `LM` β€” a single best-fit
      parameter estimate.
    - **UQ** β€” `IEKF`, `ABC`, `HM`, `CES-EKI-DMC`, `CES-EKI-CONST`, `CES-IEKF-CONST` β€” the
      full posterior / parameter uncertainty. Can still be scored on the Optimization
      leaderboard, but tends to be less competitive there since it's not optimizing for
      speed-to-target.
- **Emulator use** β€” when/whether a surrogate model of the forward model is used
    - **None** β€” `TEKI`, `ETKI`, `IEKF`, `UKI`, `ADAM`, `LM`, `ABC` β€” samples/evaluates
      the true forward model throughout.
    - **Within-optimize** β€” `HM` β€” refits a surrogate at each iteration (wave) of the
      search itself.
    - **After-optimize** β€” `CES-EKI-DMC`, `CES-EKI-CONST`, `CES-IEKF-CONST` β€” fits a
      surrogate (e.g. a GP) once, after calibration finishes, and samples the posterior
      through it.
"""
)
st.caption(
    "Note: Kalman methods are Bayesian in spirit too (they're approximate Gaussian "
    "posterior updates) β€” update type is about mechanism (gradient vs. Kalman vs. "
    "general), not whether a method is 'Bayesian'."
)

st.subheader("Key metric")
st.markdown(
    "The reported metric is the **mean number of forward-model evaluations** required "
    "to reach the target, averaged over random seeds. "
    "A value of **βˆ’1** indicates a failed run (did not reach the target); "
    "the **failure rate** shows the fraction of seeds that failed."
)