graph LR subgraph Pioneers["1970s Pioneers"] S[Shor\n1960s-70s] N[Nemirovski\n& Yudin\n1972] end subgraph Breakthrough["Late 1970s"] K[Khachiyan\n1979] end subgraph Impact["Impact"] LP[LP in P ๐] CVX[Convex Opt.\nPolynomial-time] end S --> K N --> K K --> LP K --> CVX style Pioneers fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style Breakthrough fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px style Impact fill:#fff9c4,stroke:#f57f17,stroke-width:3px style S fill:#bbdefb,stroke:#1565c0,stroke-width:3px style N fill:#bbdefb,stroke:#1565c0,stroke-width:3px style K fill:#a5d6a7,stroke:#2e7d32,stroke-width:3px style LP fill:#fff9c4,stroke:#f57f17,stroke-width:3px style CVX fill:#fff9c4,stroke:#f57f17,stroke-width:3px
graph LR A[Problem] --> B{Need to evaluate\nall constraints?} B -->|"Yes โ "| C[IPM / Simplex] B -->|"No โ have oracle ๐ฎ"| D[Ellipsoid Method] D --> E["Few vars, many constraints\nDiscrete vars\nSDP with structure"] style A fill:#fff3e0,stroke:#e65100,stroke-width:3px style B fill:#ffcdd2,stroke:#c62828,stroke-width:3px style C fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style D fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style E fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px
graph LR subgraph K["Convex Set K"] center(("x*")) end outside(("xโ")) center -.- outside style K fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style center fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style outside fill:#ffcdd2,stroke:#c62828,stroke-width:3px
graph LR subgraph K["Convex Set K"] center(("x*")) end x0(("xโ")) sep((" ")) x0 ---|"g (normal)"| sep style K fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style center fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style x0 fill:#ffcdd2,stroke:#c62828,stroke-width:3px style sep fill:#fff3e0,stroke:#e65100,stroke-width:3px linkStyle 0 stroke:#f44336,stroke-width:3px,stroke-dasharray: 5 5
graph LR E["Ellipsoid"] --> H["Half-space\neliminated"] E --> H2["Half-space\nkept"] style E fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style H fill:#fce4ec,stroke:#ad1457,stroke-width:3px style H2 fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px
graph LR E2["Ellipsoid"] --> H3["More than half\neliminated โ๏ธ"] E2 --> H4["Less than half\nkept"] style E2 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style H3 fill:#fce4ec,stroke:#ad1457,stroke-width:3px style H4 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
graph LR subgraph Epi["Epigraph of f"] line("f(xโ) + g'(x-xโ)") f("f(x)") end x0(("xโ")) f --- x0 line --- x0 style Epi fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style f fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style line fill:#ffcdd2,stroke:#c62828,stroke-width:3px style x0 fill:#fff3e0,stroke:#e65100,stroke-width:3px
graph LR subgraph 2D["2D Ellipsoid"] center(("xc โ center")) axis1[" "] axis2[" "] end center --- axis1 center --- axis2 style 2D fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style center fill:#ffcdd2,stroke:#c62828,stroke-width:3px style axis1 fill:none style axis2 fill:none linkStyle 0 stroke:#ff9800,stroke-width:3px linkStyle 1 stroke:#ff9800,stroke-width:3px
graph LR subgraph K["Feasible Region K"] center(("x*")) end E0["Initial\nEllipsoid"] --- K style K fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px style center fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style E0 fill:#e3f2fd,stroke:#1565c0,stroke-dasharray: 5 5,stroke-width:3px
graph TD Init["Initialize Ellipsoid\nEโ โ K"] --> Query["Query Oracle at xc"] Query --> Check{"Feasible?"} Check -->|"Yes โ "| Done["Return xc"] Check -->|"No โ got cut (g, ฮฒ)"| Update["Update Ellipsoid\nE โ smaller E"] Update --> Check2{"Volume small\nor empty?"} Check2 -->|"No"| Query Check2 -->|"Yes"| Fail["Return infeasible"] style Init fill:#fff3e0,stroke:#e65100,stroke-width:3px style Query fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style Check fill:#ffcdd2,stroke:#c62828,stroke-width:3px style Done fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style Update fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style Check2 fill:#ffcdd2,stroke:#c62828,stroke-width:3px style Fail fill:#ffcdd2,stroke:#c62828,stroke-width:3px
sequenceDiagram participant CP as CuttingPlane participant SS as SearchSpace participant OF as OracleFeas loop Cutting Plane Iterations CP->>SS: request xc() SS-->>CP: return xc CP->>OF: assess_feas(xc) alt Feasible (cut is None) OF-->>CP: return None CP-->>CP: Return solution else Infeasible OF-->>CP: return cut (g, ฮฒ) CP->>SS: update_bias_cut(cut) alt Success SS-->>CP: continue else Failed SS-->>CP: status CP-->>CP: Return None end end end
graph LR A["Volume\nshrinks by\ne^(-1/2n)"] -->|"After k iterations"| B["Volume\nreduced by\ne^(-k/2n)"] style A fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style B fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px
graph LR subgraph E["Ellipsoid"] center(("xc")) cut0[" "] cut1[" "] end center --- cut0 center --- cut1 style E fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style center fill:#ffcdd2,stroke:#c62828,stroke-width:3px style cut0 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style cut1 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px linkStyle 0 stroke:#4caf50,stroke-width:3px linkStyle 1 stroke:#4caf50,stroke-width:3px
graph LR subgraph Before["Before"] E1["Ellipsoid"] -->|"Single cut"| E2["Smaller"] E1 -->|"Parallel cut"| E3["Much smaller ๐"] end style Before fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style E1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style E2 fill:#bbdefb,stroke:#1565c0,stroke-width:3px style E3 fill:#81d4fa,stroke:#1565c0,stroke-width:3px
graph LR subgraph Iteration["Iteration k"] xk(("xc")) gk(("ฮณ")) end xk -->|"assess_optim"| Check2{"fโ(xc) โค ฮณ?"} Check2 -->|"Yes โ shrink ฮณ โ๏ธ"| Central["Central Cut\n(ฮฒ=0)"] Check2 -->|"No"| Deep["Deep Cut\n(ฮฒ = fโ(xc) - ฮณ)"] Central -->|"New xc', smaller ฮณ'"| Next["Next iteration"] Deep -->|"New xc'"| Next style xk fill:#fff3e0,stroke:#e65100,stroke-width:3px style gk fill:#ffcdd2,stroke:#c62828,stroke-width:3px style Check2 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style Central fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style Deep fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style Next fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
graph LR subgraph Continuous["Continuous Space"] xc(("xc")) xq(("xq โ nearest")) end xc --- xq style Continuous fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style xc fill:#ffcdd2,stroke:#c62828,stroke-width:3px style xq fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px linkStyle 0 stroke:#ff9800,stroke-width:3px,stroke-dasharray: 5 5
graph LR A["Assemble\nA(x)"] --> B["LDLT\nFactorization"] B --> C{"A(x) โป 0?"} C -->|"Yes โ "| D["Feasible"] C -->|"No โ"| E["Witness\nVector w"] E --> F["g_i = w'F_i w\nฮฒ = -w'A(x)w"] style A fill:#fff3e0,stroke:#e65100,stroke-width:3px style B fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style C fill:#ffcdd2,stroke:#c62828,stroke-width:3px style D fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style E fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style F fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
graph LR subgraph Normal["Normal Update"] P["Update\nP matrix"] -->|"O(nยฒ)"| P2["New P"] end subgraph Stable["Stable Update"] L["Update\nLDL^T factors"] -->|"O(nยฒ)"| L2["New L, D"] end style Normal fill:#fce4ec,stroke:#ad1457,stroke-width:3px style Stable fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px style P fill:#ffcdd2,stroke:#c62828,stroke-width:3px style P2 fill:#ffcdd2,stroke:#c62828,stroke-width:3px style L fill:#a5d6a7,stroke:#2e7d32,stroke-width:3px style L2 fill:#a5d6a7,stroke:#2e7d32,stroke-width:3px
graph LR A["Without Parallel\nCuts"] --> B["200-300\niterations"] C["With Parallel\nCuts"] --> D["80-120\niterations ๐"] style A fill:#fce4ec,stroke:#ad1457,stroke-width:3px style B fill:#ffcdd2,stroke:#c62828,stroke-width:3px style C fill:#e8f5e9,stroke:#2e7d32,stroke-width:3px style D fill:#a5d6a7,stroke:#2e7d32,stroke-width:3px
graph LR P1["Problem\n(paramsโ)"] --> S1["Solve โ Eโ"] P2["Problem\n(paramsโ)"] --> S2["Warm-start\nfrom Eโ โ Eโ"] P3["Problem\n(paramsโ)"] --> S3["Warm-start\nfrom Eโ โ Eโ"] style P1 fill:#fff3e0,stroke:#e65100,stroke-width:3px style P2 fill:#fff3e0,stroke:#e65100,stroke-width:3px style P3 fill:#fff3e0,stroke:#e65100,stroke-width:3px style S1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style S2 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style S3 fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
graph TD Start["Convex Problem"] --> Oracle["Separation\nOracle ๐ฎ"] Oracle --> Cut{"Cut or\nFeasible?"} Cut -->|"Feasible โ "| Done["Solution Found!"] Cut -->|"Cut (g, ฮฒ)"| Ellipsoid["Update\nEllipsoid ๐ฅ"] Ellipsoid --> Loop{"Volume\nsmall?"} Loop -->|"No"| Oracle Loop -->|"Yes"| Fail["Infeasible โ"] style Start fill:#fff3e0,stroke:#e65100,stroke-width:3px style Oracle fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style Cut fill:#ffcdd2,stroke:#c62828,stroke-width:3px style Done fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style Ellipsoid fill:#f3e5f5,stroke:#7b1fa2,stroke-width:3px style Loop fill:#ffcdd2,stroke:#c62828,stroke-width:3px style Fail fill:#ffcdd2,stroke:#c62828,stroke-width:3px