graph LR A("Roots from\nAberth Method") --> B{"Which order\n to multiply?"} B --> C("Naive Order\n โ Large errors") B --> D("Leja Order\n โ Stable") style A fill:#e3f2fd,stroke:#1565c0 style B fill:#fff9c4,stroke:#f9a825 style C fill:#ffcdd2,stroke:#c62828 style D fill:#c8e6c9,stroke:#2e7d32
graph TD subgraph Roots["Root Distribution on Complex Plane"] direction LR R1(("rโ")) R2(("rโ")) C(("Unit\nCircle")) R1r(("1/rโ")) R2r(("1/rโ")) R1 ---|"reciprocal"| R1r R2 ---|"reciprocal"| R2r C -.- R1 C -.- R1r end style R1 fill:#bbdefb,stroke:#1565c0 style R2 fill:#bbdefb,stroke:#1565c0 style R1r fill:#fce4ec,stroke:#c62828 style R2r fill:#fce4ec,stroke:#c62828 style C fill:#e8f5e9,stroke:#2e7d32,stroke-dasharray: 5 5
graph LR subgraph BadOrder["โ Bad: Adjacent roots multiplied first"] direction LR B1("(x - 0.01)") --> B2("(x - 0.02)") B2 --> B3("... small coeffs") B3 --> B4("(x - 100)") B4 --> B5("โ Catastrophic\ncancellation") end style BadOrder fill:#fce4ec,stroke:#c62828 style B5 fill:#ffcdd2,stroke:#c62828,stroke-width:3px
graph LR subgraph Leja["Leja Order"] L1["โ 0.01"] --> L2["โก 100"] --> L3["โข 0.1"] --> L4["โฃ 10"] --> L5["โค 1"] end L1 -. "min dist to {}: 0.01" .- L1 L2 -. "max min dist: |100-0.01|" .- L2 L3 -. "max min dist: min(|0.1-0.01|,|0.1-100|)" .- L3 L4 -. "max min dist: min(|10-0.01|,|10-100|,|10-0.1|)" .- L4 L5 -. "โช last remaining" .- L5 style L1 fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px style L2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style L3 fill:#a5d6a7,stroke:#2e7d32,stroke-width:2px style L4 fill:#81c784,stroke:#2e7d32,stroke-width:2px style L5 fill:#66bb6a,stroke:#2e7d32,stroke-width:1px style Leja fill:#e8f5e9
graph TD subgraph VdC["vdC sequence values"] V1["n=1: 0.1โ = 0.5 โ 180ยฐ"] V2["n=2: 0.01โ = 0.25 โ 90ยฐ"] V3["n=3: 0.11โ = 0.75 โ 270ยฐ"] V4["n=4: 0.001โ = 0.125 โ 45ยฐ"] end style V1 fill:#e3f2fd,stroke:#1565c0 style V2 fill:#bbdefb,stroke:#1565c0 style V3 fill:#90caf9,stroke:#1565c0 style V4 fill:#64b5f6,stroke:#1565c0 style VdC fill:#e3f2fd
graph TD A("ginger-cpp\nLibrary") --> B("Aberth-Ehrlich\nMethod") A --> C("Bairstow's\nMethod") A --> D("Auto-correlation\nVariants") B --> E("Complex Roots ๐งฎ") C --> F("Quadratic Factors ๐ฒ") D --> G("Palindromic\nPolynomials ๐") style A fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style B fill:#bbdefb,stroke:#1565c0 style C fill:#bbdefb,stroke:#1565c0 style D fill:#bbdefb,stroke:#1565c0 style E fill:#e8f5e9,stroke:#2e7d32 style F fill:#e8f5e9,stroke:#2e7d32 style G fill:#fff9c4,stroke:#f9a825
graph LR subgraph Critical["๐ด Critical"] F1["1. ST Aberth: 96K heap allocs\nper call (std::future)"] F2["2. Bairstow: 2M+ coeff\ncopies per call"] end subgraph Medium["๐ก Medium"] F3["3. ThreadPool re-created\nper function call"] F4["4. Missing reserve()\nin guess generators"] F7["7. LDS sequences\nrecomputed each call"] end subgraph Low["๐ข Low"] F5["5. No SIMD compiler flags"] F6["6. Deprecated benchmark API"] end style Critical fill:#fce4ec,stroke:#c62828 style Medium fill:#fff9c4,stroke:#f9a825 style Low fill:#e8f5e9,stroke:#2e7d32 style F1 fill:#ffcdd2,stroke:#c62828 style F2 fill:#ffcdd2,stroke:#c62828 style F3 fill:#fff9c4,stroke:#f9a825 style F4 fill:#fff9c4,stroke:#f9a825 style F5 fill:#c8e6c9,stroke:#2e7d32 style F6 fill:#c8e6c9,stroke:#2e7d32 style F7 fill:#fff9c4,stroke:#f9a825
graph TD subgraph Aberth["Aberth Method"] A1["poly_from_roots(zs)"] --> T1["Known roots: 1,-1 โ [1,0,-1]"] A1 --> T2["Complex conj: i,-i โ [1,0,1]"] A1 --> T3["Aberth reconstruction: 1e-8 tolerance"] end subgraph AutocorrAberth["Autocorr Aberth"] AA1["poly_from_autocorr_roots(zs)"] --> AT1["Degree-8 palindromic: 1e-8"] AA1 --> AT2["FIR filter (degree 48): 1e-3"] end subgraph Bairstow["Bairstow/Bairstow-Autocorr"] B1["poly_from_quadratic_factors(vrs)"] --> BT1["Single factor: [1,0,-1]"] B1 --> BT2["Two factors: [1,0,-5,0,4]"] B1 --> BT3["General factors: [1,-2,-15,-4,20]"] B1 --> BT4["Pbairstow reconstruction: 1e-8"] BA1["poly_from_autocorr_factors(vrs)"] --> BAT1["Degree-8 autocorr: 1e-8"] end style Aberth fill:#e3f2fd,stroke:#1565c0 style AutocorrAberth fill:#fff9c4,stroke:#f9a825 style Bairstow fill:#e8f5e9,stroke:#2e7d32 style T1 fill:#c8e6c9,stroke:#2e7d32 style T2 fill:#c8e6c9,stroke:#2e7d32 style T3 fill:#c8e6c9,stroke:#2e7d32 style AT1 fill:#c8e6c9,stroke:#2e7d32 style AT2 fill:#c8e6c9,stroke:#2e7d32 style BT1 fill:#c8e6c9,stroke:#2e7d32 style BT2 fill:#c8e6c9,stroke:#2e7d32 style BT3 fill:#c8e6c9,stroke:#2e7d32 style BT4 fill:#c8e6c9,stroke:#2e7d32 style BAT1 fill:#c8e6c9,stroke:#2e7d32
graph TD PFR["poly_from_roots"] --> LO["leja_order"] PFR --> CONV("Convolution Loop") PQPF["poly_from_quadratic_factors"] --> ROOTEX("roots_from_quadratic") ROOTEX --> PFR PFAR["poly_from_autocorr_roots"] --> RECIP("Add 1/z") RECIP --> PFR PFAF["poly_from_autocorr_factors"] --> ROOTEX2("roots_from_quadratic") ROOTEX2 --> RECIP2("Add 1/z per root") RECIP2 --> PFR style PFR fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px style LO fill:#bbdefb,stroke:#1565c0 style CONV fill:#bbdefb,stroke:#1565c0 style PQPF fill:#fff9c4,stroke:#f9a825 style PFAR fill:#fce4ec,stroke:#c62828 style PFAF fill:#f3e5f5,stroke:#7b1fa2 style ROOTEX fill:#e1d5e7,stroke:#7b1fa2 style ROOTEX2 fill:#e1d5e7,stroke:#7b1fa2 style RECIP fill:#ffcdd2,stroke:#c62828 style RECIP2 fill:#e1bee7,stroke:#7b1fa2
graph LR A("Current\nWork") --> B("Leja-Ordered\nConvolution") A --> C("Thread-Local\nScratch") A --> D("Persistent\nThreadPool") B --> E("Higher-Degree\nPolynomials ๐") C --> F("Faster FIR\nFilter Analysis โก") D --> G("Real-Time\nSignal Processing ๐ด") E --> H("Production-Grade\nRoot Finder ๐ญ") style A fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style B fill:#bbdefb,stroke:#1565c0 style C fill:#bbdefb,stroke:#1565c0 style D fill:#bbdefb,stroke:#1565c0 style E fill:#e8f5e9,stroke:#2e7d32 style F fill:#e8f5e9,stroke:#2e7d32 style G fill:#e8f5e9,stroke:#2e7d32 style H fill:#fff9c4,stroke:#f9a825,stroke-width:3px