graph LR A["๐งฎ r\n(autocorrelation)"] --> B["๐ spectral_fact"] B --> C["๐ h\n(impulse response)"] C --> D["๐งฎ CSD quantize"] D --> E["๐๏ธ Verilog module"] style A fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style B fill:#fff3e0,stroke:#e65100,color:#2e3440,stroke-width:3px style C fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style D fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style E fill:#ffcdd2,stroke:#c62828,color:#2e3440,stroke-width:3px
graph LR A["r[k]\n(N samples)"] --> B["๐ก Oversample\nm = 100รN"] B --> C["๐ข R(ฯ) = ฮฃ rยทcos\n(freq response)"] C --> D["๐ log |R(ฯ)|"] D --> N(( )) style A fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style B fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style C fill:#fff3e0,stroke:#e65100,color:#2e3440,stroke-width:3px style D fill:#ffcdd2,stroke:#c62828,color:#2e3440,stroke-width:3px style N fill:#eceff1,stroke:#455a64,stroke-width:3px
graph LR N(( )) --> E["๐ Hilbert transform\nvia FFT"] E --> F["๐ ฯ(ฯ)\n(phase)"] F --> G["โฌ Decimate\nback to N"] G --> H["๐ IFFT\nโ h[n]"] style E fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style F fill:#fff3e0,stroke:#e65100,color:#2e3440,stroke-width:3px style G fill:#ffcdd2,stroke:#c62828,color:#2e3440,stroke-width:3px style H fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style N fill:#eceff1,stroke:#455a64,stroke-width:3px
graph LR A["r[k]\n(N samples)"] --> B["๐ณ Build P(z)\n2N-1 coefficients"] B --> C["๐ฏ Initial guesses\ninitial_aberth_autocorr"] C --> D["๐ Aberth iteration\naberth_autocorr"] D --> N(( )) style A fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style B fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style C fill:#ffcdd2,stroke:#c62828,color:#2e3440,stroke-width:3px style D fill:#fff3e0,stroke:#e65100,color:#2e3440,stroke-width:3px style N fill:#eceff1,stroke:#455a64,stroke-width:3px
graph LR N(( )) --> E E{"|z| < 1?"} -->|"Yes โ "| F["๐ฅ Keep root"] E -->|"No โ"| G["๐ช Take 1/z"] F --> H["๐ poly_from_roots"] G --> H H --> I["โ๏ธ Normalize\nโ h[n]"] style E fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style F fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style G fill:#ffcdd2,stroke:#c62828,color:#2e3440,stroke-width:3px style H fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style I fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style N fill:#eceff1,stroke:#455a64,stroke-width:3px
graph LR subgraph "FFT ๐ ฐ๏ธ" FA["100รN oversampling"] FB["FFT (O(N log N))"] FC["Hilbert + IFFT"] FD["~0.1 ms ร 1482 = 148 ms"] end subgraph "Root ๐ ฑ๏ธ" RA["N coefficients"] RB["Aberth (O(Nยฒ/4))"] RC["poly_from_roots"] RD["~0.05 ms ร 333 = 17 ms"] end style FA fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style FB fill:#e1f5fe,stroke:#01579b,color:#2e3440,stroke-width:3px style FC fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style FD fill:#ffcdd2,stroke:#c62828,color:#2e3440,stroke-width:3px style RA fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style RB fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style RC fill:#a5d6a7,stroke:#1b5e20,stroke-width:3px style RD fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px
graph TD subgraph "API" SF["spectral_fact(r)\n(default: fft, more stable)"] end subgraph "Methods" SFR["spectral_fact_root(r, tol)\nโ ginger::aberth_autocorr\nโ poly_from_roots"] SFF["spectral_fact_fft(r)\nโ FFTW / Hilbert\nโ IFFT"] ISF["inverse_spectral_fact(h)\nโ convolution O(nยฒ)"] end SF --> SFR SF --> SFF style SF fill:#fff3e0,stroke:#e65100,color:#2e3440,stroke-width:3px style SFR fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style SFF fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style ISF fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px
graph TD Q{"Need spectral factor?"} --> A{"Production\nstability?"} A -->|"Yes โ "| B["๐ ฐ๏ธ FFT\nStable ยท Exact ยท Default"] A -->|"No"| C{"Want faster\niterations?"} C -->|"Yes"| D["๐ ฑ๏ธ Root-finding\nFast ยท Tunable"] C -->|"No"| E{"Large N\n> 64?"} E -->|"Yes"| B E -->|"No"| D style Q fill:#fff3e0,stroke:#e65100,color:#2e3440,stroke-width:3px style A fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style B fill:#e3f2fd,stroke:#1565c0,color:#2e3440,stroke-width:3px style C fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px style D fill:#c8e6c9,stroke:#2e7d32,color:#2e3440,stroke-width:3px style E fill:#f3e5f5,stroke:#7b1fa2,color:#2e3440,stroke-width:3px