diff --git a/docs/requirements.txt b/docs/requirements.txt index 31f981e..b646206 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,3 +4,4 @@ furo==2023.9.10 myst-parser==2.0.0 sphinx-autodoc-typehints==1.24.0 charset-normalizer>=3.4.0 +sphinxcontrib-mermaid>=0.9.2 diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css new file mode 100644 index 0000000..d4a7acf --- /dev/null +++ b/docs/source/_static/custom.css @@ -0,0 +1,138 @@ +/* ─── Optimiz-rs Documentation Custom Styles ──────────────────────────────── */ +/* Brand: orange (#f97316) on furo dark theme */ + +:root { + --brand-orange: #f97316; + --brand-orange-light: #fb923c; + --brand-orange-dim: rgba(249, 115, 22, 0.15); + --brand-orange-border: rgba(249, 115, 22, 0.35); +} + +/* ── Mermaid diagram container ─────────────────────────────────────────────── */ +.mermaid { + background: transparent !important; + padding: 1.5rem 0; + text-align: center; + overflow-x: auto; +} + +.mermaid svg { + max-width: 100%; + border-radius: 12px; + filter: drop-shadow(0 4px 16px rgba(249, 115, 22, 0.12)); +} + +/* ── Better admonitions ─────────────────────────────────────────────────────── */ +.admonition { + border-radius: 10px !important; + border-left-width: 4px !important; + margin: 1.5rem 0 !important; +} + +.admonition.note { + border-left-color: var(--brand-orange) !important; + background: var(--brand-orange-dim) !important; +} + +.admonition.tip { + border-left-color: #22c55e !important; + background: rgba(34, 197, 94, 0.1) !important; +} + +.admonition.warning { + border-left-color: #f59e0b !important; + background: rgba(245, 158, 11, 0.1) !important; +} + +.admonition.important { + border-left-color: #ef4444 !important; + background: rgba(239, 68, 68, 0.1) !important; +} + +/* ── Section headers ────────────────────────────────────────────────────────── */ +h1, h2, h3 { + scroll-margin-top: 4rem; +} + +h2 { + border-bottom: 2px solid var(--brand-orange-border); + padding-bottom: 0.4rem; +} + +/* ── Code blocks ────────────────────────────────────────────────────────────── */ +.highlight { + border-radius: 8px !important; + border: 1px solid rgba(255, 255, 255, 0.08) !important; +} + +/* Inline code */ +code.literal { + background: rgba(249, 115, 22, 0.08) !important; + border: 1px solid var(--brand-orange-border) !important; + padding: 0.1em 0.4em !important; + border-radius: 4px !important; + color: var(--brand-orange-light) !important; + font-size: 0.88em !important; +} + +/* ── Tables ─────────────────────────────────────────────────────────────────── */ +table.docutils { + border-collapse: collapse; + width: 100%; + margin: 1.2rem 0; + border-radius: 8px; + overflow: hidden; + font-size: 0.9rem; +} + +table.docutils th { + background: var(--brand-orange-dim) !important; + color: var(--brand-orange-light) !important; + font-weight: 700; + padding: 0.6rem 0.9rem; + border-bottom: 2px solid var(--brand-orange-border); +} + +table.docutils td { + padding: 0.5rem 0.9rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +table.docutils tr:hover td { + background: rgba(249, 115, 22, 0.04); +} + +/* ── Performance metric boxes (for benchmarks) ──────────────────────────────── */ +.perf-box { + background: linear-gradient(135deg, rgba(249,115,22,0.12) 0%, rgba(249,115,22,0.04) 100%); + border: 1px solid var(--brand-orange-border); + border-radius: 10px; + padding: 1rem 1.5rem; + margin: 1rem 0; + display: inline-block; + min-width: 140px; + text-align: center; +} + +.perf-box .val { + font-size: 1.8rem; + font-weight: 800; + color: var(--brand-orange); +} + +.perf-box .lbl { + font-size: 0.75rem; + color: #94a3b8; + margin-top: 0.2rem; +} + +/* ── Navigation sidebar ─────────────────────────────────────────────────────── */ +.sidebar-tree .current > .reference { + color: var(--brand-orange) !important; +} + +/* ── Mobile ─────────────────────────────────────────────────────────────────── */ +@media (max-width: 768px) { + .mermaid svg { width: 100% !important; } + table.docutils { font-size: 0.78rem; } +} diff --git a/docs/source/algorithms/differential_evolution.md b/docs/source/algorithms/differential_evolution.md index 5b8675e..40b8348 100644 --- a/docs/source/algorithms/differential_evolution.md +++ b/docs/source/algorithms/differential_evolution.md @@ -169,46 +169,18 @@ $$ ## Complete Algorithm -``` -Algorithm: Differential Evolution -───────────────────────────────── -Input: objective f, bounds [l, u], pop_size N_P, F, CR, max_iter - -1. Initialize population: - For i = 1 to N_P: - x_{i,0} = l + rand(0,1) · (u - l) # uniform in bounds - -2. Evaluate fitness: - f_i = f(x_{i,0}) for all i - -3. While g < max_iter and not converged: - - a. For i = 1 to N_P: - - i. Mutation: - Select r_1, r_2, r_3 distinct and ≠ i - v_{i,g+1} = x_{r_1,g} + F · (x_{r_2,g} - x_{r_3,g}) - - ii. Crossover: - j_rand = randint(1, D) - For j = 1 to D: - if rand(0,1) ≤ CR or j = j_rand: - u_{i,j,g+1} = v_{i,j,g+1} - else: - u_{i,j,g+1} = x_{i,j,g} - - iii. Boundary handling: - Clip u_{i,g+1} to [l, u] - - iv. Selection: - if f(u_{i,g+1}) ≤ f(x_{i,g}): - x_{i,g+1} = u_{i,g+1} - else: - x_{i,g+1} = x_{i,g} - - b. g = g + 1 - -4. Return x_best and f(x_best) +```{mermaid} +flowchart TD + A["🎲 Initialize Population\nx_i = l + rand · (u − l)"] --> B["📊 Evaluate Fitness\nf_i = f(x_i) for all i"] + B --> C{{"g < max_iter?"}} + C -->|Yes| D["Mutation\nv = x_r1 + F · (x_r2 − x_r3)"] + D --> E["Crossover\nu_j = v_j if rand ≤ CR or j = j_rand\nelse u_j = x_j"] + E --> F["Clip to bounds [l, u]"] + F --> G{{"f(trial) ≤ f(target)?"}} + G -->|"Yes — better"| H["✅ Accept trial\nx_i ← u_i"] + G -->|"No — worse"| I["Keep current\nx_i unchanged"] + H & I --> C + C -->|No| J["🏆 Return x_best, f(x_best)"] ``` --- diff --git a/docs/source/algorithms/hmm.md b/docs/source/algorithms/hmm.md index 91ba6de..aa8fdae 100644 --- a/docs/source/algorithms/hmm.md +++ b/docs/source/algorithms/hmm.md @@ -458,6 +458,24 @@ For complete examples with regime detection on real market data, see the [HMM Tu ### Transition Diagram +```{mermaid} +stateDiagram-v2 + direction LR + [*] --> Normal + Bull : 📈 Bull Market + Normal : 📊 Normal Regime + Bear : 📉 Bear Market + Bull --> Bull : a₁₁ (self) + Bull --> Normal : a₁₂ + Normal --> Bull : a₂₁ + Normal --> Normal : a₂₂ (self) + Normal --> Bear : a₂₃ + Bear --> Normal : a₃₂ + Bear --> Bear : a₃₃ (self) +``` + +**Code example** — build and visualize the transition graph programmatically: + ```python import networkx as nx diff --git a/docs/source/api/point_processes.md b/docs/source/api/point_processes.md index a1ff79b..984ae4c 100644 --- a/docs/source/api/point_processes.md +++ b/docs/source/api/point_processes.md @@ -406,25 +406,32 @@ plt.show() ## Module Architecture -``` -optimizr/point_processes/ -├── mod.rs # Module root, public API re-exports -├── kernels.rs # ExcitationKernel trait + implementations -│ ├── ExponentialKernel (φ = αe^{-βt}) -│ ├── PowerLawKernel (φ = K₀(1+t)^{-1-α₀}) -│ └── CompletelyMonotoneKernel (Mittag-Leffler) -├── hawkes.rs # Hawkes process simulation & fitting -│ ├── HawkesProcess (univariate, Ogata thinning) -│ └── BivariateHawkes (buy/sell reaction flow) -├── mittag_leffler.rs # Special functions -│ ├── mittag_leffler() (E_{α,β}(z)) -│ ├── f_alpha_lambda() (Theorem 3.1 scaling fn) -│ ├── gamma() (Lanczos Γ function) -│ └── incomplete_gamma*() (upper/lower) -├── mixed_fbm.rs # Fractional Brownian motion -│ ├── FractionalBM (Cholesky & Hosking simulation) -│ └── MixedFractionalBM (a·B + b·B^H) -└── python_bindings.rs # PyO3 bindings for all functions +```{mermaid} +graph TD + MOD["📦 mod.rs\nPublic API re-exports"] + K["🔧 kernels.rs\nExcitationKernel trait"] + H["⚡ hawkes.rs\nSimulation & fitting"] + ML["🔢 mittag_leffler.rs\nSpecial functions"] + FBM["〰️ mixed_fbm.rs\nFractional Brownian motion"] + PY["🐍 python_bindings.rs\nPyO3 bindings"] + + MOD --> K + MOD --> H + MOD --> ML + MOD --> FBM + MOD --> PY + + K --> EK["ExponentialKernel\nφ = α·e^−βt"] + K --> PLK["PowerLawKernel\nφ = K₀(1+t)^−1−α"] + K --> CMK["CompletelyMonotoneKernel\nMittag-Leffler"] + + H --> HP["HawkesProcess K\nunivariate · Ogata thinning"] + H --> BH["BivariateHawkes K\nbuy/sell reaction flow"] + + ML --> mf["mittag_leffler · f_alpha_lambda\ngamma · incomplete_gamma"] + + FBM --> fbm1["FractionalBM\nCholesky & Hosking"] + FBM --> fbm2["MixedFractionalBM\na·B + b·B^H"] ``` --- diff --git a/docs/source/conf.py b/docs/source/conf.py index 70fa4e1..7f98ec4 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,6 +20,7 @@ extensions = [ 'sphinx.ext.intersphinx', 'sphinx.ext.mathjax', 'myst_parser', + 'sphinxcontrib.mermaid', ] # Add any paths that contain templates here, relative to this directory. @@ -76,3 +77,10 @@ myst_enable_extensions = [ "deflist", "dollarmath", ] + +# Custom CSS +html_css_files = ["custom.css"] + +# Mermaid configuration +mermaid_version = "10.9.0" +mermaid_init_js = "mermaid.initialize({startOnLoad:true, theme:'dark', themeVariables:{primaryColor:'#f97316',primaryTextColor:'#fff',primaryBorderColor:'#ea6a0a',lineColor:'#fb923c',secondaryColor:'#1e293b',tertiaryColor:'#0f172a'}});"