stacked_tensorial_nn / stnn /data /test_functions.py
caleb2's picture
initial commit
d68c650
import numpy as np
"""
Interface to a subset of the test functions listed at
https://en.wikipedia.org/wiki/Test_functions_for_optimization
"""
def rastrigin(x, y):
args = (x, y)
A = 10
return A * len(x) + sum([(xi**2 - A * np.cos(2 * np.pi * xi)) for xi in args])
def ackley(x, y):
return -20 * np.exp(-0.2 * np.sqrt(0.5 * (x**2 + y**2))) - \
np.exp(0.5 * (np.cos(2 * np.pi * x) + np.cos(2 * np.pi * y))) + np.e + 20
def sphere(x, y):
return x**2 + y**2
def rosenbrock(x, y):
return 100 * (y - x**2)**2 + (1 - x)**2
def beale(x, y):
return (1.5 - x + x * y)**2 + (2.25 - x + x * y**2)**2 + (2.625 - x + x * y**3)**2
def goldstein_price(x, y):
return (1 + (x + y + 1)**2 * (19 - 14 * x + 3 * x**2 - 14 * y + 6 * x * y + 3 * y**2)) * \
(30 + (2 * x - 3 * y)**2 * (18 - 32 * x + 12 * x**2 + 48 * y - 36 * x * y + 27 * y**2))
def booth(x, y):
return (x + 2 * y - 7)**2 + (2 * x + y - 5)**2
def bukin(x, y):
return 100 * np.sqrt(abs(y - 0.01 * x**2)) + 0.01 * abs(x + 10)
def matyas(x, y):
return 0.26 * (x**2 + y**2) - 0.48 * x * y
def levi(x, y):
return np.sin(3 * np.pi * x)**2 + (x - 1)**2 * (1 + np.sin(3 * np.pi * y)**2) + \
(y - 1)**2 * (1 + np.sin(2 * np.pi * y)**2)
def himmelblau(x, y):
return (x**2 + y - 11)**2 + (x + y**2 - 7)**2
def three_hump_camel(x, y):
return 2 * x**2 - 1.05 * x**4 + x**6 / 6 + x * y + y**2
def easom(x, y):
return -np.cos(x) * np.cos(y) * np.exp(-((x - np.pi)**2 + (y - np.pi)**2))
def cross_in_tray(x, y):
return -0.0001 * (abs(np.sin(x) * np.sin(y) * np.exp(abs(100 - np.sqrt(x**2 + y**2) / np.pi))) + 1)**0.1
def eggholder(x, y):
return -(y + 47) * np.sin(np.sqrt(abs(x / 2 + (y + 47)))) - x * np.sin(np.sqrt(abs(x - (y + 47))))
def holder_table(x, y):
return -abs(np.sin(x) * np.cos(y) * np.exp(abs(1 - np.sqrt(x**2 + y**2) / np.pi)))
def mccormick(x, y):
return np.sin(x + y) + (x - y)**2 - 1.5 * x + 2.5 * y + 1
def schaffer2(x, y):
return 0.5 + (np.sin(x**2 - y**2)**2 - 0.5) / (1 + 0.001 * (x**2 + y**2))**2
def schaffer4(x, y):
return 0.5 + (np.cos(np.sin(abs(x**2 - y**2)))**2 - 0.5) / (1 + 0.001 * (x**2 + y**2))**2
def styblinski_tang(x, y):
args = (x, y)
return sum([xi**4 - 16 * xi**2 + 5 * xi for xi in args]) / 2
functions = [
rastrigin,
ackley,
sphere,
rosenbrock,
beale,
goldstein_price,
booth,
bukin,
matyas,
levi,
himmelblau,
three_hump_camel,
easom,
cross_in_tray,
eggholder,
holder_table,
mccormick,
schaffer2,
schaffer4,
styblinski_tang
]
function_names = [
'rastrigin',
'ackley',
'sphere',
'rosenbrock',
'beale',
'goldstein_price',
'booth',
'bukin',
'matyas',
'levi',
'himmelblau',
'three_hump_camel',
'easom',
'cross_in_tray',
'eggholder',
'holder_table',
'mccormick',
'schaffer2',
'schaffer4',
'styblinski_tang'
]
domains = {
'rastrigin': (-5.12, 5.12),
'ackley': (-5, 5),
'sphere': (-1, 1),
'rosenbrock': {'x': (-2, 2), 'y': (-10, 10)},
'beale': (-4.5, 4.5),
'goldstein_price': (-2, 2),
'booth': (-10, 10),
'bukin': {'x': (-15, -5), 'y': (-3, 3)},
'matyas': (-10, 10),
'levi': (-10, 10),
'himmelblau': (-5, 5),
'three_hump_camel': (-5, 5),
'easom': (-100, 100),
'cross_in_tray': (-10, 10),
'eggholder': (-512, 512),
'holder_table': (-10, 10),
'mccormick': {'x': (-1.5, 4), 'y': (-3, 4)},
'schaffer2': (-100, 100),
'schaffer4': (-100, 100),
'styblinski_tang': (-5, 5)
}
def scale_input(x, domain):
min_d, max_d = domain
return min_d + (max_d - min_d) * x
def get_test_function(X, Y, fun_idx):
"""
Evaluates a function on inputs (X, Y).
Args:
X (float or array-like): The X input values to be scaled and used in the function.
Y (float or array-like): The Y input values to be scaled and used in the function.
Ignored if the function takes only one argument.
fun_idx (int): The index of the function to be retrieved from a predefined list 'functions'.
Returns:
(float or array-like), values of the function on the grid
"""
func = functions[fun_idx]
domain = domains[func.__name__]
if isinstance(domain, dict):
x_scaled = scale_input(X, domain['x'])
y_scaled = scale_input(Y, domain['y'])
else:
x_scaled = scale_input(X, domain)
y_scaled = scale_input(Y, domain)
try:
output = func(X, Y)
except TypeError:
output = func(X)
return output