"""For the online documentation of shifted form of these base functions, refer to:
https://pypop.readthedocs.io/en/latest/benchmarks.html#shifted-transformed-forms
Here all of below shifted functions are ordered only in *name*. However,
in the above online documentation, all of shifted functions are
classified mainly according to *uni-modality* or *multi-modality*
(dichotomy).
Note that sometimes the *shifted* form is also called the *transformed* form.
"""
import os
import numpy as np
from pypop7.benchmarks import base_functions as bf
from pypop7.benchmarks.base_functions import squeeze_and_check
# helper functions
[docs]def generate_shift_vector(func, ndim, low, high, seed=None):
"""Generate a *random* shift vector of dimension `ndim`, sampled uniformly
between `low` (inclusive) and `high` (exclusive).
.. note:: The generated shift vector will be automatically stored in
the *txt* form **for further use**.
Parameters
----------
func : str or func
function name.
ndim : int
number of dimensions of the shift vector.
low : float or array_like
lower boundary of the shift vector.
high : float or array_like
upper boundary of the shift vector.
seed : int
a scalar seed for random number generator (RNG).
Returns
-------
shift_vector : ndarray (of dtype np.float64)
a shift vector of size `ndim` sampled uniformly in [`low`, `high`).
"""
low, high = squeeze_and_check(low), squeeze_and_check(high)
if hasattr(func, '__name__'):
func = func.__name__
data_folder = 'pypop_benchmarks_input_data'
if not os.path.exists(data_folder):
os.mkdir(data_folder) # only in the working directory
data_name = 'shift_vector_' + func + '_dim_' + str(ndim) + '.txt'
data_path = os.path.join(data_folder, data_name)
shift_vector = np.random.default_rng(seed).uniform(low, high, size=ndim)
np.savetxt(data_path, shift_vector)
return shift_vector
[docs]def load_shift_vector(func, x, shift_vector=None):
"""Load the shift vector which needs to be generated *in advance*.
.. note:: When `None`, the shift vector should have been generated and
stored in the *txt* form **in advance** via `generate_shift_vector()`.
Parameters
----------
func : func
function name.
x : array_like
a decision vector (aka an input vector).
shift_vector : array_like
a shift vector with the same size as `x`.
Returns
-------
shift_vector : ndarray (of dtype np.float64)
a shift vector with the same size as `x`.
"""
x = squeeze_and_check(x)
if shift_vector is None:
if not hasattr(func, 'pypop_shift_vector'):
data_folder = 'pypop_benchmarks_input_data'
data_name = 'shift_vector_' + func.__name__ + '_dim_' + str(x.size)
data_path = os.path.join(data_folder, data_name + '.txt')
shift_vector = np.loadtxt(data_path)
func.pypop_shift_vector = shift_vector
shift_vector = func.pypop_shift_vector
shift_vector = squeeze_and_check(shift_vector)
if shift_vector.shape != x.shape:
raise TypeError('shift_vector should have the same shape as x.')
if len(shift_vector) != len(x):
raise TypeError('shift_vector should have the same size as x.')
return shift_vector
[docs]def cigar(x, shift_vector=None):
"""**Cigar** test function.
Parameters
----------
x : ndarray
an input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
a scalar fitness.
"""
shift_vector = load_shift_vector(cigar, x, shift_vector)
y = bf.cigar(x - shift_vector)
return y
[docs]def cigar_discus(x, shift_vector=None):
"""**Cigar-Discus** test function.
Parameters
----------
x : ndarray
an input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
a scalar fitness.
"""
shift_vector = load_shift_vector(cigar_discus, x, shift_vector)
y = bf.cigar_discus(x - shift_vector)
return y
[docs]def different_powers(x, shift_vector=None):
"""**Different-Powers** test function.
Parameters
----------
x : ndarray
an input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
a scalar fitness.
"""
shift_vector = load_shift_vector(different_powers, x, shift_vector)
y = bf.different_powers(x - shift_vector)
return y
[docs]def discus(x, shift_vector=None):
"""**Discus** (aka **Tablet**) test function.
Parameters
----------
x : ndarray
an input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
a scalar fitness.
"""
shift_vector = load_shift_vector(discus, x, shift_vector)
y = bf.discus(x - shift_vector)
return y
[docs]def ellipsoid(x, shift_vector=None):
"""**Ellipsoid** test function.
Parameters
----------
x : ndarray
an input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
a scalar fitness.
"""
shift_vector = load_shift_vector(ellipsoid, x, shift_vector)
y = bf.ellipsoid(x - shift_vector)
return y
[docs]def sphere(x, shift_vector=None):
"""**Sphere** test function.
Parameters
----------
x : ndarray
an input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
a scalar fitness.
"""
shift_vector = load_shift_vector(sphere, x, shift_vector)
y = bf.sphere(x - shift_vector)
return y
[docs]def schwefel221(x, shift_vector=None):
"""**Schwefel221** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(schwefel221, x, shift_vector)
y = bf.schwefel221(x - shift_vector)
return y
[docs]def step(x, shift_vector=None):
"""**Step** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(step, x, shift_vector)
y = bf.step(x - shift_vector)
return y
[docs]def schwefel222(x, shift_vector=None):
"""**Schwefel222** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(schwefel222, x, shift_vector)
y = bf.schwefel222(x - shift_vector)
return y
[docs]def rosenbrock(x, shift_vector=None):
"""**Rosenbrock** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(rosenbrock, x, shift_vector)
y = bf.rosenbrock(x - shift_vector)
return y
[docs]def schwefel12(x, shift_vector=None):
"""**Schwefel12** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(schwefel12, x, shift_vector)
y = bf.schwefel12(x - shift_vector)
return y
[docs]def exponential(x, shift_vector=None):
"""**Exponential** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(exponential, x, shift_vector)
y = bf.exponential(x - shift_vector)
return y
[docs]def griewank(x, shift_vector=None):
"""**Griewank** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(griewank, x, shift_vector)
y = bf.griewank(x - shift_vector)
return y
[docs]def bohachevsky(x, shift_vector=None):
"""**Bohachevsky** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(bohachevsky, x, shift_vector)
y = bf.bohachevsky(x - shift_vector)
return y
[docs]def ackley(x, shift_vector=None):
"""**Ackley** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(ackley, x, shift_vector)
y = bf.ackley(x - shift_vector)
return y
[docs]def rastrigin(x, shift_vector=None):
"""**Rastrigin** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(rastrigin, x, shift_vector)
y = bf.rastrigin(x - shift_vector)
return y
[docs]def scaled_rastrigin(x, shift_vector=None):
"""**Scaled-Rastrigin** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(scaled_rastrigin, x, shift_vector)
y = bf.scaled_rastrigin(x - shift_vector)
return y
[docs]def skew_rastrigin(x, shift_vector=None):
"""**Skew-Rastrigin** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(skew_rastrigin, x, shift_vector)
y = bf.skew_rastrigin(x - shift_vector)
return y
[docs]def levy_montalvo(x, shift_vector=None):
"""**Levy-Montalvo** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(levy_montalvo, x, shift_vector)
y = bf.levy_montalvo(x - shift_vector)
return y
[docs]def michalewicz(x, shift_vector=None):
"""**Michalewicz** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(michalewicz, x, shift_vector)
y = bf.michalewicz(x - shift_vector)
return y
[docs]def salomon(x, shift_vector=None):
"""**Salomon** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(salomon, x, shift_vector)
y = bf.salomon(x - shift_vector)
return y
[docs]def shubert(x, shift_vector=None):
"""**Shubert** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(shubert, x, shift_vector)
y = bf.shubert(x - shift_vector)
return y
[docs]def schaffer(x, shift_vector=None):
"""**Schaffert** test function.
.. note:: It's LaTeX formulation is `$$`.
If its parameter `shift_vector` is `None`, please use function `generate_shift_vector()` to
generate it (stored in *txt* form) in advance.
Parameters
----------
x : ndarray
input vector.
shift_vector : ndarray
a vector with the same size as `x`.
Returns
-------
y : float
scalar fitness.
"""
shift_vector = load_shift_vector(schaffer, x, shift_vector)
y = bf.schaffer(x - shift_vector)
return y