Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/surfaces/test_functions/algebraic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,19 @@

# Standard functions (1D, 2D, 4D, ND)
from .standard import (
# 2D
AckleyFunction,
BealeFunction,
BoothFunction,
BukinFunctionN6,
ColvilleFunction,
CrossInTrayFunction,
# 1D
DampedSineFunction,
DropWaveFunction,
EasomFunction,
EggholderFunction,
ForresterFunction,
GoldsteinPriceFunction,
GramacyAndLeeFunction,
# ND
GriewankFunction,
HimmelblausFunction,
HölderTableFunction,
Expand All @@ -60,7 +58,6 @@
RastriginFunction,
RosenbrockFunction,
SchafferFunctionN2,
# 4D
ShekelFunction,
SimionescuFunction,
SineProductFunction,
Expand Down Expand Up @@ -106,6 +103,7 @@
"SimionescuFunction",
"ThreeHumpCamelFunction",
# Standard 4D
"ColvilleFunction",
"ShekelFunction",
# Standard ND
"GriewankFunction",
Expand Down
5 changes: 4 additions & 1 deletion src/surfaces/test_functions/algebraic/standard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
)

# 4D functions
from .test_functions_4d import ShekelFunction
from .test_functions_4d import ColvilleFunction, ShekelFunction

# ND functions
from .test_functions_nd import (
Expand Down Expand Up @@ -79,6 +79,7 @@
"RosenbrockFunction",
"SphereFunction",
"StyblinskiTangFunction",
"ColvilleFunction",
"ShekelFunction",
]

Expand Down Expand Up @@ -109,6 +110,7 @@
SimionescuFunction,
ThreeHumpCamelFunction,
# 4D
ColvilleFunction,
ShekelFunction,
# ND
GriewankFunction,
Expand Down Expand Up @@ -148,6 +150,7 @@
]

standard_functions_4d = [
ColvilleFunction,
ShekelFunction,
]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .colville_function import ColvilleFunction
from .shekel_function import ShekelFunction

__all__ = ["ShekelFunction"]
__all__ = ["ColvilleFunction", "ShekelFunction"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from typing import Any, Callable, Dict, List, Optional, Union

from surfaces._array_utils import ArrayLike
from surfaces.modifiers import BaseModifier

from ..._base_algebraic_function import AlgebraicFunction


class ColvilleFunction(AlgebraicFunction):
"""Colville 4-dimensional test function.

A multimodal, non-convex, continuous function fixed at 4 dimensions.

The function is defined as:

.. math::

f(\\vec{x}) = 100(x_1^2 - x_2)^2 + (x_1 - 1)^2
+ (x_3 - 1)^2 + 90(x_3^2 - x_4)^2
+ 10.1((x_2 - 1)^2 + (x_4 - 1)^2)
+ 19.8(x_2 - 1)(x_4 - 1)

The global minimum is :math:`f(1, 1, 1, 1) = 0`.

Parameters
----------
objective : str, default="minimize"
Either "minimize" or "maximize".
modifiers : list of BaseModifier, optional
List of modifiers to apply to function evaluations.
memory : bool, default=False
Whether to store function evaluations in memory.
collect_data : bool, default=True
Whether to collect data for visualization/history.
callbacks : list of callable, optional
Functions to call after evaluation.
catch_errors : dict, optional
Dictionary mapping error types to return values.

Attributes
----------
n_dim : int
Number of dimensions (fixed at 4).

Examples
--------
>>> from surfaces.test_functions import ColvilleFunction
>>> func = ColvilleFunction()
>>> result = func({"x0": 1.0, "x1": 1.0, "x2": 1.0, "x3": 1.0})
>>> abs(float(result)) < 1e-10
True
"""

_spec = {
"convex": False,
"unimodal": False,
"separable": False,
"scalable": False,
"default_bounds": (-10.0, 10.0),
}

f_global = 0.0

latex_formula = (
r"f(\vec{x}) = 100(x_1^2 - x_2)^2 + (x_1 - 1)^2 + (x_3 - 1)^2 "
r"+ 90(x_3^2 - x_4)^2 + 10.1((x_2 - 1)^2 + (x_4 - 1)^2) "
r"+ 19.8(x_2 - 1)(x_4 - 1)"
)
pgfmath_formula = None

tagline = "A 4-dimensional polynomial function with a narrow curved valley."
display_bounds = (-10.0, 10.0)

display_projection = {"fixed_values": {"x2": 1.0, "x3": 1.0}}

reference = "Colville, A. R. (1968). A comparative study on nonlinear programming codes."
reference_url = "https://www.sfu.ca/~ssurjano/colville.html"

def __init__(
self,
objective: str = "minimize",
modifiers: Optional[List[BaseModifier]] = None,
memory: bool = False,
collect_data: bool = True,
callbacks: Optional[Union[Callable, List[Callable]]] = None,
catch_errors: Optional[Dict[type, float]] = None,
) -> None:
self.n_dim = 4
self.x_global = (1.0, 1.0, 1.0, 1.0)

super().__init__(objective, modifiers, memory, collect_data, callbacks, catch_errors)

def _objective(self, params: Dict[str, Any]) -> float:
x0 = params["x0"]
x1 = params["x1"]
x2 = params["x2"]
x3 = params["x3"]

result = (
100.0 * (x0**2 - x1) ** 2
+ (x0 - 1.0) ** 2
+ (x2 - 1.0) ** 2
+ 90.0 * (x2**2 - x3) ** 2
+ 10.1 * ((x1 - 1.0) ** 2 + (x3 - 1.0) ** 2)
+ 19.8 * (x1 - 1.0) * (x3 - 1.0)
)

return float(result)

def _batch_objective(self, X: ArrayLike) -> ArrayLike:
"""Vectorized batch evaluation for Colville Function."""
x0 = X[:, 0]
x1 = X[:, 1]
x2 = X[:, 2]
x3 = X[:, 3]

result = (
100.0 * (x0**2 - x1) ** 2
+ (x0 - 1.0) ** 2
+ (x2 - 1.0) ** 2
+ 90.0 * (x2**2 - x3) ** 2
+ 10.1 * ((x1 - 1.0) ** 2 + (x3 - 1.0) ** 2)
+ 19.8 * (x1 - 1.0) * (x3 - 1.0)
)

return result

def _search_space(
self,
min: float = -10.0,
max: float = 10.0,
size: int = 10000,
value_types: str = "array",
) -> Dict[str, Any]:
space_1d = super()._create_n_dim_search_space(min, max, size=size, value_types=value_types)[
"x0"
]

return {f"x{i}": space_1d.copy() for i in range(4)}
2 changes: 1 addition & 1 deletion tests/core/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def test_filter_by_category_algebraic(self):
from surfaces import collection

result = collection.filter(category="algebraic")
assert len(result) == 29 # standard algebraic functions only
assert len(result) == 30 # standard algebraic functions only
assert all("algebraic" in f.__module__ for f in result)

def test_filter_by_category_bbob(self):
Expand Down
Loading