Criteria

A Criterion is the outer-loop validation oracle: it slices the full Problem into a training subproblem, drives the inner solver, and returns the criterion value (and, when asked, the hypergradient chained through implicit_forward).

class sparho.Criterion[source]

Bases: Protocol

Outer-loop validation oracle.

Implementations: HeldOutMSE, HeldOutLogistic, CrossVal.

x0 is an optional warm-start coefficient guess threaded through to the inner solver. Single-split criteria forward it directly; CrossVal ignores caller-supplied x0 because it manages its own per-fold cache.

tol is an optional inner-solver tolerance that overrides the adapter’s default. Threaded through to Solver.__call__(tol=...). Used by HOAG-style outer loops to schedule inner accuracy across iterations.

value(problem, hp, solver, *, x0=None, tol=None)[source]
Parameters:
Return type:

float

value_and_hypergrad(problem, hp, solver, hypergrad_fn, *, x0=None, tol=None)[source]
Parameters:
Return type:

CriterionResult

__init__(*args, **kwargs)
class sparho.CriterionResult[source]

Bases: object

Outcome of Criterion.value_and_hypergrad().

coef and active_set are reported from the last (or only) inner solve; for CrossVal they come from the final fold and are diagnostic only — the user is expected to refit on the full data at best_hyperparam if a single final β is needed.

value: float
hypergrad: float | ndarray[tuple[Any, ...], dtype[floating]]
coef: ndarray[tuple[Any, ...], dtype[floating]]
active_set: ndarray[tuple[Any, ...], dtype[int32]]
__init__(value, hypergrad, coef, active_set)
Parameters:
Return type:

None

class sparho.HeldOutMSE[source]

Bases: object

Held-out mean-squared-error.

C(β) = (1/|val|) Σ_{i val} (yᵢ Xᵢ β)² — matches sklearn’s mean_squared_error (no 1/2). The gradient ∂C/∂β carries the factor of 2.

idx_train: ndarray[tuple[Any, ...], dtype[int32]]
idx_val: ndarray[tuple[Any, ...], dtype[int32]]
value(problem, hp, solver, *, x0=None, tol=None)[source]
Parameters:
Return type:

float

value_and_hypergrad(problem, hp, solver, hypergrad_fn, *, x0=None, tol=None)[source]
Parameters:
Return type:

CriterionResult

__init__(idx_train, idx_val)
Parameters:
Return type:

None

class sparho.HeldOutLogistic[source]

Bases: object

Held-out logistic loss: C(β) = (1/|val|) Σᵢ log(1 + exp(−yᵢ Xᵢβ)).

Labels assumed in {−1, +1} (sparho’s LogisticLoss convention).

idx_train: ndarray[tuple[Any, ...], dtype[int32]]
idx_val: ndarray[tuple[Any, ...], dtype[int32]]
value(problem, hp, solver, *, x0=None, tol=None)[source]
Parameters:
Return type:

float

value_and_hypergrad(problem, hp, solver, hypergrad_fn, *, x0=None, tol=None)[source]
Parameters:
Return type:

CriterionResult

__init__(idx_train, idx_val)
Parameters:
Return type:

None

class sparho.CrossVal[source]

Bases: object

K-fold cross-validation aggregator.

Wraps a single-split base criterion class (typically HeldOutMSE) over a tuple of (train_idx, val_idx) pairs. Both value and hypergradient are means across folds.

Build via kfold():

cv = CrossVal.kfold(problem.n_samples, k=5)

For classification, pass base=HeldOutLogistic to kfold.

Warm-start: with warm_start=True, each fold’s previous-iteration β* seeds the next inner solve at the same fold. Big wins when the inner solver dominates (sparse-X, small α, large active set); converges to the same answer as warm_start=False because Lasso is convex. The cache is mutable but excluded from equality / hash so the dataclass remains a well-behaved value object.

folds: tuple[tuple[ndarray[tuple[Any, ...], dtype[int32]], ndarray[tuple[Any, ...], dtype[int32]]], ...]
base: Callable[[ndarray[tuple[Any, ...], dtype[int32]], ndarray[tuple[Any, ...], dtype[int32]]], Criterion]
warm_start: bool
classmethod kfold(n_samples, k=5, *, shuffle=True, random_state=0, base=<class 'sparho.criteria.HeldOutMSE'>, warm_start=False)[source]

Build a CrossVal from sklearn.model_selection.KFold.

Parameters:
Return type:

CrossVal

value(problem, hp, solver, *, x0=None, tol=None)[source]
Parameters:
Return type:

float

value_and_hypergrad(problem, hp, solver, hypergrad_fn, *, x0=None, tol=None)[source]
Parameters:
Return type:

CriterionResult

__init__(folds, base=<class 'sparho.criteria.HeldOutMSE'>, warm_start=False, _cache=<factory>)
Parameters:
Return type:

None