Gradient-Free-Optimizers icon indicating copy to clipboard operation
Gradient-Free-Optimizers copied to clipboard

Search-space API change in version 2.0

Open SimonBlanke opened this issue 4 months ago • 1 comments

Introduce a dataclass API for defining search spaces. This replaces the v1 “dict of numeric arrays” API and unlocks continuous ranges, SciPy distributions, categorical values, constants, and unions of spaces via + operator. Without importing custom primitives. This is how this could look like:

@dataclass
class SearchSpace(BaseSearchSpace):
    x       = np.arange(-10, 10, 0.1)          # numeric grid (ordered floats)
    lr      = st.loguniform(1e-5, 1e-2)        # log-uniform prior on (1e-5, 1e-2)
    filters = np.arange(16, 128 + 1, 16)       # numeric grid (ordered integers)
    act     = ["relu", "gelu", "tanh"]         # categorical (unordered)
    dropout = st.beta(2, 5)                    # Beta prior on [0, 1]
    use_bn  = [True, False]                    # categorical boolean
    seed    = 42                               # fixed constant
# Unions (disjoint alternatives) via operator overloading
CombinedSpace = SearchSpace1 + SearchSpace2

The current v1 API uses a dictionary of numeric arrays to define the search space. While this approach is simple, it is limited in scope. It forces users to discretize everything into finite arrays, even when the underlying parameter is truly continuous. There is no native way to specify priors from statistical distributions, to define constants, or to cleanly represent categorical values alongside numeric ranges. Expressing disjoint or alternative search spaces is also awkward, requiring manual merging of dictionaries rather than simple composition.

The proposed dataclass API addresses these issues directly. Parameters can be defined using native Python structures such as lists, ranges, or NumPy arrays for discrete sets, tuples for continuous bounds, and SciPy frozen distributions for priors. Constants are written as plain scalars. The dataclass structure gives each parameter a name, making the code self-documenting and IDE-friendly. By subclassing BaseSearchSpace, additional capabilities are available such as the __add__ method, which enables simple composition of independent search spaces. This operator overloading provides a natural syntax for defining unions of search spaces, where an optimizer can explore completely different parameter configurations in a single run. The result is a more expressive, composable, and maintainable way to define search spaces, while still allowing the library to infer the correct internal dimension type without requiring users to import special constructors.

  • A space is a dataclass subclassing BaseSearchSpace.
  • Fields use native Python structures, numpy arrays or SciPy frozen distributions. No GFO-specific constructors.
  • Spaces can be added (add) to create unions of disjoint sub-spaces.

SimonBlanke avatar Aug 15 '25 09:08 SimonBlanke