Add necessary utils
This commit is contained in:
parent
1bbd75a87b
commit
bcf22269e8
3 changed files with 162 additions and 0 deletions
42
src/function.py
Normal file
42
src/function.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import NamedTuple
|
||||
|
||||
import numpy as np
|
||||
|
||||
from src.types import INPUT_VECTOR
|
||||
|
||||
|
||||
class Interval(NamedTuple):
|
||||
"""Interval determining a number range (both inclusive)."""
|
||||
|
||||
min: float
|
||||
max: float
|
||||
|
||||
def random_point(self, dimensions: int, rng: np.random.Generator | None = None) -> INPUT_VECTOR:
|
||||
"""Generate an N-dimensional random point, where all numbers lie within this interval.
|
||||
|
||||
Args:
|
||||
dimensions: The amount of dimensions this point should have.
|
||||
rng: Random generator instance (None for a new rng).
|
||||
"""
|
||||
if rng is None:
|
||||
rng = np.random.default_rng()
|
||||
|
||||
return rng.uniform(self.min, self.max, size=dimensions)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Function:
|
||||
"""Class representing an N-dimensional function.
|
||||
|
||||
This function can work with arbitrary number of dimensions, where each input dimension is restricted
|
||||
within the specified definition interval.
|
||||
"""
|
||||
|
||||
function: Callable[[INPUT_VECTOR], float]
|
||||
definition_interval: Interval
|
||||
|
||||
def __call__(self, params: INPUT_VECTOR) -> float:
|
||||
"""Evaluate the function."""
|
||||
return self.function(params)
|
116
src/functions.py
Normal file
116
src/functions.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
"""Various N-dimensional well-known optimization functions.
|
||||
|
||||
All of the functions here work with N (# of dimensions) ranging from 1 to infinity.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
|
||||
from src.function import Function, Interval
|
||||
from src.types import INPUT_VECTOR
|
||||
|
||||
|
||||
def _sphere_function(vector: INPUT_VECTOR) -> float:
|
||||
"""Compute the sphere function.
|
||||
|
||||
Arguments:
|
||||
vector: An n-dimensional input vector.
|
||||
|
||||
Returns:
|
||||
float: The function value at the given input vector.
|
||||
|
||||
See: https://www.sfu.ca/~ssurjano/spheref.html
|
||||
"""
|
||||
return np.sum(vector**2)
|
||||
|
||||
|
||||
sphere_function = Function(_sphere_function, Interval(-10, 10))
|
||||
|
||||
|
||||
def _zakharov_function(vector: INPUT_VECTOR) -> float:
|
||||
"""Compute the Zakharov function.
|
||||
|
||||
Arguments:
|
||||
vector: An n-dimensional input vector.
|
||||
|
||||
Returns:
|
||||
float: The function value at the given input vector.
|
||||
|
||||
See: https://www.sfu.ca/~ssurjano/zakharov.html
|
||||
"""
|
||||
d = vector.shape[0]
|
||||
|
||||
# First term: sum(x_i^2)
|
||||
term_1 = np.sum(vector**2)
|
||||
|
||||
# Second term: (sum(0.5 * i * x_i))^2
|
||||
term_2 = np.sum(0.5 * np.arange(1, d + 1) * vector) ** 2
|
||||
|
||||
# Third term: (sum(0.5 * i * x_i))^4
|
||||
term_3 = np.sum(0.5 * np.arange(1, d + 1) * vector) ** 4
|
||||
|
||||
return term_1 + term_2 + term_3
|
||||
|
||||
|
||||
zakharov_function = Function(_zakharov_function, Interval(-10, 10))
|
||||
|
||||
|
||||
def _rosenbrock_function(vector: INPUT_VECTOR) -> float:
|
||||
"""Compute the Rosenbrock function.
|
||||
|
||||
Arguments:
|
||||
vector: An n-dimensional input vector.
|
||||
|
||||
Returns:
|
||||
float: The function value at the given input vector.
|
||||
|
||||
See: https://www.sfu.ca/~ssurjano/rosenbrockf.html
|
||||
"""
|
||||
return np.sum(100 * (vector[:-1] ** 2 - vector[1:]) ** 2 + (1 - vector[:-1]) ** 2)
|
||||
|
||||
|
||||
rosenbrock_function = Function(_rosenbrock_function, Interval(-10, 10))
|
||||
|
||||
|
||||
def _schwefel_function(vector: INPUT_VECTOR) -> float:
|
||||
"""Compute the Schwefel function.
|
||||
|
||||
Arguments:
|
||||
vector: An n-dimensional input vector.
|
||||
|
||||
Returns:
|
||||
float: The function value at the given input vector.
|
||||
|
||||
See: https://www.sfu.ca/~ssurjano/schwefel.html
|
||||
"""
|
||||
d = vector.shape[0]
|
||||
|
||||
return 418.9829 * d - np.sum(vector * np.sin(np.sqrt(np.abs(vector))))
|
||||
|
||||
|
||||
schwefel_function = Function(_schwefel_function, Interval(-500, 500))
|
||||
|
||||
|
||||
def _styblinski_tang_function(vector: INPUT_VECTOR) -> float:
|
||||
"""Compute the Styblinski-Tang function.
|
||||
|
||||
Arguments:
|
||||
vector: An n-dimensional input vector.
|
||||
|
||||
Returns:
|
||||
float: The function value at the given input vector.
|
||||
|
||||
See: https://www.sfu.ca/~ssurjano/stybtang.html
|
||||
"""
|
||||
return 0.5 * np.sum(vector**4 - 16 * vector**2 + 5 * vector)
|
||||
|
||||
|
||||
styblinski_tang_function = Function(_styblinski_tang_function, Interval(-5, 5))
|
||||
|
||||
|
||||
available_functions = {
|
||||
"Sphere": sphere_function,
|
||||
"Zakharov": zakharov_function,
|
||||
"Rosenbrock": rosenbrock_function,
|
||||
"Schwefel": schwefel_function,
|
||||
"Styblinski-Tang": styblinski_tang_function,
|
||||
}
|
4
src/types.py
Normal file
4
src/types.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
import numpy as np
|
||||
import numpy.typing as npt
|
||||
|
||||
type INPUT_VECTOR = npt.NDArray[np.float64]
|
Loading…
Add table
Reference in a new issue