docs(v2.0.0-alpha.3): inline plot injection across the entire doc tree
Add scripts/inject_doc_plots.py that scans every .md and .rst page under docs/source/, executes each Python code-block in an isolated namespace with a non-interactive matplotlib backend, captures every figure produced, and inserts an inline image directive immediately after the code-block. Markers AUTO-PLOT-BEGIN/END make the injection idempotent on re-runs. Blocks that fail to execute or produce no figure are left untouched. Add a transparent __getattr__ fallback in python/optimizr/__init__.py that forwards any unresolved top-level attribute to the compiled _core extension. This lets all v1.x and v2.0 doc samples that use 'from optimizr import X' (estimate_ou_params_py, linear_bsde_constant_coeffs, mmd_gaussian, ...) execute as written. Augment the OU Parameter Estimation example (docs/source/algorithms/optimal_control.md) with a two-panel visualization (simulated path plus empirical/theoretical autocorrelation). Net effect: 14 doc pages now display matplotlib plots inline directly under the code that produced them -- including the OU page, point processes, Grid Search, HMM, MCMC, plus the 8 v2.0 RST pages.
This commit is contained in:
@@ -40,6 +40,16 @@ Generic interacting-agent simulator (`consensus_dynamics`) — linear bounded-co
|
||||
ax.set_title('Bounded-confidence consensus, α = 0.3')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__agent_based/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/agent_based/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -56,6 +66,16 @@ Generic interacting-agent simulator (`consensus_dynamics`) — linear bounded-co
|
||||
ax.set_title('Convergence rate vs averaging weight α'); ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__agent_based/block_04_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/agent_based/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -48,6 +48,16 @@ With $a(t) \equiv -\rho$, $b = c = 0$ and $Y_T = 1$ the analytic deterministic s
|
||||
ax.legend(); ax.grid(alpha=0.3)
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__bsde/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/bsde/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -76,6 +86,16 @@ Crank–Nicolson is second-order in `Δt`.
|
||||
ax.set_title('Crank–Nicolson convergence'); ax.grid(which='both', alpha=0.3); ax.legend()
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__bsde/block_05_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/bsde/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -32,6 +32,16 @@ Maximum-Mean-Discrepancy distance with Gaussian kernel (`mmd_gaussian`). Self-d
|
||||
ax.set_title('Gaussian-kernel MMD vs translation (σ = 1)')
|
||||
ax.grid(alpha=0.3); fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__generative_calibration_hooks/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/generative_calibration_hooks/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -49,6 +59,16 @@ Bandwidth dependence
|
||||
ax.set_title('MMD as a function of kernel bandwidth')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__generative_calibration_hooks/block_04_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/generative_calibration_hooks/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -305,6 +305,13 @@ plt.ylabel('Learning Rate')
|
||||
plt.title('Grid Search: Loss Surface')
|
||||
plt.savefig('grid_search_heatmap.png', dpi=150)
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**Output:**
|
||||
|
||||
|
||||
@@ -447,6 +447,13 @@ axes[1].set_yticklabels(['Bull', 'Bear'])
|
||||
plt.tight_layout()
|
||||
plt.savefig('hmm_states.png', dpi=150)
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**Output:**
|
||||
|
||||
|
||||
@@ -41,6 +41,16 @@ Interacting-particle Euler scheme for $dX_t = θ(\bar X_t - X_t) dt + σ dW_t$ (
|
||||
ax.set_title('Mean-reverting McKean–Vlasov — 200 particles')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__mckean_vlasov/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/mckean_vlasov/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -54,6 +64,16 @@ Interacting-particle Euler scheme for $dX_t = θ(\bar X_t - X_t) dt + σ dW_t$ (
|
||||
ax.set_title('Marginal density at t = 0 and t = T')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__mckean_vlasov/block_04_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/mckean_vlasov/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -295,6 +295,13 @@ axes[1, 1].set_title('Posterior: σ')
|
||||
plt.tight_layout()
|
||||
plt.savefig('mcmc_posterior.png', dpi=150)
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -261,15 +261,17 @@ Estimates Ornstein-Uhlenbeck process parameters from time series data.
|
||||
```python
|
||||
from optimizr import estimate_ou_params_py
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Simulate OU process (for testing)
|
||||
dt = 1/252 # Daily data
|
||||
T = 1000
|
||||
kappa_true, theta_true, sigma_true = 3.0, 0.0, 0.2
|
||||
rng = np.random.default_rng(0)
|
||||
spread = [0.0]
|
||||
for _ in range(T-1):
|
||||
dx = kappa_true * (theta_true - spread[-1]) * dt + \
|
||||
sigma_true * np.sqrt(dt) * np.random.randn()
|
||||
sigma_true * np.sqrt(dt) * rng.standard_normal()
|
||||
spread.append(spread[-1] + dx)
|
||||
|
||||
spread = np.array(spread)
|
||||
@@ -280,7 +282,36 @@ kappa, theta, sigma, half_life = estimate_ou_params_py(spread, dt=dt)
|
||||
print(f"True: κ={kappa_true:.2f}, θ={theta_true:.3f}, σ={sigma_true:.3f}")
|
||||
print(f"Estimated: κ={kappa:.2f}, θ={theta:.3f}, σ={sigma:.3f}")
|
||||
print(f"Half-life: {half_life:.1f} periods ({half_life*252:.1f} days)")
|
||||
|
||||
# Visualise the simulated path together with the estimated mean-reversion
|
||||
# level and the decay envelope implied by the fitted half-life.
|
||||
t_axis = np.arange(len(spread)) * dt * 252 # in days
|
||||
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
|
||||
axes[0].plot(t_axis, spread, lw=0.7, label="simulated path")
|
||||
axes[0].axhline(theta_true, color="k", ls=":", label="true θ")
|
||||
axes[0].axhline(theta, color="red", ls="--", label="estimated θ")
|
||||
axes[0].set_xlabel("days"); axes[0].set_ylabel("spread")
|
||||
axes[0].set_title("OU simulation vs estimated long-run mean")
|
||||
axes[0].legend(); axes[0].grid(alpha=0.3)
|
||||
|
||||
# Empirical autocorrelation vs theoretical exp(-κ τ).
|
||||
lags = np.arange(0, 60)
|
||||
x = spread - spread.mean()
|
||||
acf = np.array([
|
||||
(x[: len(x) - k] @ x[k:]) / (x @ x) for k in lags
|
||||
])
|
||||
axes[1].plot(lags, acf, "o-", label="empirical ACF")
|
||||
axes[1].plot(lags, np.exp(-kappa * lags * dt), "--",
|
||||
label=r"theoretical $e^{-\kappa\,\tau}$")
|
||||
axes[1].set_xlabel("lag (days)"); axes[1].set_ylabel("autocorrelation")
|
||||
axes[1].set_title("Mean-reversion fingerprint")
|
||||
axes[1].legend(); axes[1].grid(alpha=0.3)
|
||||
fig.tight_layout(); plt.show()
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
**Method**: Maximum likelihood estimation (MLE) using analytical formulas for discrete-time OU process.
|
||||
|
||||
@@ -431,6 +462,10 @@ plt.plot(pnl_path, label='P&L')
|
||||
plt.legend()
|
||||
plt.tight_layout()
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
**Metrics interpretation**:
|
||||
- `total_return`: Should be positive with low transaction costs
|
||||
|
||||
@@ -47,6 +47,16 @@ $\partial_t m = \tfrac12 \partial_{xx} m$ with Gaussian initial density should r
|
||||
ax.set_title('Pure-diffusion Fokker–Planck'); ax.grid(alpha=0.3); ax.legend()
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__pde/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/pde/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -78,6 +88,16 @@ $-\Delta u = 2\pi^2 \sin(\pi x)\sin(\pi y)$ on the unit square with zero Dirichl
|
||||
axes[1].set_title('error vs analytic'); plt.colorbar(im1, ax=axes[1])
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__pde/block_05_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/pde/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -104,6 +124,16 @@ Heat-only relaxation ($H = 0$, σ² > 0) preserves a constant value, while a qua
|
||||
plt.colorbar(im, ax=ax)
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__pde/block_07_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/pde/plot_03.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -451,6 +451,10 @@ plt.suptitle("Fractional Brownian Motion Paths")
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
### Mixed fBM for Aggregate Order Flow
|
||||
|
||||
@@ -518,6 +522,10 @@ plt.title('Power-law decay in scaling limit')
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
```
|
||||
<!-- AUTO-PLOT-BEGIN -->
|
||||

|
||||
<!-- AUTO-PLOT-END -->
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -41,6 +41,16 @@ $h'(t) = h(t)^2/γ - φ$ with $h(T) = A$. When $γ = φ = A = 1$ the right-hand
|
||||
ax.set_title('Riccati fixed point γ=φ=A=1')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__quadratic_impact_control/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/quadratic_impact_control/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -60,6 +70,16 @@ Vary $A$, fix $γ = 1$, $φ = 0.25$, $T = 1$.
|
||||
ax.set_title('Riccati sensitivity to terminal weight')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__quadratic_impact_control/block_04_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/quadratic_impact_control/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -43,6 +43,16 @@ Synthetic stationary process with 5 % outliers
|
||||
ax.set_title('Synthetic series with heavy-tailed innovations')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__robust_drift/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/robust_drift/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -71,6 +81,16 @@ Synthetic stationary process with 5 % outliers
|
||||
ax.legend(); ax.grid(alpha=0.3); ax.set_title('Robust vs OLS drift estimate')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__robust_drift/block_05_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/robust_drift/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -43,6 +43,15 @@ Two modes; only mode 1 pays a unit reward. Free switching should give `V_0(0) =
|
||||
ax.set_title('Snell envelope — free switching')
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__stochastic_control/block_03_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/stochastic_control/plot_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -73,6 +82,15 @@ Closed-form Riccati for $a=q=0$, $b=r=s_T=1$, $T=1$ is $P(t) = 1/(1 + (T - t))$,
|
||||
axes[2].plot(tg[:-1], u); axes[2].set_title('feedback u(t) = -(b/r) P(t) x(t)'); axes[2].set_xlabel('t'); axes[2].grid(alpha=0.3)
|
||||
fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__stochastic_control/block_05_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/stochastic_control/plot_02.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
@@ -96,6 +114,15 @@ Affine premium $δ_±(λ) = α_± + κ_± λ$. First-order condition: $\lambda^
|
||||
ax.set_title('Optimal upward intensity vs value-function gradient')
|
||||
ax.grid(alpha=0.3); fig.tight_layout(); plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
.. AUTO-PLOT-BEGIN
|
||||
.. image:: ../_static/auto/algorithms__stochastic_control/block_06_fig_01.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
.. AUTO-PLOT-END
|
||||
.. image:: ../_static/v2/stochastic_control/plot_03.png
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
Reference in New Issue
Block a user