mixle.evolve.space moduleΒΆ

A small typed search space: the categorical/integer/box gap-filler over the numeric BO backend.

mixle.doe optimizes over a continuous numeric box (a sequence of (low, high) bounds). Real configuration search needs categorical and integer knobs too, and the evolutionary/bandit backends want to sample and walk neighbors natively. Space is the encoding layer that gives both:

  • Space.to_bounds() – a continuous (low, high) box for the BO backend, with categoricals encoded as integer indices ([-0.5, k - 0.5] so a round lands on each level with equal width).

  • Space.encode() / Space.decode() – the lossy round-trip between a config dict and the numeric vector the BO backend proposes (decode rounds integers / categorical indices, clips to range).

  • Space.sample() / Space.neighbors() – native draws and local moves for the evolutionary/bandit backends that handle categoricals without going through the numeric box.

The space lives in evolve (not doe) on purpose: doe stays a pure numeric-box optimizer, and the encoding policy that bridges categoricals into it is an evolve concern.

class Space(dims)[source]

Bases: object

A typed, named search space over Real / Integer / Categorical dims.

Construct from a dict mapping each parameter name to its dimension:

space = Space({"mu": Real(-5, 5), "k": Integer(1, 4), "family": Categorical(["a", "b"])})

Dimension order is the insertion order of the dict; encode() / decode() and to_bounds() all use that same fixed order so the numeric vector and the box align.

Parameters:

dims (dict[str, Real | Integer | Categorical])

dims: dict[str, Real | Integer | Categorical]
names: tuple[str, ...]
property ndim: int
to_bounds()[source]

The continuous (low, high) box for the BO backend (categoricals as integer indices).

Return type:

list[tuple[float, float]]

sample(rng)[source]

Draw a random config dict, each dimension sampled natively.

Parameters:

rng (RandomState)

Return type:

dict[str, Any]

encode(config)[source]

Encode a config dict into the numeric vector (in the fixed dimension order).

Parameters:

config (dict[str, Any])

Return type:

ndarray

decode(vector)[source]

Decode a numeric vector (BO proposal) back into a config dict (rounding / clipping).

Parameters:

vector (Sequence[float])

Return type:

dict[str, Any]

neighbors(point)[source]

All configs one local move away in exactly one dimension (the evolutionary mutation set).

Parameters:

point (dict[str, Any])

Return type:

list[dict[str, Any]]

class Real(lo, hi)[source]

Bases: object

A continuous dimension over [lo, hi].

Parameters:
lo: float
hi: float
bounds()[source]
Return type:

tuple[float, float]

sample(rng)[source]
Parameters:

rng (RandomState)

Return type:

float

encode(value)[source]
Parameters:

value (Any)

Return type:

float

decode(x)[source]
Parameters:

x (float)

Return type:

float

neighbors(value)[source]

A coarse local move: +/- 10% of the range, clipped to bounds.

Parameters:

value (Any)

Return type:

list[float]

class Integer(lo, hi)[source]

Bases: object

An integer dimension over the inclusive range [lo, hi].

Parameters:
lo: int
hi: int
bounds()[source]
Return type:

tuple[float, float]

sample(rng)[source]
Parameters:

rng (RandomState)

Return type:

int

encode(value)[source]
Parameters:

value (Any)

Return type:

float

decode(x)[source]
Parameters:

x (float)

Return type:

int

neighbors(value)[source]
Parameters:

value (Any)

Return type:

list[int]

class Categorical(choices)[source]

Bases: object

An unordered categorical dimension over a finite list of choices.

Parameters:

choices (tuple[Any, ...])

choices: tuple[Any, ...]
bounds()[source]
Return type:

tuple[float, float]

sample(rng)[source]
Parameters:

rng (RandomState)

Return type:

Any

encode(value)[source]
Parameters:

value (Any)

Return type:

float

decode(x)[source]
Parameters:

x (float)

Return type:

Any

neighbors(value)[source]
Parameters:

value (Any)

Return type:

list[Any]