for LowpassOracle {
type CutChoice = ParallelCut;
fn assess_feas(&mut self, x: &Arr) -> Option<(Arr, ParallelCut)> {
// ... passband and stopband checks ...
if val > self.up_sq {
// Two violations: val > up_sq AND val > lp_sq
return Some((col_k.clone(),
ParallelCut(val - self.up_sq, Some(val - self.lp_sq))));
}
// Single violation
return Some((col_k.clone(), ParallelCut(-val, None)));
}
}
```
`ParallelCut(beta0, Some(beta1))` represents a true parallel cut, while `ParallelCut(beta, None)` falls back to single-cut behavior.
---
class: nord-light, middle, center
## ๐ Architecture Summary
---
### ๐ Complete Trait Wiring Diagram
.mermaid[
graph TB
subgraph Algorithm["โ๏ธ Algorithms"]
CPF[cutting_plane_feas]
CPO[cutting_plane_optim]
CPQ[cutting_plane_optim_q]
BS[bsearch]
end
subgraph Oracle["๐ฎ Oracle Traits"]
OF[OracleFeas <+update()>]
OO[OracleOptim]
OOQ[OracleOptimQ]
OBS[OracleBS]
end
subgraph Space["๐ฅ SearchSpace"]
ELL[Ell]
ELS[EllStable]
EL1[Ell1D]
end
subgraph CutStrat["โ๏ธ Cut Strategy"]
SC[SingleCut]
PC[ParallelCut]
CT[CutType] -.->|internal| SC
CT -.->|internal| PC
end
CPF -->|"uses"| OF
CPF -->|"uses"| Space
CPF -->|"uses CutChoice=T"| CutStrat
CPO -->|"uses"| OO
CPO -->|"uses"| Space
CPO -->|"uses CutChoice=T"| CutStrat
CPQ -->|"uses"| OOQ
CPQ -->|"uses"| Space
CPQ -->|"uses CutChoice=T"| CutStrat
BS -->|"uses"| OBS
OBS -.->|"BSearchAdaptor wraps"| OF
style CPF fill:#fff3e0,stroke:#e65100,stroke-width:3px
style CPO fill:#fff3e0,stroke:#e65100,stroke-width:3px
style CPQ fill:#fff3e0,stroke:#e65100,stroke-width:3px
style BS fill:#fff3e0,stroke:#e65100,stroke-width:3px
style OF fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
style OO fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
style OOQ fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
style OBS fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px
style ELL fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
style ELS fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
style EL1 fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
style SC fill:#fce4ec,stroke:#ad1457,stroke-width:3px
style PC fill:#fce4ec,stroke:#ad1457,stroke-width:3px
style CT fill:#fce4ec,stroke:#ad1457,stroke-width:3px
]
---
### ๐ก Key Design Decisions
| Decision | Rationale |
|----------|-----------|
| **Associated types** for `ArrayType` and `CutChoice` | Allows type-level dispatch without runtime overhead |
| **`CutChoice = T` constraint** connects Oracle โ UpdateByCutChoice | Compile-time guarantee that cut types match |
| **`OracleFeas::update()`** default method | Replaced `OracleFeas2` โ one less trait ๐งน |
| **`SearchSpace::update_q()`** default method | Replaced `SearchSpaceQ` โ one less trait ๐งน |
| **`SingleCut` / `ParallelCut` newtypes** | Named types instead of bare `f64` / tuples ๐ |
| **Internal `CutType` trait** (in `ell.rs`) | Blanket impl avoids duplicating `UpdateByCutChoice` for `Ell` |
| **`BSearchAdaptor`** composes `OracleBS` from `OracleFeas` | Reuses existing traits without new abstractions |
---
### ๐ฏ Why This Architecture Works
.pull-left[
**โ
Zero-cost abstraction**
All polymorphism is resolved at compile time via generics and associated types. No `dyn` trait objects, no vtable dispatch.
**โ
Open for extension**
Add a new oracle โ implement `OracleOptim`. Add a new search space โ implement `SearchSpace`. No existing code changes.
]
.pull-right[
**โ
Type safety**
Wrong cut type or array type โ **compiler error**. The type system prevents mixing single cuts with parallel updates.
**โ
Leaner trait hierarchy**
Two traits eliminated (`OracleFeas2`, `SearchSpaceQ`) via default methods โ same power, fewer concepts. ๐งน
**โ
Composition over inheritance**
`BSearchAdaptor` = `OracleFeas` + `SearchSpace + Clone` โ `OracleBS`. Traits compose like building blocks. ๐งฑ
]
---
### ๐ Type-Level State Machine
The algorithm functions encode a **type-level protocol**:
```
cutting_plane_feas
where T: UpdateByCutChoice,
Oracle: OracleFeas,
Space: SearchSpace
๐
Oracle::CutChoice โโโ type-equals โโโโ T โโโ implements โโโโ UpdateByCutChoice
Space::ArrayType โโโ type-equals โโโโ Oracle::ArrayType โโโ T::ArrayType
```
If any of these type relationships is violated, the code **doesn't compile** ๐ซ. This is Rust's superpower โ catching architectural mismatches at compile time.
---
### ๐ Benchmark: ProfitOracle
```terminal
test_profit_oracle ...... regression: 83 iterations
test_profit_oracle_rb ..... regression: 90 iterations
test_profit_oracle_q ...... regression: 29 iterations
```
The quantized oracle (`OracleOptimQ`) converges **~3ร faster** in iterations than the continuous variant, because the discrete search space is smaller. The same algorithm function adapts via trait dispatch! โก
All numerical regression values are preserved exactly โ the type-level refactoring changed no arithmetic.
---
count: false
class: nord-dark, middle, center
## โ
Summary
### ๐ฆ Rust Traits Make the Ellipsoid Method:
- ๐ฎ **Generic** โ same algorithm, any oracle
- ๐ฅ **Flexible** โ any search space (`Ell`, `EllStable`, `Ell1D`)
- โ๏ธ **Composable** โ cut strategies as named types (`SingleCut` / `ParallelCut`)
- โก **Zero-cost** โ all dispatch resolved at compile time
- ๐งน **Clean** โ merged traits via default methods, two traits removed
- ๐งฉ **Extensible** โ new oracles, spaces, or strategies without touching existing code
The **three-pillar trait architecture** demonstrates how Rust's type system can model a complex optimization algorithm with clarity, safety, and performance. ๐
---
count: false
class: nord-dark, middle, center
## Q&A ๐ค
### Questions? ๐