Oracles
All oracles solve the linear minimization problem
\[v^* = \arg\min_{v \in \mathcal{C}} \langle g, v \rangle\]
in-place via lmo(v, g). Any callable (v, g) -> v works as an oracle — plain functions are auto-wrapped by solve. Subtype AbstractOracle for specialized dispatch (e.g. active_set, sparse vertex protocol). See the Tutorial for an example of writing a custom oracle.
Marguerite.AbstractOracle — Type
AbstractOracleAbstract supertype for Frank-Wolfe linear minimization oracles.
Every concrete oracle lmo <: AbstractOracle is a callable struct invoked as lmo(v, g), writing the solution of
\[\min_{v \in C} \langle g, v \rangle\]
into v in-place.
Plain functions (v, g) -> v are auto-wrapped as FunctionOracle by solve. Non-function callable structs should subtype AbstractOracle directly or be wrapped explicitly with FunctionOracle for specialized dispatch (e.g. active_set, sparse vertex protocol).
Marguerite.FunctionOracle — Type
FunctionOracle{F} <: AbstractOracleWraps a plain function fn(v, g) -> v as an AbstractOracle.
lmo = FunctionOracle(my_lmo_function)
solve(f, lmo, x0; grad=∇f!)Simplex
Marguerite.Simplex — Type
Simplex{T, Equality}(r)Oracle for simplex constraints. The type parameter Equality controls whether the budget constraint is $\le$ or $=$.
Simplex(r)/Simplex(; r=1.0): capped simplex $\{x \ge 0,\; \sum x_i \le r\}$ProbSimplex(r)/ProbabilitySimplex(r): probability simplex $\{x \ge 0,\; \sum x_i = r\}$
Capped (Equality=false): Vertices are $\{0, r e_1, \ldots, r e_n\}$. Selects $r e_{i^*}$ where $i^* = \arg\min_i g_i$ when $g_{i^*} < 0$, otherwise the origin. Complexity: $O(n)$.
Probability (Equality=true): Vertices are $\{r e_1, \ldots, r e_n\}$. Always selects $r e_{i^*}$ where
\[i^* = \arg\min_i g_i\]
Complexity: $O(n)$.
Marguerite.ProbSimplex — Function
ProbSimplex(r=1.0)Convenience constructor for Simplex{T, true}(r) – the probability simplex $\{x \ge 0,\; \sum x_i = r\}$.
Marguerite.ProbabilitySimplex — Function
ProbabilitySimplex(r=1.0)Alias for ProbSimplex.
Knapsack
Marguerite.Knapsack — Type
Knapsack(budget, m)Oracle for the knapsack polytope
\[C = \{x \in [0,1]^m : \sum x_i \le \text{budget}\}\]
Selects up to budget indices with most negative gradient and sets them to 1; only indices with strictly negative gradient are selected. Complexity: $O(m \cdot k)$ where $k = \text{budget}$, via zero-allocation insertion sort. For large budgets ($k \approx m$), consider using a full sort or a Box oracle instead.
MaskedKnapsack
Marguerite.MaskedKnapsack — Type
MaskedKnapsack(budget, masked, m)Oracle for the knapsack polytope with masked indices fixed to 1:
\[C = \{x \in [0,1]^m : \sum x_i \le \text{budget},\; x_e = 1 \;\forall\; e \in \text{masked}\}\]
Fixes masked entries to 1, then selects up to $k = \text{budget} - |\text{masked}|$ non-masked indices with most negative gradient; only indices with strictly negative gradient are selected. Complexity: $O(m \cdot k)$ via zero-allocation insertion sort.
Box
Marguerite.Box — Type
Box(lb, ub)Oracle for the box constraint set
\[C = \{x : l_i \le x_i \le u_i\}\]
Each coordinate is solved independently: select $l_i$ when $g_i \ge 0$, $u_i$ when $g_i < 0$:
\[v_i = \begin{cases} l_i & g_i \ge 0 \\ u_i & g_i < 0 \end{cases}\]
Complexity: $O(n)$.
ScalarBox
ScalarBox is a memory-efficient alternative to Box when all lower bounds are the same scalar and all upper bounds are the same scalar. Use the convenience constructor Box(lb, ub) with scalar arguments:
lmo = Box(0.0, 1.0) # equivalent to ScalarBox{Float64}(0.0, 1.0)Marguerite.ScalarBox — Type
ScalarBox{T}(lb, ub)Oracle for a box constraint with uniform scalar bounds:
\[C = \{x : l \le x_i \le u \;\forall i\}\]
Memory-efficient alternative to Box when all bounds are identical. Convenience constructor: Box(lb::Real, ub::Real).
Complexity: $O(n)$.
WeightedSimplex
Marguerite.WeightedSimplex — Type
WeightedSimplex(α, β, lb)Oracle for the weighted simplex
\[C = \{x \ge l : \langle \alpha, x \rangle \le \beta\}\]
Shifts $u = x - l$, adjusted budget $\beta_{\mathrm{bar}} = \beta - \langle \alpha, l \rangle$. Then
\[u^* = \frac{\bar\beta}{\alpha_{i^*}}\, e_{i^*}, \quad i^* = \arg\min_i \left\{\frac{g_i}{\alpha_i} : g_i < 0\right\}\]
Returns $v = u^* + l$.
When all $g_i \ge 0$, returns the lower bound $l$.
Complexity: $O(m)$.
Spectraplex
The spectraplex is the natural constraint set for semidefinite programming (SDP) relaxations. The solver operates on vec(X) (the column major vectorization of the matrix variable), and the oracle computes the minimum eigenvector to produce a rank-1 vertex. The trace radius must be nonnegative.
Convenience: Spectraplex(n) gives the unit spectraplex ($r = 1$).
Marguerite.Spectraplex — Type
Spectraplex{T}(n, r)Oracle for the spectraplex (spectrahedron with trace constraint)
\[C = \{X \in \mathbb{S}_+^n : \operatorname{tr}(X) = r\}\]
The solver operates on vec(X) (length $n^2$). Given gradient $g$ (as a vector), reshapes to $G \in \mathbb{R}^{n \times n}$, symmetrizes, and computes the minimum eigenvector $v_{\min}$ of $\frac{1}{2}(G + G^\top)$. The vertex is the rank-1 matrix $r \, v_{\min} v_{\min}^\top$, written column major into the output buffer.
Convenience: Spectraplex(n) gives the unit spectraplex ($r = 1$).
Complexity: $O(n^3)$ (dense eigendecomposition).
Active Set Identification
At a solution $x^*$, Marguerite identifies which constraints are active (binding) to support KKT adjoint differentiation. Each oracle type has a specialized active_set method.
For custom oracles, this specialization is optional for primal solves but required for differentiated solves unless you pass assume_interior=true explicitly.
Marguerite.ActiveConstraints — Type
ActiveConstraints{T}Active constraint identification at a solution $x^*$.
Fields
bound_indices::Vector{Int}– indices pinned to boundsbound_values::Vector{T}– their bound valuesbound_is_lower::BitVector–trueif bound is a lower bound,falseif upperfree_indices::Vector{Int}– unconstrained variable indiceseq_normals– vector-like collection of equality constraint normals (in full space)eq_rhs– equality constraint RHS values
Marguerite.active_set — Function
active_set(lmo, x; tol=1e-8) -> ActiveConstraintsIdentify active constraints at solution x for the given oracle.
Returns an ActiveConstraints with bound-pinned indices, free indices, and equality constraint normals/RHS.