"""
objectives
==========
This module implements obejective functions to test the performance of consesus
algorithms.
"""
import numpy as np
from scipy.stats import multivariate_normal
from .utils.objective_handling import cbx_objective
#%%
[docs]
class three_hump_camel(cbx_objective):
"""Three-hump camel function
Three-hump camel function is a multimodal function with a global minimum at
:math:`(0,0)`. The function is defined as
.. math::
f(x,y) = 2x^2 - 1.05x^4 + \\frac{1}{6}x^6 + xy + y^2
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import three_hump_camel
>>> x = np.array([[1,2], [3,4], [5,6.]])
>>> obj = three_hump_camel()
>>> obj(x)
array([ 7.11666667, 82.45 , 2063.91666667])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import three_hump_camel
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -2.
y_max = 2.
f = three_hump_camel()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', markersize=5)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
"""
def __init__(self):
super().__init__()
self.minima = np.array([[0,0]])
def apply(self, x):
return 2*x[..., 0]**2 - 1.05 * x[..., 0]**4 + (1/6) * x[..., 0]**6 + x[..., 0]*x[..., 1] + x[..., 1]**2
[docs]
class McCormick(cbx_objective):
r"""McCormick's function
McCormick's function is a multimodal function with two global minima at
:math:`(-0.54719,-1.54719)` and :math:`(1.54719,0.54719)`. The function is defined as
.. math::
f(x,y) = \sin(x+y) + (x-y)^2 - 1.5x + 2.5y + 1
See `McCormick's function <https://en.wikipedia.org/wiki/Test_functions_for_optimization>`_.
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import McCormick
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = McCormick()
>>> f(x)
array([5.64112001, 8.1569866 , 8.50000979])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import McCormick
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 3.
y_min = -3
y_max = 4
f = McCormick()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(-0.54719,-1.54719, color='orange', marker='x', markersize=10)
ax0.plot(1.54719, 0.54719, color='orange', marker='x', markersize=10)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
"""
def apply(self, x):
return np.sin(x[..., 0] + x[...,1]) + (x[...,0] - x[...,1])**2 - 1.5 * x[...,0] + 2.5*x[...,1] + 1
[docs]
class Rosenbrock(cbx_objective):
"""Rosenbrock's function
Rosenbrock's function is a multimodal function with a global minimum at
:math:`(1,1)`. The function is defined as
.. math::
f(x,y) = (a-x)^2 + b(y-x^2)^2
See `Rosenbrock's function <https://en.wikipedia.org/wiki/Rosenbrock_function>`_.
Parameters
----------
a : float, optional
The first parameter of the function. The default is 1.0.
b : float, optional
The second parameter of the function. The default is 100.0.
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Rosenbrock
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Rosenbrock()
>>> f(x)
array([ 0., 76., 76.])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Rosenbrock
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -1.
y_max = 3.
f = Rosenbrock()
num_pts_landscape = 150
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(1,1, color='orange', marker='x', markersize=10)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
"""
def __init__(self, a=1., b=100.):
super().__init__()
self.a = a
self.b = b
def apply(self, x):
return (self.a - x[..., 0])**2 + self.b* (x[..., 1] - x[..., 0]**2)**2
[docs]
class Himmelblau(cbx_objective):
"""Himmelblau's function
Himmelblau's function is a multimodal function with. The function is defined as
.. math::
f(x,y) = (x^2 + y - 11)^2 + (x + y^2 - 7)^2
See `Himmelblau's function <https://en.wikipedia.org/wiki/Himmelblau%27s_function>`_.
Parameters
----------
factor : float, optional
The factor by which the input is multiplied. The default is 1.0.
Global minima
-------------
- :math:`f(x,y) = 0` at :math:`(x,y) = (3,2)`
- :math:`f(x,y) = 0` at :math:`(x,y) = (-2.805118,3.131312)`
- :math:`f(x,y) = 0` at :math:`(x,y) = (-3.779310,-3.283186)`
- :math:`f(x,y) = 0` at :math:`(x,y) = (3.584428,-1.848126)`
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Himmelblau
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Himmelblau()
>>> f(x)
array([ 68., 148., 1556.])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Himmelblau
fig = plt.figure(figsize=(15,5))
x_min = -5.
x_max = 5.
y_min = -5.
y_max = 5.
f = Himmelblau()
num_pts_landscape = 250
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.scatter(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', s=15)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
"""
def __init__(self, factor=1.0):
super().__init__()
self.factor = factor
self.minima = np.array([[3,2], [-2.805118,3.131312], [-3.779310,-3.283186], [3.584428,-1.848126]])
def apply(self, x):
x = self.factor*x
return (x[...,0]**2 + x[...,1] - 11)**2 + (x[...,0] + x[...,1]**2 - 7)**2
[docs]
class Rastrigin(cbx_objective):
r"""Rastrigin's function
Rastrigin's function is a multimodal function with a global minima at
:math:`(0,0)`. The function is originally defined on :math:`\mathbb{R}^2` as
.. math::
f(x,y) = (x^2 + y - 11)^2 + (x + y^2 - 7)^2.
See `Rastrigin's function <https://en.wikipedia.org/wiki/Rastrigin_function>`_.
For our case we employ a shifted version on :math:`\mathbb{R}^d`, where the global minimum is at
:math:`(b)` and we additonally employ a offset :math:`c`,
.. math::
\tilde{f}(x,y) = \frac{1}{n} \sum_{i=1}^n \left[ (x_i - b)^2 - 10 \cos(2 \pi (x_i - b)) + 10 \right] + c.
Parameters
----------
b : float, optional
The first parameter of the function. The default is 0.0.
c : float, optional
The second parameter of the function. The default is 0.0.
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Rastrigin
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Rastrigin()
>>> f(x)
array([ 68., 148., 1556.])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Rastrigin
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -2.
y_max = 2.
f = Rastrigin()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', markersize=5)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
"""
def __init__(self, b=0., c=0.):
super().__init__()
self.b = b
self.c = c
self.minima = np.array([[self.b, self.b]])
def apply(self, x):
return (1/x.shape[-1]) * ((x - self.b)**2 - 10*np.cos(2*np.pi*(x - self.b)) + 10).sum(-1) + self.c
[docs]
class Rastrigin_multimodal(cbx_objective):
r"""Multimodal Rastrigin's function
Let :math:`V` be the Rastrigin's function. Then the multimodal Rastrigin's function is defined as
.. math::
f(x) = \prod_{i=1}^n V(\alpha_i (x - z_i))
Parameters
----------
alpha : list of floats, optional
The factor for each multiplicative term. The default is [1.0].
z : numpy array, optional
The shift vectors in each term. The default is np.array([[0]]).
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Rastrigin_multimodal
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> alpha = [2., 3.]
>>> z = np.array([[2,3], [4,5]])
>>> f = Rastrigin_multimodal(alpha = alpha, z = z)
>>> f(x)
array([324., 36., 324.])
See Also
--------
Rastrigin : The Rastrigin's function
Ackley_multimodal : The multimodal Ackley's function
"""
def __init__(self, alpha = None, z = None):
super().__init__()
self.alpha = alpha if alpha else [1.]
self.z = z if z else np.zeros((len(self.alpha), 1))
self.V = Rastrigin()
self.minima = self.z
self.num_terms = len(self.alpha)
def apply(self, x):
y = np.ones(x.shape[0:-1] )
for i in range(self.num_terms):
y *= self.V(self.alpha[i] * (x - self.z[i,:]))
return y
[docs]
class Ackley(cbx_objective):
r"""Ackley's function
Ackley's function is a multimodal function with a global minima at
:math:`(0,0)`. The function is originally defined on :math:`\mathbb{R}^2` as
.. math::
f(x,y) = -20 \exp \left( -b \sqrt{\frac{1}{2} (x^2 + y^2)} \right) - \exp \left( \frac{1}{2} (\cos(c x) + \cos(c y)) \right) + a + e
See `Ackley's function <https://en.wikipedia.org/wiki/Ackley_function>`_.
Parameters
----------
a : float, optional
The default is 20.0.
b : float, optional
The default is 0.2.
c : float, optional
The default is 2*np.pi.
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Ackley
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Ackley()
>>> f(x)
array([ 68., 148., 1556.])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Ackley
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -2.
y_max = 2.
f = Ackley()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', markersize=5)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
"""
def __init__(self, a=20., b=0.2, c=2*np.pi):
super().__init__()
self.a=a
self.b=b
self.c=c
self.minima = np.array([[0,0]])
def apply(self, x):
d = x.shape[-1]
arg1 = -self.b * np.sqrt(1/d) * np.linalg.norm(x,axis=-1)
arg2 = (1/d) * np.sum(np.cos(self.c * x), axis=-1)
return -self.a * np.exp(arg1) - np.exp(arg2) + self.a + np.e
[docs]
class Ackley_multimodal(cbx_objective):
r"""Multimodal Ackley's function
Let :math:`V` be the Ackley's function. Then the multimodal Ackley's function is defined as
.. math::
f(x) = \prod_{i=1}^n V(\alpha_i (x - z_i))
Parameters
----------
alpha : list of floats, optional
The factor for each multiplicative term. The default is [1.0].
z : numpy array, optional
The shift vectors in each term. The default is np.array([[0]]).
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Ackley_multimodal
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> alpha = [2., 3.]
>>> z = np.array([[2,3], [4,5]])
>>> f = Ackley_multimodal(alpha = alpha, z = z)
>>> f(x)
array([110.07368964, 59.49910362, 126.11721609])
See Also
--------
Ackley
Rasrigin_multimodal
"""
def __init__(self, alpha = None, z = None):
super().__init__()
self.alpha = alpha if alpha else [1.]
self.z = z if z else np.zeros((len(self.alpha), 1))
self.V = Ackley()
self.minima = self.z
self.num_terms = len(self.alpha)
def apply(self, x):
y = np.ones(x.shape[0:-1] )
for i in range(self.num_terms):
y *= self.V(self.alpha[i] * (x - self.z[i,:]))
return y
# def test2d(x):
# return np.cos(x.T[0])+np.sin(x.T[1])
class accelerated_sinus(cbx_objective):
def __init__(self, a=1.0):
super().__init__()
self.a = a
def apply(self, x):
x = np.linalg.norm(x, axis=-1)
return np.sin((self.a * x)/(1+x*x)).squeeze() + 1
class nd_sinus(cbx_objective):
def __init__(self, a=1.0):
super().__init__()
self.a = a
def apply(self, x):
x = 0.3*x
z = 1/x.shape[-1] * np.linalg.norm(x,axis=-1)**2
res = (np.sin(z) + 1) * (x[...,0]**4 - x[...,0]**2 + 1)
return res.squeeze()
class p_4th_order(cbx_objective):
def __init__(self,):
super().__init__()
def apply(self, x):
n = x
res = (np.sum(n**4,axis=-1) - np.sum(n**2,axis=-1) + 1)
return res.squeeze()
class Quadratic(cbx_objective):
def __init__(self, alpha=1.0):
super().__init__()
self.alpha = alpha
def apply(self, x):
return np.linalg.norm(self.alpha*x, axis=-1)**2
class Banana(cbx_objective):
def __init__(self, m=0, sigma=0.5, sigma_prior=2):
super().__init__()
self.m = m
self.sigma = sigma
self.sigma_prior = sigma_prior
def apply(self, x):
G = ((x[...,1]-1)**2-(x[...,0]-2.5) -1)
Phi = 0.5/(self.sigma**2)*(G - self.m)**2
return Phi + 0.5/(self.sigma_prior**2)*np.linalg.norm(x,axis=-1)**2
class Bimodal(cbx_objective):
def __init__(self, a=None, b=None):
super().__init__()
self.a = a if a else [1., 1.5]
self.b = b if b else [-1.2, -0.7]
def apply(self, x):
a = self.a
b = self.b
ret = -np.log(np.exp(-((x[...,0]-a[0])**2 + (x[...,1]-a[1])**2/0.2)) \
+ 0.5*np.exp( -(x[...,0]-b[0])**2/8 - (x[...,1]-b[1])**2/0.5 ))
return ret
class Unimodal(cbx_objective):
def __init__(self, a = None):
super().__init__()
self.a = a if a else [-1.2, -0.7]
def apply(self, x):
a = self.a
ret = -np.log(0.5*np.exp( -(x[...,0]-a[0])**2/8 - (x[...,1]-a[1])**2/0.5 ))
return ret
class Multimodal(cbx_objective):
def __init__(self, means=None, covs=None):
super().__init__()
self.means = [np.zeros((2,))] if means is None else means
self.covs = [np.eye(2)] if covs is None else covs
self.mns = [multivariate_normal(mean=m, cov=c) for m,c in zip(self.means, self.covs)]
def apply(self, x):
res = 0
for mn in self.mns:
res += mn.pdf(x)
return -np.log(res)
[docs]
class Bukin6(cbx_objective):
r"""Bukin's function 6
Bunkin's sixth function is a function with many local minima and one global minimum. It is defined as
.. math::
f(x,y) = 100\sqrt{|y - 0.01x^2|} + 0.01|x + 10|,
see, e.g., [1]_.
Parameters
----------
None
Global minima
-------------
- :math:`f(x,y) = 0` at :math:`(x,y) = (0,0)`
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Bukin6
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Bukin6()
>>> f(x)
array([ 68., 148., 1556.])
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Bukin6
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -2.
y_max = 2.
f = Bukin6()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', markersize=5)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/bukin6.html
"""
def __init__(self,):
super().__init__()
self.minima = np.array([[0, 0]])
def apply(self, x):
return 100 * np.sqrt(np.abs(x[...,1] - 0.01 * x[...,0]**2)) + 0.01 * np.abs(x[...,0] + 10)
[docs]
class cross_in_tray(cbx_objective):
r"""Cross-In-Tray function
The Cross-In-Tray function is a function with many local minima and one global minimum [1]_. It is defined as
.. math::
f(x,y) = -0.0001 \left( \left| \sin(x) \sin(y) \exp \left( \left| 100 - \frac{\sqrt{x^2 + y^2}}{\pi} \right| \right) + 1 \right| + 1 \right)^0.1,
see [1]_.
Parameters
----------
None
Global minima
-------------
- :math:`f(x,y) = -2.06261` at :math:`(x,y) = (1.34941, 1.34941)`
- :math:`f(x,y) = -2.06261` at :math:`(x,y) = (-1.34941, -1.34941)`
- :math:`f(x,y) = -2.06261` at :math:`(x,y) = (1.34941, -1.34941)`
- :math:`f(x,y) = -2.06261` at :math:`(x,y) = (-1.34941, 1.34941)`
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import cross_in_tray
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = cross_in_tray()
>>> f(x)
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import cross_in_tray
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -2.
y_max = 2.
f = cross_in_tray()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.scatter(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', s=20)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/crossit.html
"""
def __init__(self):
super().__init__()
self.minima = np.array([[1.34941, 1.34941], [-1.34941, 1.34941], [1.34941, -1.34941], [-1.34941, -1.34941]])
def apply(self, x):
return -0.0001 * (np.abs(np.sin(x[...,0]) * np.sin(x[...,1]) * np.exp(np.abs(100 - np.sqrt(x[...,0]**2 + x[...,1]**2)/np.pi))) + 1)**0.1
[docs]
class Easom(cbx_objective):
r"""Easom
The Easom function is a function with many local minima and one global minimum [1]_ . It is defined as
.. math::
f(x,y) = -\cos(x) \cos(y) \exp \left( -\left( x - \pi \right)^2 - \left( y - \pi \right)^2 \right).
Parameters
----------
None
Global minima
-------------
- :math:`f(x,y) = -1` at :math:`(x,y) = (\pi, \pi)`
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Easom
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Easom()
>>> f(x)
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Easom
fig = plt.figure(figsize=(15,5))
x_min = 0
x_max = 2. * np.pi
y_min = 0.
y_max = 2. * np.pi
f = Easom()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', markersize=5)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/easom.html
"""
def __init__(self):
super().__init__()
self.minima = np.array([[np.pi, np.pi]])
def apply(self, x):
return -np.cos(x[...,0]) * np.cos(x[...,1]) * np.exp(-((x[...,0] - np.pi)**2 + (x[...,1] - np.pi)**2))
[docs]
class drop_wave(cbx_objective):
r"""Drop Wave
The Drop Wave function is a function with many local minima and one global minimum [1]_. It is defined as
.. math::
f(x,y) = -\left( 1 + \cos(12 \sqrt{x^2 + y^2}) \right) \exp \left( -\frac{x^2 + y^2}{2(1 + 0.001(x^2 + y^2))} \right),
see [1]_.
Parameters
----------
None
Global minima
-------------
- :math:`f(x,y) = -1` at :math:`(x,y) = (0, 0)`
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import drop_wave
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = drop_wave()
>>> f(x)
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import drop_wave
fig = plt.figure(figsize=(15,5))
x_min = -2.
x_max = 2.
y_min = -2.
y_max = 2.
f = drop_wave()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.plot(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', markersize=5)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/drop.html
"""
def __init__(self):
super().__init__()
self.minima = np.array([[0, 0]])
def apply(self, x):
return -(1 + np.cos(12 * np.sqrt(x[...,0]**2 + x[...,1]**2))) * np.exp(-0.5 * (x[...,0]**2 + x[...,1]**2) / (1 + 0.001 * (x[...,0]**2 + x[...,1]**2)))
[docs]
class Holder_table(cbx_objective):
r"""Holder table
The Holder table function is a function with many local minima and four global minima [1]_. It is defined as
.. math::
f(x,y) = -\left| \sin(x) \cos(y) \exp \left( \left| 1 - \frac{\sqrt{x^2 + y^2}}{\pi} \right| \right) \right|,
and its domain is :math:`[-10,10]^2`. Note, that this function can decrease further if the domain is enlarged.
Parameters
----------
None
Global minima
-------------
- :math:`f(x,y) = -19.2085` at :math:`(x,y) = (8.05502, 9.66459)`
- :math:`f(x,y) = -19.2085` at :math:`(x,y) = (-8.05502, 9.66459)`
- :math:`f(x,y) = -19.2085` at :math:`(x,y) = (8.05502, -9.66459)`
- :math:`f(x,y) = -19.2085` at :math:`(x,y) = (-8.05502, -9.66459)`
Examples
--------
>>> import numpy as np
>>> from cbx.objectives import Holder_table
>>> x = np.array([[1,2], [3,4], [5,6]])
>>> f = Holder_table()
>>> f(x)
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Holder_table
fig = plt.figure(figsize=(15,5))
x_min = -10.
x_max = 10.
y_min = -10.
y_max = 10.
f = Holder_table()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.scatter(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', s=20)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/holdertable.html
"""
def __init__(self):
super().__init__()
self.minima = np.array([[8.05502, 9.66459], [-8.05502, 9.66459], [8.05502, -9.66459], [-8.05502, -9.66459]])
def apply(self, x):
return -np.abs(np.sin(x[...,0]) * np.cos(x[...,1]) * np.exp(np.abs(1 - np.sqrt(x[...,0]**2 + x[...,1]**2) / np.pi)))
[docs]
class snowflake(cbx_objective):
r"""Snowflake
The snowflake function is a function with many local minima and six global minima [1]_. Using polar coordinates, it is as
.. math::
f(r, \phi) = \min\{f_0(r,\phi), f_1(r,\phi), f_2(r,\phi), 0.8\},
where for :math:`i\in\{0,1,2\}` we define
.. math::
f_i(r,\phi) = r^8 - r^4 + \sqrt{\left|\cos\left(\phi + i\cdot \frac{\pi}{3}\right)\right|} \cdot r^{0.3}.
This function was introduced to showcase the performance of the PolarCBO algorithm [2]_.
Parameters
----------
alpha : float
Scales the input. Default is .5
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import snowflake
fig = plt.figure(figsize=(15,5))
x_min = -2.5
x_max = 2.5
y_min = -2.5
y_max = 2.5
f = snowflake()
num_pts_landscape = 100
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ, 20, cmap=cm.get_cmap('Blues'))
ax0.contour(cs, colors='white', alpha=0.2)
ax0.scatter(f.minima[:, 0], f.minima[:, 1], color='blue', marker='x', s=20)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.get_cmap('Blues'))
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://github.com/TimRoith/polarcbo
.. [2] Bungert, L., Roith, T., Wacker, P. (2022): Polarized consensus-based dynamics for optimization and sampling. arXiv:2211.05238
"""
def __init__(self, alpha=.5):
super().__init__()
self.alpha = alpha
self.minima_polar = np.array([[ 1/self.alpha * 0.5**(1/4), np.pi/2],
[-1/self.alpha * 0.5**(1/4), np.pi/2],
[ 1/self.alpha * 0.5**(1/4), np.pi/2 - np.pi/3],
[-1/self.alpha * 0.5**(1/4), np.pi/2 - np.pi/3],
[ 1/self.alpha * 0.5**(1/4), np.pi/2 - 2*np.pi/3],
[-1/self.alpha * 0.5**(1/4), np.pi/2 - 2*np.pi/3]])
self.minima = np.zeros((self.minima_polar.shape))
self.minima[:, 0] = self.minima_polar[:, 0] * np.cos(self.minima_polar[:, 1])
self.minima[:, 1] = self.minima_polar[:, 0] * np.sin(self.minima_polar[:, 1])
def apply(self, x):
x = self.alpha * x
r = np.linalg.norm(x,axis=-1)
phi = np.arctan2(x[...,1], x[...,0])
res = np.ones((x.shape[:-1]))
for psi in [0, np.pi/3, np.pi*2/3]:
g = r**8 - r**4 + np.abs(np.cos(phi+psi))**0.5*r**0.3
res = np.minimum(res, g)
res = np.minimum(res, .8)
return res
[docs]
class eggholder(cbx_objective):
r"""Eggholder
The Eggholder function is a function with many local minima and one global minimum [1]_. It is defined as
.. math::
f(x,y) = -(y+47)\cdot \sin\left(\sqrt{\left|y+x/2+47\right|}\right) - x\cdot \sin\left(\sqrt{\left|x-y-47\right|}\right).
Parameters
----------
None
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import eggholder
fig = plt.figure(figsize=(15,5))
x_min = -600
x_max = 600
y_min = x_min
y_max = x_max
f = eggholder()
num_pts_landscape = 200
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ,30, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.scatter(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', s=30)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/egg.html
"""
def __init__(self):
super().__init__()
self.minima = np.array([[512, 404.2319]])
def apply(self, x):
return -(x[...,1] + 47) * np.sin(np.sqrt(np.abs(x[...,1] + x[...,0]/2 + 47))) - x[...,0] * np.sin(np.sqrt(np.abs(x[...,0] - (x[...,1] + 47))))
[docs]
class Michalewicz(cbx_objective):
r"""Michalewicz
Michalewicz function is a function with many local minima and one global minimum [1]_. It is defined as
.. math::
f(x,y) = -\sum_{i=1}^d \sin(x_i)\cdot \left(\sin\left(\frac{i x_i^2}{\pi}\right)\right)^{2m},
where :math:`d` denotes the dimension and the parameter :math:`m` is ususally chosen as :math:`m=10`.
Parameters
----------
None
Visualization
-------------
.. plot::
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
from cbx.objectives import Michalewicz
fig = plt.figure(figsize=(15,5))
x_min = 0.
x_max = 4.
y_min = x_min
y_max = x_max
f = Michalewicz()
num_pts_landscape = 200
xx = np.linspace(x_min, x_max, num_pts_landscape)
yy = np.linspace(y_min, y_max, num_pts_landscape)
XX, YY = np.meshgrid(xx,yy)
XXYY = np.stack((XX.T,YY.T)).T
Z = np.zeros((num_pts_landscape,num_pts_landscape, 2))
Z[:,:,0:2] = XXYY
ZZ = f(Z)
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122, projection='3d')
cs = ax0.contourf(XX,YY,ZZ,30, cmap=cm.jet)
ax0.contour(cs, colors='orange', alpha=0.2)
ax0.scatter(f.minima[:, 0], f.minima[:, 1], color='orange', marker='x', s=30)
ax1.plot_surface(XX,YY,ZZ, cmap=cm.jet)
ax0.set_title('Contour plot')
ax1.set_title('Surface plot')
References
----------
.. [1] https://www.sfu.ca/~ssurjano/michal.html
"""
def __init__(self, d=2, m=10):
super().__init__()
self.d = d
self.m = m
if d == 2:
self.minima = np.array([[2.2029, 1.5708]])
else:
self.minima = None
def apply(self, x):
arr_shape = np.ones(x.ndim, dtype=int)
arr_shape[-1] = x.shape[-1]
arr = np.arange(x.shape[-1]).reshape(arr_shape) + 1
return -np.sum(np.sin(x) * np.sin(arr * (x**2)/np.pi)**(2*self.m), axis=-1)