Skip to content

bbob-noisy

bbobax.bbob_noisy

The bbob-noisy suite, f101-f130.

Thirty problems built from eight of the noiseless functions under the three official noise models, at the paper's two severities. Transcribed from the vendored bbobbenchmarks.py, whose _evalfull makes the composition explicit:

fadd = f_opt + boundaryhandling(x)
ftrue = raw(x - x_opt)          # the core, without the function's own penalty
fval = noise(ftrue) + fadd

Two things in that are easy to get wrong, and neither is "the noiseless function plus noise":

  • Boundary handling is uniform here. Every noisy problem uses defaultboundaryhandling(x, 100), replacing whatever factor its noiseless counterpart used -- including the several that have no penalty at all. Noise makes the outside of the box exploitable in a way it is not without it.
  • Three of the bases are reparameterized. f116-f118 use an ellipsoid of conditioning 1e4, not the noiseless f10's 1e6; f125-f127 scale Griewank-Rosenbrock by 1 rather than 10. (The Gallagher variants look reparameterized too -- highpeakcond = 1000 ** .5 where f22 has 1000 -- but that is f21's own value in the reference's parameterization, which is the square root of the paper's. They are f21 unchanged.)

The suite is a table because it is a table: a base function, a noise model, and a severity. Noisy composes those three, so nothing here restates a function that already exists.

Noisy

Bases: BBOBProblem

A noiseless BBOB function under one of the three noise models.

A base class rather than a protocol, and a wrapper rather than 30 subclasses: the suite varies only in which function, which model and which severity, so those are constructor arguments and the composition is written once.

Parameters:

Name Type Description Default
problem BBOBProblem

The noiseless function underneath, already at its dimension.

required
noise_model NoiseModel

The model, at a pinned severity -- Gaussian.severe() and friends, since a published f101-f130 number is at one of the paper's two points.

required
**kwargs Any

Passed to BBOBProblem.

{}
Source code in src/bbobax/bbob_noisy.py
class Noisy(BBOBProblem):
    """A noiseless BBOB function under one of the three noise models.

    A base class rather than a protocol, and a wrapper rather than 30
    subclasses: the suite varies only in which function, which model and which
    severity, so those are constructor arguments and the composition is written
    once.

    Args:
        problem: The noiseless function underneath, already at its dimension.
        noise_model: The model, at a pinned severity -- `Gaussian.severe()`
            and friends, since a published f101-f130 number is at one of the
            paper's two points.
        **kwargs: Passed to `BBOBProblem`.

    """

    name = "bbob-noisy"

    # Every noisy problem's boundary handling, replacing the base function's
    # own (`defaultboundaryhandling(x, 100.)` on all three noisy mixins).
    penalty_factor: float = 100.0

    def __init__(self, problem: BBOBProblem, noise_model: NoiseModel, **kwargs: Any):
        """Initialize the noisy problem."""
        super().__init__(num_dims=problem.num_dims, noise_model=noise_model, **kwargs)
        self.problem = problem

    def _sample_x_opt(self, key: jax.Array) -> jax.Array:
        """Draw the optimum the way the underlying function requires."""
        return self.problem._sample_x_opt(key)

    def _value(self, x: jax.Array, params: BBOBParams) -> tuple[jax.Array, jax.Array]:
        # The base's own penalty is discarded, not added to: the bbob-noisy suite
        # replaces it with one factor for all thirty.
        value, _ = self.problem._value(x, params)
        return value, self.penalty_factor * f_pen(x)

__init__(problem, noise_model, **kwargs)

Initialize the noisy problem.

Source code in src/bbobax/bbob_noisy.py
def __init__(self, problem: BBOBProblem, noise_model: NoiseModel, **kwargs: Any):
    """Initialize the noisy problem."""
    super().__init__(num_dims=problem.num_dims, noise_model=noise_model, **kwargs)
    self.problem = problem

bbob_noisy_suite(names=None, num_dims=10, **kwargs)

Build the bbob-noisy suite, f101-f130.

Parameters:

Name Type Description Default
names list[str] | None

Which problems to include, as f101 .. f130; defaults to all thirty in order.

None
num_dims int

The dimension every problem is built at.

10
**kwargs Any

Passed to every problem.

{}

Returns:

Type Description
dict[str, Noisy]

A mapping from f101-style name to problem.

Raises:

Type Description
KeyError

If names contains something outside f101-f130.

Source code in src/bbobax/bbob_noisy.py
def bbob_noisy_suite(
    names: list[str] | None = None, num_dims: int = 10, **kwargs: Any
) -> dict[str, Noisy]:
    """Build the bbob-noisy suite, f101-f130.

    Args:
        names: Which problems to include, as `f101` .. `f130`; defaults to all
            thirty in order.
        num_dims: The dimension every problem is built at.
        **kwargs: Passed to every problem.

    Returns:
        A mapping from `f101`-style name to problem.

    Raises:
        KeyError: If `names` contains something outside f101-f130.

    """
    names = list(BBOB_NOISY_PROBLEMS) if names is None else names

    unknown = [name for name in names if name not in BBOB_NOISY_PROBLEMS]
    if unknown:
        raise KeyError(
            f"not bbob-noisy problems: {unknown}; "
            f"available: {sorted(BBOB_NOISY_PROBLEMS)}"
        )

    suite = {}
    for name in names:
        problem_class, severity = BBOB_NOISY_PROBLEMS[name]
        base = problem_class(num_dims=num_dims, **kwargs)
        suite[name] = Noisy(base, _NOISE_MODELS[severity](), **kwargs)
    return suite