graph LR XC["Center x_c\ncurrent guess"] OR["Oracle\nassess(x_c)"] CUT["Cut\n(g, beta)"] UPD["Ellipsoid update\nshrink M, kappa"] XC -->|"x_c"| OR OR -->|"infeasible"| CUT CUT --> UPD UPD -->|"next iter"| XC OR -->|"feasible โ "| DONE["Return x_c"] style XC fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style OR fill:#fff9c4,stroke:#f57f17,stroke-width:3px style CUT fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style UPD fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style DONE fill:#d1c4e9,stroke:#6a1b9a,stroke-width:3px
graph LR PY["ellalgo ๐\nnumpy"] CPP["ellalgo-cpp โ๏ธ\nvalarray + Matrix"] RS["ellalgo-rs ๐ฆ\ncustom Arr"] LMIC["lmi-solver-cpp โ๏ธ\nEigen"] LMIR["lmi-solver-rs ๐ฆ\nndarray"] PY -.->|"same math"| CPP PY -.->|"same math"| RS CPP -->|"Ell engine"| LMIC RS -->|"Ell engine"| LMIR style PY fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style CPP fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style RS fill:#ffe0b2,stroke:#e65100,stroke-width:3px style LMIC fill:#d1c4e9,stroke:#6a1b9a,stroke-width:3px style LMIR fill:#f8bbd0,stroke:#c2185b,stroke-width:3px
Lowpass benchmark ยท cProfile (13.5 s) ndarray.dot (1.6 M calls) 45% assess_feas Python loop 33% Ell._update_core 7% RoundRobin.next (1.6 M calls) 5% np.outer + np.finfo + np.all 3% 1.6 M tiny per-row dots โ ~128 per oracle call, in pure Python
graph TD subgraph BEFORE["Before ยท per-row"] B1["row k"] --> B2["dot(row, x)"] --> B3["check"] --> B4["row k+1 ๐"] end subgraph AFTER["After ยท one gemv"] A1["A @ x\none BLAS call"] --> A2["boolean masks\n+ first-true"] --> A3["land cursor"] end style B1 fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style B2 fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style B3 fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style B4 fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style A1 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style A2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style A3 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
Scan primitive on the real (480 ร 32) spectrum per-row dots 2 487 ยตs spectrum @ x 112 ยตs โ 22ร faster on the primitive
graph LR PEEK["peek_next()\nread cursor\n(no advance)"] MASK["_first_rotated\nfirst True in\ncyclic order"] SET["seek(k)\nland on violation"] NONE["no violation\ncursor unchanged"] PEEK --> MASK MASK -->|"found โ "| SET MASK -->|"none"| NONE style PEEK fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style SET fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style NONE fill:#fff9c4,stroke:#f57f17,stroke-width:3px
Lowpass ยท honest git-stash A/B ยท best-of-3 parallel cut 14.60 s 3.73 s ยท 3.91ร single cut 35.29 s 8.16 s ยท 4.33ร Ell core micro-fixes (separate micro-bench): 1.09โ1.40ร across n = 3, 8, 32. Suite: 163 tests + 41 doctests + 14 bench asserts green; black / isort / flake8 clean. โ
xmake ยท MSVC release ยท /arch:AVX2 ยท /W4 /WX lowpass parallel 229.3 ms 173.1 ms ยท 1.32ร LMI_Lazy 206.4 ยตs 144.7 ยตs ยท 1.43ร ELL_normal (micro) 72.8 ยตs 52.8 ยตs ยท 1.38ร lmi-solver solve 26.99 ยตs 16.24 ยตs ยท 1.66ร Zero warnings; xmake test green in both repos. โ
lmi-solver-cpp ยท full LMI solve (stash A/B) Ell<VectorXd> 26.99 ยตs 16.24 ยตs ยท 1.66ร EllStable<VectorXd> 25.81 ยตs 17.80 ยตs ยท 1.45ร
cargo ยท release ellalgo-rs ยท dim 50 20.37 ยตs 6.99 ยตs ยท 2.91ร ellalgo-rs ยท dim 100 82.95 ยตs 31.70 ยตs ยท 2.62ร lmi assess 2ร2 0.873 ยตs 0.172 ยตs ยท 5.08ร lmi-solver solve 222.8 ยตs 150.2 ยตs ยท 1.48ร Suite green incl. assert_eq!(result, 281); cargo clippy clean. โ
graph TD ROOT["Hot loop:\nM, x_c update"] ROOT --> PY["๐ Python\nnp.outer + np.finfo\nper call"] ROOT --> CPP["โ๏ธ C++\nvalarray temps +\nstd::valarray g(n)"] ROOT --> RS["๐ฆ Rust\ndot_mv Vec +\nndarray view/dot"] PY --> FIX["Fix:\npre-allocate scratch\n(EllStable already did!)"] CPP --> FIX RS --> FIX style ROOT fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style PY fill:#ffe0b2,stroke:#e65100,stroke-width:3px style CPP fill:#d1c4e9,stroke:#6a1b9a,stroke-width:3px style RS fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style FIX fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
graph LR ENG["engine fix\n(uncommitted on dev)"] ENG -->|"xmake / local path โ "| OKC["lmi-solver-cpp\nsees it now"] ENG -->|"CMake v1.6.12 โณ"| WAITC["lmi-solver-cpp\nsees it after release"] ENG -->|"cargo local patch โ "| OKR["lmi-solver-rs\nsees it now"] ENG -->|"crates.io 0.1.8 โณ"| WAITR["lmi-solver-rs\nsees it after release"] style ENG fill:#fff9c4,stroke:#f57f17,stroke-width:3px style OKC fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style OKR fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style WAITC fill:#f8bbd0,stroke:#c2185b,stroke-width:3px style WAITR fill:#f8bbd0,stroke:#c2185b,stroke-width:3px