Spaces¶
Space classes are exported from sekai and sekai.spaces; the utility functions from
sekai.spaces (also available as sekai.space_utils). See the Spaces guide.
Base class¶
Space
¶
Abstract base class for all observation and action spaces.
Spaces define the valid range of values for observations and actions. Unlike gymnasium, T is invariant so contains() is correctly typed.
Equality: the built-in spaces compare by value (and, being mutable, are not
hashable). A subclass that does not define __eq__ compares by identity, so
two instances are equal only if they are the same object; define __eq__
(and set __hash__ = None, or define it consistently) to compare by value.
Fundamental spaces¶
Box
¶
Box(low: ArrayLike | float, high: ArrayLike | float, shape: tuple[int, ...] | None = None, dtype: DTypeLike = float32, seed: SeedType = None)
Continuous n-dimensional box space.
Supports bounded, semi-bounded, and unbounded dimensions. Unbounded dimensions are sampled from a shifted/scaled normal distribution.
Bounds must not be NaN. For integer dtypes, infinite bounds (and any others outside
the dtype's range) become the dtype's limits, e.g. Box(-np.inf, np.inf, dtype=np.int64)
spans np.iinfo(np.int64).
is_bounded
property
¶
Returns (lower_bounded, upper_bounded) for the entire space.
zero
¶
The zero element, clipped into the bounds (the neutral value for padding).
sample
¶
Sample uniformly (bounded), exponentially (half-bounded) or normally (unbounded).
mask: optional array broadcastable to shape; entries where it is 0 are
not sampled but set to zero clipped into the bounds (zero()), e.g. the
weight of an asset that cannot be traded.
Discrete
¶
MultiDiscrete
¶
MultiDiscrete(nvec: ArrayLike, dtype: type = int64, seed: SeedType = None, start: ArrayLike | None = None)
Space for multi-dimensional discrete actions.
Each dimension i takes values in {start[i], ..., start[i] + nvec[i] - 1}.
sample
¶
Sample uniformly, optionally restricted by a mask.
mask: per entry, an int8 array of length nvec[i] with 1 marking allowed values. Give either a tuple of such arrays (nested to match nvec's shape, as in gymnasium) or one array whose last axis is padded to max(nvec). A mask of any other shape raises ValueError.
MultiBinary
¶
Composite spaces¶
Dict
¶
Dict(spaces: Mapping[str, Space[Any]] | None = None, seed: SeedType | dict[str, SeedType] | None = None, **spaces_kwargs: Space[Any])
Space of ordered dicts of sub-spaces.
Useful for heterogeneous observations, e.g. combining price arrays, portfolio state, and order book snapshots into a single observation.
seed
¶
Seed this space and, deterministically, every sub-space.
A dict of seeds ({"prices": 1, "cash": 2}) seeds the named sub-spaces
individually instead, leaving the others as they are, and returns -1 (there is
no single seed). A key that is not a sub-space raises ValueError.
Tuple
¶
Tuple(spaces: tuple[Space[Any], ...] | list[Space[Any]], seed: SeedType | list[SeedType] | None = None)
Space of ordered tuples of sub-spaces.
Unlike Dict, Tuple sub-spaces are accessed by index rather than key. Useful when the number and type of components are fixed and heterogeneous.
seed
¶
Seed this space and, deterministically, every sub-space.
A list of seeds ([1, None, 3]) seeds the sub-spaces individually instead, in
order (None leaves one as it is), and returns -1 (there is no single seed).
More seeds than sub-spaces raise ValueError.
Variable-size spaces¶
See Variable-size observations.
Sequence
¶
Sequence(feature_space: Space[Any], *, max_length: int | None = None, stack: bool = False, seed: SeedType = None)
Variable-length sequences of elements from a feature space.
For observations whose size changes from step to step: the trades printed
since the last decision, the news items in a window, the orders resting in
a book. With stack=False (the default) a sample is a tuple of elements;
with stack=True the elements are stacked into one batched sample (an
array of shape (length, *feature_shape) for a Box, a dict of arrays for
a Dict, and so on), which is what most models consume.
Sequences cannot be flattened or stacked across vector sub-envs into one
array; convert them to a fixed-size padded form with
sekai.PadSequenceObservation (which yields a MaskedBox) when a policy
needs fixed shapes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature_space
|
Space[Any]
|
The space of each element. |
required |
max_length
|
int | None
|
Optional upper bound on the length. Samples are uniform in
|
None
|
stack
|
bool
|
Represent samples as one stacked batch instead of a tuple. |
False
|
seed
|
SeedType
|
Seed for sampling. |
None
|
seed
¶
seed(seed: SeedType = None) -> int
Seed this space and, deterministically, its feature space.
sample
¶
Sample a sequence.
mask: optional (length, feature_mask); a given length fixes the
sequence length, and feature_mask is passed to every element's sample().
pack
¶
Build a sample of this space from a list of elements.
MaskedBox
¶
MaskedBox(low: ArrayLike | float, high: ArrayLike | float, shape: tuple[int, ...] | None = None, *, max_size: int, dtype: DTypeLike = float32, fill_value: ArrayLike | None = None, seed: SeedType = None)
Bases: Dict
A variable-size set of up to max_size Box elements, padded to a fixed shape.
Samples are dicts with two arrays:
"values": shape(max_size, *shape), one row per slot;"mask": int8 of shape(max_size,), 1 where the slot holds an element.
Empty slots hold fill_value (by default zero, clipped into the bounds). This
is the standard way to give a policy an observation whose size changes, such
as the assets in a trading universe that gains and loses listings: shapes stay
fixed, so samples batch across vector sub-envs, flatten, and convert to
gymnasium, while the mask tells a set encoder, transformer or masked mean which
rows are real.
MaskedBox is a Dict subclass, so every Dict utility (flatten, batch_space,
concatenate, FilterObservation, gymnasium conversion) applies unchanged.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
low
|
ArrayLike | float
|
Lower bound of each element (scalar or array of |
required |
high
|
ArrayLike | float
|
Upper bound of each element. |
required |
shape
|
tuple[int, ...] | None
|
Shape of one element; inferred from low/high when omitted. |
None
|
max_size
|
int
|
Number of slots. |
required |
dtype
|
DTypeLike
|
Element dtype. |
float32
|
fill_value
|
ArrayLike | None
|
Value of empty slots; must lie within the bounds. |
None
|
seed
|
SeedType
|
Seed for sampling. |
None
|
Utilities¶
Space utilities: flattening, batching, and (de)serialisation.
Every function here is a functools.singledispatch generic, so custom spaces
can opt in by registering an implementation:
@sekai.spaces.flatdim.register(MySpace)
def _(space: MySpace) -> int: ...
flatdim
¶
Return the number of dimensions when this space is flattened.
flatten
¶
Flatten a sample from space into a 1D float32 array.
float32 holds integers exactly only up to 2**24 in magnitude, and rounds float64 values, so such samples do not survive a flatten/unflatten round trip exactly.
unflatten
¶
Unflatten a 1D array back into a valid sample from space.
The result is always contained in space: Box values are cast to its dtype (integers rounded) and clipped into its bounds, MultiBinary values are thresholded at 0.5, and (Multi)Discrete one-hots are read with argmax.
flatten_space
¶
Return the float32 Box that flatten() maps samples of space into.
batch_space
¶
Return the space of n stacked samples from space (leading axis of size n).
concatenate
¶
Stack per-env samples of space into one batched sample.
Array spaces stack along a new leading axis; Dict and Tuple recurse into their sub-spaces. Spaces without a registered rule return a plain list.
iterate
¶
Split a batched sample of space back into per-env samples (inverse of concatenate).
A list of per-env samples is also accepted and iterated as-is.
zero_sample
¶
The neutral element of space: zeros clipped into bounds, the lowest discrete value, empty sequences and empty MaskedBox slots. Used for padding (frame stacks, delays).
space_from_jsonable
¶
Rebuild a space from the dict produced by its to_jsonable().