[1]:
import numpy as np
import time
from scipy.optimize import differential_evolution, minimize, dual_annealing
import matplotlib.pyplot as plt
import concurrent.futures
import threading, multiprocessing

import sys
sys.path.append("../")
import minionpy as mpy
import minionpy.test_functions as mpytest
import time
[2]:
mpy
[2]:
<module 'minionpy' from '/home/muzakka/Developments/minion/examples/../minionpy/__init__.py'>

Minimizing Basic Functions

In this section, we minimize basic functions such as Sphere, Rosenbrock, and Rastrigin. The search space is shifted to prevent algorithms from converging near the origin, as some algorithms tend to favor that region.

[3]:
def sphere(x) :
    x =np.asarray(x)-1
    return 100+np.sum(x**2)

def rosenbrock(x):
    #if x[0]<-1 or x[0]>1 : print(x, "bound violated")
    x = np.asarray(x)-5.0
    return 100+np.sum(100 * (x[1:] - x[:-1]**2)**2 + (1 - x[:-1])**2)

def rastrigin(x):
    x = np.asarray(x)-1.0
    A = 10
    return 100+A * len(x) + np.sum(x**2 - A * np.cos(2 * np.pi * x))

#remember that in minion, objective function must be vectorized. Suppose you want to
func = rosenbrock
def objective_function(X) :
    """
    Here, X is a list of x, where x is an input vector.
    """
    return [func(x) for x in X]

#Now minimize the function using minion
dimension = 5 #set dimension of the problem
maxevals = 1000 #number of function calls
x0 = [[0.0]*dimension] # initial guesses

min = mpy.Minimizer(func=objective_function, x0=x0, bounds=[(-1, 1)]*dimension, algo="ARRDE",
                    maxevals=10000, callback=None, seed=None, options={"minimum_population_size":4})
result = min.optimize()
print("The minimum of the function is ", "\n\t x : ", result.x, "\n\t f(x) : ", result.fun)
The minimum of the function is
         x :  [1.0, 0.9999999999999998, 0.9999999999999997, 0.9999999999999998, 0.9999999999999836]
         f(x) :  160200.00000000006

Using Basic Test Functions

Minionpy provides a variety of test functions for evaluating optimization algorithms. The dictionary testFunctionDict below contains some of the fundamental functions available. Many of these functions have a global minimum at the origin, which can be problematic since some algorithms naturally converge toward it. To address this issue, CEC benchmark functions apply rotation and shifting to these basic functions, making them more representative of real-world optimization scenarios.

The test functions in minionpy.test_functions are vectorized by default. They accept input as a 2D NumPy array.

[4]:
testFunctionDict = {
    "sphere" : mpytest.sphere,
    "rosenbrock" : mpytest.rosenbrock,
    "rastrigin" : mpytest.rastrigin,
    "schaffer2" : mpytest.schaffer2,
    "griewank" : mpytest.griewank,
    "ackley" : mpytest.ackley,
    "zakharov" : mpytest.zakharov,
    "bent_cigar" : mpytest.bent_cigar,
    "levy" : mpytest.levy,
    "discus" : mpytest.discus,
    "drop_wave" : mpytest.drop_wave,
    "goldstein_price" : mpytest.goldstein_price,
    "exponential" : mpytest.exponential,
    "quartic" : mpytest.quartic,
    "hybrid_composition1" : mpytest.hybrid_composition1,
    "hybrid_composition2" : mpytest.hybrid_composition2,
    "hybrid_composition3" : mpytest.hybrid_composition3,
    "happy_cat"  : mpytest.happy_cat,
    "michalewics" : mpytest.michalewicz,
    "scaffer6" : mpytest.scaffer6,
    "hcf" : mpytest.hcf,
    "grie_rosen" : mpytest.grie_rosen,
    "dixon_price" : mpytest.dixon_price,
    "eosom" : mpytest.easom,
    "hgbat" : mpytest.hgbat,
    "styblinski_tang" : mpytest.styblinski_tang,
    "step" : mpytest.step,
    "weierstrass" : mpytest.weierstrass,
    "sum_squares" : mpytest.sum_squares
}

The performance of different algorithms to minimize these functions can be compared as shown below.

[5]:
dimension = 10
maxevals = 10000
np.random.seed(1)
shift = 10 * np.random.rand(dimension)  # Shift randomly
bounds = [(-10, 10)] * dimension
x0 = [10 * np.random.rand(dimension)] # Initial guesses
np.random.seed(None)

for func_name in testFunctionDict:
    #if func_name not in ["schaffer2", "ackley", "rastrigin", "rosenbrock"]:
    #    continue  # Minimize only these functions; comment this line to compare all test functions

    print(f"Function: {func_name}")

    N = 0

    def objective_function(X):
        """Shifted objective function for minimization."""
        global N
        X = np.array(X) - shift  # Shift the space
        N += len(X)
        return testFunctionDict[func_name](X)

    def objective_function_scipy(X):
        """Objective function for SciPy optimizers."""
        global N
        N += 1
        return testFunctionDict[func_name]([X])[0]

    algoList = [
        "DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
        "ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES", "RCMAES"
    ]


    for algo in algoList:
        t_start = time.time()
        N = 0
        result = mpy.Minimizer(
            func=objective_function, x0=x0, bounds=bounds, algo=algo,
            maxevals=maxevals, callback=None, seed=None,
            options={"population_size": 0, "convergence_tol":0.0}
        ).optimize()
        elapsed_time = time.time() - t_start
        print(f"\tAlgorithm: {algo:<18} f(x): {result.fun:<15.8g} Elapsed: {elapsed_time:.3f} s")

    # Compare to SciPy algorithms
    algorithms_scipy = [
        ("Scipy Nelder-Mead", minimize, {"x0": x0[0], "method": "Nelder-Mead",
                                         "bounds": bounds, "options": {"maxfev": maxevals, "adaptive": True}}),
        ("Scipy L-BFGS-B", minimize, {"x0": x0[0], "method": "L-BFGS-B",
                                      "options": {"maxfun": maxevals}, "bounds": bounds}),
        ("Scipy DA", dual_annealing, {"bounds": bounds, "maxfun": maxevals, "x0": x0[0], "no_local_search": False})
    ]

    for name, func, kwargs in algorithms_scipy:
        t_start = time.time()
        N = 0
        result = func(objective_function_scipy, **kwargs)
        elapsed_time = time.time() - t_start
        print(f"\tAlgorithm: {name:<18} f(x): {result.fun:<15.8g} Elapsed: {elapsed_time:.3f} s")

    print("")

Function: sphere
        Algorithm: DE                 f(x): 6.8796947e-06   Elapsed: 0.020 s
        Algorithm: ABC                f(x): 4.9772917e-06   Elapsed: 0.014 s
        Algorithm: LSHADE             f(x): 1.4353805e-09   Elapsed: 0.019 s
        Algorithm: LSHADE_cnEpSin     f(x): 5.4674191e-14   Elapsed: 0.034 s
        Algorithm: JADE               f(x): 7.8886091e-31   Elapsed: 0.027 s
        Algorithm: jSO                f(x): 1.3277479e-10   Elapsed: 0.022 s
        Algorithm: j2020              f(x): 1.542933e-12    Elapsed: 0.114 s
        Algorithm: LSRTDE             f(x): 2.2833503e-11   Elapsed: 0.018 s
        Algorithm: NLSHADE_RSP        f(x): 2.2553804e-08   Elapsed: 0.018 s
        Algorithm: ARRDE              f(x): 4.288481e-27    Elapsed: 0.028 s
        Algorithm: GWO_DE             f(x): 2.9030876e-06   Elapsed: 0.022 s
        Algorithm: NelderMead         f(x): 4.6709368e-30   Elapsed: 0.041 s
        Algorithm: DA                 f(x): 1.2691251e-12   Elapsed: 0.003 s
        Algorithm: L_BFGS_B           f(x): 1.0668492e-13   Elapsed: 0.000 s
        Algorithm: PSO                f(x): 1.1904985e-14   Elapsed: 0.015 s
        Algorithm: DMSPSO             f(x): 4.3319447e-16   Elapsed: 0.019 s
        Algorithm: SPSO2011           f(x): 2.9549519e-08   Elapsed: 0.022 s
        Algorithm: CMAES              f(x): 7.7764599e-30   Elapsed: 0.024 s
        Algorithm: BIPOP_aCMAES       f(x): 1.2150014e-27   Elapsed: 0.039 s
        Algorithm: RCMAES             f(x): 1.8351504e-13   Elapsed: 0.028 s
        Algorithm: Scipy Nelder-Mead  f(x): 5.8359322e-09   Elapsed: 0.038 s
        Algorithm: Scipy L-BFGS-B     f(x): 6.9420299e-12   Elapsed: 0.002 s
        Algorithm: Scipy DA           f(x): 2.153777e-16    Elapsed: 0.342 s

Function: rosenbrock
        Algorithm: DE                 f(x): 55.388125       Elapsed: 0.017 s
        Algorithm: ABC                f(x): 1.4722782       Elapsed: 0.017 s
        Algorithm: LSHADE             f(x): 4.6352793       Elapsed: 0.021 s
        Algorithm: LSHADE_cnEpSin     f(x): 2.8390061       Elapsed: 0.031 s
        Algorithm: JADE               f(x): 3.7829995       Elapsed: 0.033 s
        Algorithm: jSO                f(x): 2.175247        Elapsed: 0.021 s
        Algorithm: j2020              f(x): 4.9777057       Elapsed: 0.175 s
        Algorithm: LSRTDE             f(x): 3.5782003       Elapsed: 0.019 s
        Algorithm: NLSHADE_RSP        f(x): 7.4663937       Elapsed: 0.022 s
        Algorithm: ARRDE              f(x): 0.65001897      Elapsed: 0.032 s
        Algorithm: GWO_DE             f(x): 7.345552        Elapsed: 0.022 s
        Algorithm: NelderMead         f(x): 3.1653044e-27   Elapsed: 0.084 s
        Algorithm: DA                 f(x): 1.4773537e-13   Elapsed: 0.023 s
        Algorithm: L_BFGS_B           f(x): 4.307979e-13    Elapsed: 0.005 s
        Algorithm: PSO                f(x): 2.9404998       Elapsed: 0.020 s
        Algorithm: DMSPSO             f(x): 1.3684967       Elapsed: 0.027 s
        Algorithm: SPSO2011           f(x): 7.4379368       Elapsed: 0.021 s
        Algorithm: CMAES              f(x): 0.020598558     Elapsed: 0.027 s
        Algorithm: BIPOP_aCMAES       f(x): 1.299369e-20    Elapsed: 0.052 s
        Algorithm: RCMAES             f(x): 5.234485e-13    Elapsed: 0.029 s
        Algorithm: Scipy Nelder-Mead  f(x): 8.9958364e-09   Elapsed: 0.077 s
        Algorithm: Scipy L-BFGS-B     f(x): 1.1087483e-10   Elapsed: 0.070 s
        Algorithm: Scipy DA           f(x): 2.2407375e-10   Elapsed: 0.478 s

Function: rastrigin
        Algorithm: DE                 f(x): 16.914289       Elapsed: 0.018 s
        Algorithm: ABC                f(x): 0.99590106      Elapsed: 0.017 s
        Algorithm: LSHADE             f(x): 0.41492165      Elapsed: 0.023 s
        Algorithm: LSHADE_cnEpSin     f(x): 4.6453245       Elapsed: 0.032 s
        Algorithm: JADE               f(x): 1.7763568e-15   Elapsed: 0.029 s
        Algorithm: jSO                f(x): 11.567473       Elapsed: 0.023 s
        Algorithm: j2020              f(x): 7.8875801e-07   Elapsed: 0.163 s
        Algorithm: LSRTDE             f(x): 5.9835982       Elapsed: 0.023 s
        Algorithm: NLSHADE_RSP        f(x): 0.25889458      Elapsed: 0.022 s
        Algorithm: ARRDE              f(x): 2.9848895       Elapsed: 0.033 s
        Algorithm: GWO_DE             f(x): 20.664176       Elapsed: 0.022 s
        Algorithm: NelderMead         f(x): 102.47964       Elapsed: 0.025 s
        Algorithm: DA                 f(x): 39.798216       Elapsed: 0.003 s
        Algorithm: L_BFGS_B           f(x): 102.47964       Elapsed: 0.001 s
        Algorithm: PSO                f(x): 8.9546271       Elapsed: 0.018 s
        Algorithm: DMSPSO             f(x): 2.9848772       Elapsed: 0.020 s
        Algorithm: SPSO2011           f(x): 17.358313       Elapsed: 0.021 s
        Algorithm: CMAES              f(x): 7.9596674       Elapsed: 0.029 s
        Algorithm: BIPOP_aCMAES       f(x): 19.899141       Elapsed: 0.045 s
        Algorithm: RCMAES             f(x): 3.9798362       Elapsed: 0.034 s
        Algorithm: Scipy Nelder-Mead  f(x): 254.70399       Elapsed: 0.033 s
        Algorithm: Scipy L-BFGS-B     f(x): 237.78983       Elapsed: 0.006 s
        Algorithm: Scipy DA           f(x): 3.375078e-14    Elapsed: 0.524 s

Function: schaffer2
        Algorithm: DE                 f(x): 0.65081687      Elapsed: 0.160 s
        Algorithm: ABC                f(x): 0.15434129      Elapsed: 0.171 s
        Algorithm: LSHADE             f(x): 0.20266581      Elapsed: 0.225 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.27548185      Elapsed: 0.254 s
        Algorithm: JADE               f(x): 0.089429299     Elapsed: 0.181 s
        Algorithm: jSO                f(x): 0.42909799      Elapsed: 0.161 s
        Algorithm: j2020              f(x): 0.47213831      Elapsed: 0.269 s
        Algorithm: LSRTDE             f(x): 0.72162619      Elapsed: 0.194 s
        Algorithm: NLSHADE_RSP        f(x): 0.20402425      Elapsed: 0.197 s
        Algorithm: ARRDE              f(x): 0.33442623      Elapsed: 0.184 s
        Algorithm: GWO_DE             f(x): 0.49450848      Elapsed: 0.189 s
        Algorithm: NelderMead         f(x): 0.18775994      Elapsed: 0.145 s
        Algorithm: DA                 f(x): 0.54146345      Elapsed: 0.016 s
        Algorithm: L_BFGS_B           f(x): 0.18775994      Elapsed: 0.023 s
        Algorithm: PSO                f(x): 0.44707258      Elapsed: 0.181 s
        Algorithm: DMSPSO             f(x): 0.56897164      Elapsed: 0.153 s
        Algorithm: SPSO2011           f(x): 0.60304324      Elapsed: 0.162 s
        Algorithm: CMAES              f(x): 0.42418884      Elapsed: 0.161 s
        Algorithm: BIPOP_aCMAES       f(x): 0.89193328      Elapsed: 0.210 s
        Algorithm: RCMAES             f(x): 0.11495135      Elapsed: 0.235 s
        Algorithm: Scipy Nelder-Mead  f(x): 0.38943872      Elapsed: 0.082 s
        Algorithm: Scipy L-BFGS-B     f(x): 0.38943873      Elapsed: 0.179 s
        Algorithm: Scipy DA           f(x): 0.048580255     Elapsed: 0.932 s

Function: griewank
        Algorithm: DE                 f(x): 0.058070859     Elapsed: 0.029 s
        Algorithm: ABC                f(x): 0.0033985548    Elapsed: 0.045 s
        Algorithm: LSHADE             f(x): 0.0018340505    Elapsed: 0.023 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.010286034     Elapsed: 0.033 s
        Algorithm: JADE               f(x): 3.3306691e-16   Elapsed: 0.032 s
        Algorithm: jSO                f(x): 0.15101667      Elapsed: 0.022 s
        Algorithm: j2020              f(x): 0.041824189     Elapsed: 0.220 s
        Algorithm: LSRTDE             f(x): 0.0046657659    Elapsed: 0.021 s
        Algorithm: NLSHADE_RSP        f(x): 0.0076825755    Elapsed: 0.024 s
        Algorithm: ARRDE              f(x): 0               Elapsed: 0.034 s
        Algorithm: GWO_DE             f(x): 0.022150776     Elapsed: 0.023 s
        Algorithm: NelderMead         f(x): 0.02461003      Elapsed: 0.036 s
        Algorithm: DA                 f(x): 0.11319805      Elapsed: 0.050 s
        Algorithm: L_BFGS_B           f(x): 0.02461003      Elapsed: 0.002 s
        Algorithm: PSO                f(x): 0.093409802     Elapsed: 0.019 s
        Algorithm: DMSPSO             f(x): 0.012316073     Elapsed: 0.021 s
        Algorithm: SPSO2011           f(x): 0.0033482646    Elapsed: 0.024 s
        Algorithm: CMAES              f(x): 0               Elapsed: 0.018 s
        Algorithm: BIPOP_aCMAES       f(x): 0.014772408     Elapsed: 0.053 s
        Algorithm: RCMAES             f(x): 2.43916e-13     Elapsed: 0.032 s
        Algorithm: Scipy Nelder-Mead  f(x): 0.046729411     Elapsed: 0.051 s
        Algorithm: Scipy L-BFGS-B     f(x): 0.024637062     Elapsed: 0.035 s
        Algorithm: Scipy DA           f(x): 0.090965727     Elapsed: 0.585 s

Function: ackley
        Algorithm: DE                 f(x): 1.1551485       Elapsed: 0.018 s
        Algorithm: ABC                f(x): 0.0026262615    Elapsed: 0.022 s
        Algorithm: LSHADE             f(x): 4.2703653e-05   Elapsed: 0.029 s
        Algorithm: LSHADE_cnEpSin     f(x): 1.3078989e-05   Elapsed: 0.037 s
        Algorithm: JADE               f(x): 1.4654944e-14   Elapsed: 0.030 s
        Algorithm: jSO                f(x): 8.4967761e-06   Elapsed: 0.026 s
        Algorithm: j2020              f(x): 4.3406527e-09   Elapsed: 0.260 s
        Algorithm: LSRTDE             f(x): 3.7132093e-05   Elapsed: 0.022 s
        Algorithm: NLSHADE_RSP        f(x): 0.00025993931   Elapsed: 0.026 s
        Algorithm: ARRDE              f(x): 4.1255888e-13   Elapsed: 0.038 s
        Algorithm: GWO_DE             f(x): 0.00086205221   Elapsed: 0.028 s
        Algorithm: NelderMead         f(x): 9.0738777       Elapsed: 0.037 s
        Algorithm: DA                 f(x): 8.4515582       Elapsed: 0.009 s
        Algorithm: L_BFGS_B           f(x): 9.4529928       Elapsed: 0.001 s
        Algorithm: PSO                f(x): 3.0926249e-08   Elapsed: 0.020 s
        Algorithm: DMSPSO             f(x): 8.7186845e-08   Elapsed: 0.024 s
        Algorithm: SPSO2011           f(x): 0.00014708193   Elapsed: 0.029 s
        Algorithm: CMAES              f(x): 7.5495166e-15   Elapsed: 0.032 s
        Algorithm: BIPOP_aCMAES       f(x): 5.0182081e-14   Elapsed: 0.056 s
        Algorithm: RCMAES             f(x): 5.2624571e-13   Elapsed: 0.034 s
        Algorithm: Scipy Nelder-Mead  f(x): 12.719749       Elapsed: 0.035 s
        Algorithm: Scipy L-BFGS-B     f(x): 12.719749       Elapsed: 0.012 s
        Algorithm: Scipy DA           f(x): 1.9016682e-08   Elapsed: 0.782 s

Function: zakharov
        Algorithm: DE                 f(x): 6.7319085e-10   Elapsed: 0.021 s
        Algorithm: ABC                f(x): 68.686964       Elapsed: 0.022 s
        Algorithm: LSHADE             f(x): 1.7793574e-06   Elapsed: 0.025 s
        Algorithm: LSHADE_cnEpSin     f(x): 8.3336135e-09   Elapsed: 0.036 s
        Algorithm: JADE               f(x): 1.2927008e-10   Elapsed: 0.042 s
        Algorithm: jSO                f(x): 1.7774563e-08   Elapsed: 0.025 s
        Algorithm: j2020              f(x): 0.052630981     Elapsed: 0.282 s
        Algorithm: LSRTDE             f(x): 3.9927412e-09   Elapsed: 0.022 s
        Algorithm: NLSHADE_RSP        f(x): 0.0033036086    Elapsed: 0.028 s
        Algorithm: ARRDE              f(x): 6.9119074e-15   Elapsed: 0.044 s
        Algorithm: GWO_DE             f(x): 0.005279014     Elapsed: 0.026 s
        Algorithm: NelderMead         f(x): 9.5208937e-30   Elapsed: 0.094 s
        Algorithm: DA                 f(x): 2.4048964e-11   Elapsed: 0.003 s
        Algorithm: L_BFGS_B           f(x): 2.1392905e-13   Elapsed: 0.003 s
        Algorithm: PSO                f(x): 3.6381897e-07   Elapsed: 0.023 s
        Algorithm: DMSPSO             f(x): 2.5707731e-09   Elapsed: 0.025 s
        Algorithm: SPSO2011           f(x): 0.0077367976    Elapsed: 0.039 s
        Algorithm: CMAES              f(x): 4.3479854e-28   Elapsed: 0.033 s
        Algorithm: BIPOP_aCMAES       f(x): 2.8547234e-27   Elapsed: 0.061 s
        Algorithm: RCMAES             f(x): 3.1856509e-13   Elapsed: 0.036 s
        Algorithm: Scipy Nelder-Mead  f(x): 7.6416259e-09   Elapsed: 0.105 s
        Algorithm: Scipy L-BFGS-B     f(x): 7.2026284e-14   Elapsed: 0.033 s
        Algorithm: Scipy DA           f(x): 1.4354997e-13   Elapsed: 0.585 s

Function: bent_cigar
        Algorithm: DE                 f(x): 29.006599       Elapsed: 0.015 s
        Algorithm: ABC                f(x): 0.11506033      Elapsed: 0.016 s
        Algorithm: LSHADE             f(x): 0.0025002294    Elapsed: 0.020 s
        Algorithm: LSHADE_cnEpSin     f(x): 5.9717649e-06   Elapsed: 0.030 s
        Algorithm: JADE               f(x): 4.9796845e-24   Elapsed: 0.027 s
        Algorithm: jSO                f(x): 0.00024070497   Elapsed: 0.020 s
        Algorithm: j2020              f(x): 1.1231602e-08   Elapsed: 0.153 s
        Algorithm: LSRTDE             f(x): 3.9890005e-06   Elapsed: 0.024 s
        Algorithm: NLSHADE_RSP        f(x): 0.00016536792   Elapsed: 0.023 s
        Algorithm: ARRDE              f(x): 2.2682853e-20   Elapsed: 0.033 s
        Algorithm: GWO_DE             f(x): 1.2819706       Elapsed: 0.026 s
        Algorithm: NelderMead         f(x): 7.6172326e-24   Elapsed: 0.064 s
        Algorithm: DA                 f(x): 5.7827062e-17   Elapsed: 0.002 s
        Algorithm: L_BFGS_B           f(x): 6.5127066e-14   Elapsed: 0.001 s
        Algorithm: PSO                f(x): 8.8400241e-10   Elapsed: 0.019 s
        Algorithm: DMSPSO             f(x): 3.1808956e-10   Elapsed: 0.025 s
        Algorithm: SPSO2011           f(x): 97.414782       Elapsed: 0.024 s
        Algorithm: CMAES              f(x): 3.8441176e-07   Elapsed: 0.030 s
        Algorithm: BIPOP_aCMAES       f(x): 1.9155292e-21   Elapsed: 0.059 s
        Algorithm: RCMAES             f(x): 3.420942e-13    Elapsed: 0.034 s
        Algorithm: Scipy Nelder-Mead  f(x): 98.947303       Elapsed: 0.043 s
        Algorithm: Scipy L-BFGS-B     f(x): 2.0992461e-10   Elapsed: 0.080 s
        Algorithm: Scipy DA           f(x): 2.7037432e-10   Elapsed: 0.538 s

Function: levy
        Algorithm: DE                 f(x): 6.4922554e-21   Elapsed: 0.026 s
        Algorithm: ABC                f(x): 3.6224872e-07   Elapsed: 0.031 s
        Algorithm: LSHADE             f(x): 9.1556036e-09   Elapsed: 0.035 s
        Algorithm: LSHADE_cnEpSin     f(x): 1.1069458e-10   Elapsed: 0.040 s
        Algorithm: JADE               f(x): 1.3831394e-30   Elapsed: 0.044 s
        Algorithm: jSO                f(x): 6.9503421e-10   Elapsed: 0.029 s
        Algorithm: j2020              f(x): 7.1913004e-12   Elapsed: 0.360 s
        Algorithm: LSRTDE             f(x): 7.7276062e-11   Elapsed: 0.026 s
        Algorithm: NLSHADE_RSP        f(x): 5.394141e-08    Elapsed: 0.032 s
        Algorithm: ARRDE              f(x): 1.4485636e-22   Elapsed: 0.049 s
        Algorithm: GWO_DE             f(x): 2.9158882e-06   Elapsed: 0.028 s
        Algorithm: NelderMead         f(x): 2.3300009       Elapsed: 0.065 s
        Algorithm: DA                 f(x): 1.883362        Elapsed: 0.016 s
        Algorithm: L_BFGS_B           f(x): 0.089528251     Elapsed: 0.002 s
        Algorithm: PSO                f(x): 0.45432402      Elapsed: 0.025 s
        Algorithm: DMSPSO             f(x): 1.3167123e-15   Elapsed: 0.025 s
        Algorithm: SPSO2011           f(x): 1.9169279e-06   Elapsed: 0.029 s
        Algorithm: CMAES              f(x): 5.8939727e-30   Elapsed: 0.036 s
        Algorithm: BIPOP_aCMAES       f(x): 2.5393056e-25   Elapsed: 0.064 s
        Algorithm: RCMAES             f(x): 2.1584126e-13   Elapsed: 0.038 s
        Algorithm: Scipy Nelder-Mead  f(x): 10.612364       Elapsed: 0.111 s
        Algorithm: Scipy L-BFGS-B     f(x): 5.6358232       Elapsed: 0.074 s
        Algorithm: Scipy DA           f(x): 1.3245842e-10   Elapsed: 0.920 s

Function: discus
        Algorithm: DE                 f(x): 1.2349284e-06   Elapsed: 0.015 s
        Algorithm: ABC                f(x): 4.2136472e-06   Elapsed: 0.015 s
        Algorithm: LSHADE             f(x): 2.645397e-07    Elapsed: 0.019 s
        Algorithm: LSHADE_cnEpSin     f(x): 2.7922858e-09   Elapsed: 0.029 s
        Algorithm: JADE               f(x): 3.4512665e-30   Elapsed: 0.025 s
        Algorithm: jSO                f(x): 1.3796864e-09   Elapsed: 0.019 s
        Algorithm: j2020              f(x): 9.1269245e-13   Elapsed: 0.146 s
        Algorithm: LSRTDE             f(x): 1.4300898e-10   Elapsed: 0.017 s
        Algorithm: NLSHADE_RSP        f(x): 1.058335e-07    Elapsed: 0.022 s
        Algorithm: ARRDE              f(x): 2.1379832e-22   Elapsed: 0.027 s
        Algorithm: GWO_DE             f(x): 3.5937759e-05   Elapsed: 0.020 s
        Algorithm: NelderMead         f(x): 2.5838254e-24   Elapsed: 0.078 s
        Algorithm: DA                 f(x): 4.0181518e-14   Elapsed: 0.002 s
        Algorithm: L_BFGS_B           f(x): 1.2333528e-13   Elapsed: 0.001 s
        Algorithm: PSO                f(x): 6.5854435e-12   Elapsed: 0.015 s
        Algorithm: DMSPSO             f(x): 1.8629488e-14   Elapsed: 0.017 s
        Algorithm: SPSO2011           f(x): 76.396509       Elapsed: 0.025 s
        Algorithm: CMAES              f(x): 2.9307015e-18   Elapsed: 0.027 s
        Algorithm: BIPOP_aCMAES       f(x): 6.6426122e-15   Elapsed: 0.040 s
        Algorithm: RCMAES             f(x): 2.6317567e-13   Elapsed: 0.030 s
        Algorithm: Scipy Nelder-Mead  f(x): 7.8818509e-09   Elapsed: 0.155 s
        Algorithm: Scipy L-BFGS-B     f(x): 7.8454543e-12   Elapsed: 0.045 s
        Algorithm: Scipy DA           f(x): 6.0097778e-05   Elapsed: 0.414 s

Function: drop_wave
        Algorithm: DE                 f(x): -1              Elapsed: 0.011 s
        Algorithm: ABC                f(x): -0.99185923     Elapsed: 0.031 s
        Algorithm: LSHADE             f(x): -1              Elapsed: 0.039 s
        Algorithm: LSHADE_cnEpSin     f(x): -1              Elapsed: 0.049 s
        Algorithm: JADE               f(x): -1              Elapsed: 0.024 s
        Algorithm: jSO                f(x): -1              Elapsed: 0.037 s
        Algorithm: j2020              f(x): -1              Elapsed: 0.128 s
        Algorithm: LSRTDE             f(x): -1              Elapsed: 0.037 s
        Algorithm: NLSHADE_RSP        f(x): -1              Elapsed: 0.038 s
        Algorithm: ARRDE              f(x): -1              Elapsed: 0.045 s
        Algorithm: GWO_DE             f(x): -1              Elapsed: 0.039 s
        Algorithm: NelderMead         f(x): -1              Elapsed: 0.018 s
        Algorithm: DA                 f(x): -1              Elapsed: 0.001 s
        Algorithm: L_BFGS_B           f(x): -0.93624533     Elapsed: 0.001 s
        Algorithm: PSO                f(x): -1              Elapsed: 0.034 s
        Algorithm: DMSPSO             f(x): -1              Elapsed: 0.034 s
        Algorithm: SPSO2011           f(x): -0.99999843     Elapsed: 0.042 s
        Algorithm: CMAES              f(x): -0.99581752     Elapsed: 0.041 s
        Algorithm: BIPOP_aCMAES       f(x): -0.99374443     Elapsed: 0.062 s
        Algorithm: RCMAES             f(x): -0.99496582     Elapsed: 0.047 s
        Algorithm: Scipy Nelder-Mead  f(x): -0.053939199    Elapsed: 0.016 s
        Algorithm: Scipy L-BFGS-B     f(x): -0.060920875    Elapsed: 0.003 s
        Algorithm: Scipy DA           f(x): -0.93624533     Elapsed: 0.386 s

Function: goldstein_price
        Algorithm: DE                 f(x): 3               Elapsed: 0.022 s
        Algorithm: ABC                f(x): 42.812827       Elapsed: 0.042 s
        Algorithm: LSHADE             f(x): 3               Elapsed: 0.048 s
        Algorithm: LSHADE_cnEpSin     f(x): 3               Elapsed: 0.065 s
        Algorithm: JADE               f(x): 3               Elapsed: 0.035 s
        Algorithm: jSO                f(x): 3               Elapsed: 0.048 s
        Algorithm: j2020              f(x): 3               Elapsed: 0.110 s
        Algorithm: LSRTDE             f(x): 3               Elapsed: 0.039 s
        Algorithm: NLSHADE_RSP        f(x): 3               Elapsed: 0.043 s
        Algorithm: ARRDE              f(x): 3               Elapsed: 0.046 s
        Algorithm: GWO_DE             f(x): 3               Elapsed: 0.041 s
        Algorithm: NelderMead         f(x): 3               Elapsed: 0.013 s
        Algorithm: DA                 f(x): 410.47045       Elapsed: 0.001 s
        Algorithm: L_BFGS_B           f(x): 3               Elapsed: 0.002 s
        Algorithm: PSO                f(x): 3               Elapsed: 0.036 s
        Algorithm: DMSPSO             f(x): 3               Elapsed: 0.038 s
        Algorithm: SPSO2011           f(x): 3.0001546       Elapsed: 0.045 s
        Algorithm: CMAES              f(x): 3               Elapsed: 0.051 s
        Algorithm: BIPOP_aCMAES       f(x): 3               Elapsed: 0.067 s
        Algorithm: RCMAES             f(x): 3               Elapsed: 0.061 s
        Algorithm: Scipy Nelder-Mead  f(x): 84              Elapsed: 0.027 s
        Algorithm: Scipy L-BFGS-B     f(x): 3               Elapsed: 0.128 s
        Algorithm: Scipy DA           f(x): 3               Elapsed: 0.537 s

Function: exponential
        Algorithm: DE                 f(x): -0.99985638     Elapsed: 0.022 s
        Algorithm: ABC                f(x): -0.99999983     Elapsed: 0.017 s
        Algorithm: LSHADE             f(x): -1              Elapsed: 0.027 s
        Algorithm: LSHADE_cnEpSin     f(x): -1              Elapsed: 0.035 s
        Algorithm: JADE               f(x): -1              Elapsed: 0.017 s
        Algorithm: jSO                f(x): -1              Elapsed: 0.024 s
        Algorithm: j2020              f(x): -1              Elapsed: 0.174 s
        Algorithm: LSRTDE             f(x): -1              Elapsed: 0.023 s
        Algorithm: NLSHADE_RSP        f(x): -1              Elapsed: 0.024 s
        Algorithm: ARRDE              f(x): -1              Elapsed: 0.033 s
        Algorithm: GWO_DE             f(x): -0.9999971      Elapsed: 0.025 s
        Algorithm: NelderMead         f(x): -1              Elapsed: 0.030 s
        Algorithm: DA                 f(x): -1.7984945e-13  Elapsed: 0.162 s
        Algorithm: L_BFGS_B           f(x): -1.609051e-22   Elapsed: 0.001 s
        Algorithm: PSO                f(x): -1              Elapsed: 0.017 s
        Algorithm: DMSPSO             f(x): -1              Elapsed: 0.021 s
        Algorithm: SPSO2011           f(x): -1              Elapsed: 0.024 s
        Algorithm: CMAES              f(x): -1              Elapsed: 0.017 s
        Algorithm: BIPOP_aCMAES       f(x): -1              Elapsed: 0.054 s
        Algorithm: RCMAES             f(x): -4.4682748e-15  Elapsed: 0.160 s
        Algorithm: Scipy Nelder-Mead  f(x): -1              Elapsed: 0.044 s
        Algorithm: Scipy L-BFGS-B     f(x): -5.2446221e-54  Elapsed: 0.001 s
        Algorithm: Scipy DA           f(x): -1.2603173e-10  Elapsed: 0.415 s

Function: quartic
        Algorithm: DE                 f(x): 0.070869952     Elapsed: 0.026 s
        Algorithm: ABC                f(x): 0.058337628     Elapsed: 0.027 s
        Algorithm: LSHADE             f(x): 0.034153371     Elapsed: 0.031 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.0051602264    Elapsed: 0.040 s
        Algorithm: JADE               f(x): 0.0040307964    Elapsed: 0.044 s
        Algorithm: jSO                f(x): 0.020823493     Elapsed: 0.031 s
        Algorithm: j2020              f(x): 0.013745377     Elapsed: 0.246 s
        Algorithm: LSRTDE             f(x): 0.0060928615    Elapsed: 0.028 s
        Algorithm: NLSHADE_RSP        f(x): 0.0092803471    Elapsed: 0.030 s
        Algorithm: ARRDE              f(x): 0.0021502969    Elapsed: 0.041 s
        Algorithm: GWO_DE             f(x): 0.007787476     Elapsed: 0.028 s
        Algorithm: NelderMead         f(x): 1.1578399       Elapsed: 0.119 s
        Algorithm: DA                 f(x): 0.043719912     Elapsed: 0.026 s
        Algorithm: L_BFGS_B           f(x): 0.11726177      Elapsed: 0.001 s
        Algorithm: PSO                f(x): 0.016140929     Elapsed: 0.025 s
        Algorithm: DMSPSO             f(x): 0.011472653     Elapsed: 0.026 s
        Algorithm: SPSO2011           f(x): 0.016133436     Elapsed: 0.031 s
        Algorithm: CMAES              f(x): 0.0033771471    Elapsed: 0.012 s
        Algorithm: BIPOP_aCMAES       f(x): 0.00022872766   Elapsed: 0.059 s
        Algorithm: RCMAES             f(x): 0.0043934279    Elapsed: 0.039 s
        Algorithm: Scipy Nelder-Mead  f(x): 11.235701       Elapsed: 0.293 s
        Algorithm: Scipy L-BFGS-B     f(x): 50784.738       Elapsed: 0.009 s
        Algorithm: Scipy DA           f(x): 0.26768236      Elapsed: 0.485 s

Function: hybrid_composition1
        Algorithm: DE                 f(x): 8.9683086       Elapsed: 0.020 s
        Algorithm: ABC                f(x): 27.482065       Elapsed: 0.025 s
        Algorithm: LSHADE             f(x): 8.9683095       Elapsed: 0.029 s
        Algorithm: LSHADE_cnEpSin     f(x): 8.9683084       Elapsed: 0.036 s
        Algorithm: JADE               f(x): 8.9683084       Elapsed: 0.045 s
        Algorithm: jSO                f(x): 8.9683085       Elapsed: 0.030 s
        Algorithm: j2020              f(x): 46.125917       Elapsed: 0.300 s
        Algorithm: LSRTDE             f(x): 8.9683085       Elapsed: 0.025 s
        Algorithm: NLSHADE_RSP        f(x): 8.9683114       Elapsed: 0.034 s
        Algorithm: ARRDE              f(x): 8.9683084       Elapsed: 0.051 s
        Algorithm: GWO_DE             f(x): 8.9707298       Elapsed: 0.034 s
        Algorithm: NelderMead         f(x): 8.9683084       Elapsed: 0.077 s
        Algorithm: DA                 f(x): 127.26569       Elapsed: 0.042 s
        Algorithm: L_BFGS_B           f(x): 129.896         Elapsed: 0.004 s
        Algorithm: PSO                f(x): 8.9683084       Elapsed: 0.029 s
        Algorithm: DMSPSO             f(x): 8.9683084       Elapsed: 0.032 s
        Algorithm: SPSO2011           f(x): 8.9683403       Elapsed: 0.028 s
        Algorithm: CMAES              f(x): 8.9683084       Elapsed: 0.040 s
        Algorithm: BIPOP_aCMAES       f(x): 8.9683084       Elapsed: 0.067 s
        Algorithm: RCMAES             f(x): 8.9683085       Elapsed: 0.047 s
        Algorithm: Scipy Nelder-Mead  f(x): 81.481178       Elapsed: 0.070 s
        Algorithm: Scipy L-BFGS-B     f(x): 49.451818       Elapsed: 0.045 s
        Algorithm: Scipy DA           f(x): 8.9683084       Elapsed: 0.720 s

Function: hybrid_composition2
        Algorithm: DE                 f(x): 0.004561202     Elapsed: 0.027 s
        Algorithm: ABC                f(x): 0.0059918142    Elapsed: 0.032 s
        Algorithm: LSHADE             f(x): 1.7486585e-05   Elapsed: 0.034 s
        Algorithm: LSHADE_cnEpSin     f(x): 7.2635021e-06   Elapsed: 0.043 s
        Algorithm: JADE               f(x): 1.5099033e-14   Elapsed: 0.042 s
        Algorithm: jSO                f(x): 1.1174438e-05   Elapsed: 0.035 s
        Algorithm: j2020              f(x): 3.6833568e-10   Elapsed: 0.489 s
        Algorithm: LSRTDE             f(x): 9.4920236e-06   Elapsed: 0.030 s
        Algorithm: NLSHADE_RSP        f(x): 0.00031830377   Elapsed: 0.044 s
        Algorithm: ARRDE              f(x): 1.0980753e-10   Elapsed: 0.060 s
        Algorithm: GWO_DE             f(x): 0.0041439795    Elapsed: 0.035 s
        Algorithm: NelderMead         f(x): 2.1270735       Elapsed: 0.170 s
        Algorithm: DA                 f(x): 1.5411461e-12   Elapsed: 0.064 s
        Algorithm: L_BFGS_B           f(x): 1.5647319e-11   Elapsed: 0.010 s
        Algorithm: PSO                f(x): 1.1284677e-07   Elapsed: 0.027 s
        Algorithm: DMSPSO             f(x): 1.2772599e-07   Elapsed: 0.032 s
        Algorithm: SPSO2011           f(x): 0.00063301396   Elapsed: 0.033 s
        Algorithm: CMAES              f(x): 1.2023368e-14   Elapsed: 0.047 s
        Algorithm: BIPOP_aCMAES       f(x): 5.492785e-14    Elapsed: 0.193 s
        Algorithm: RCMAES             f(x): 6.7368333e-13   Elapsed: 0.046 s
        Algorithm: Scipy Nelder-Mead  f(x): 9.7571206       Elapsed: 0.206 s
        Algorithm: Scipy L-BFGS-B     f(x): 6.6785884e-08   Elapsed: 0.323 s
        Algorithm: Scipy DA           f(x): 4.6583145e-08   Elapsed: 0.937 s

Function: hybrid_composition3
        Algorithm: DE                 f(x): 1.9432442       Elapsed: 0.034 s
        Algorithm: ABC                f(x): 44.02707        Elapsed: 0.049 s
        Algorithm: LSHADE             f(x): 1.2839537       Elapsed: 0.045 s
        Algorithm: LSHADE_cnEpSin     f(x): 1.2839526       Elapsed: 0.057 s
        Algorithm: JADE               f(x): 2.0659812       Elapsed: 0.123 s
        Algorithm: jSO                f(x): 1.2839529       Elapsed: 0.048 s
        Algorithm: j2020              f(x): 1.2297994       Elapsed: 0.697 s
        Algorithm: LSRTDE             f(x): 1.2839526       Elapsed: 0.043 s
        Algorithm: NLSHADE_RSP        f(x): 1.2895342       Elapsed: 0.061 s
        Algorithm: ARRDE              f(x): 1.2839526       Elapsed: 0.090 s
        Algorithm: GWO_DE             f(x): 1.2937963       Elapsed: 0.046 s
        Algorithm: NelderMead         f(x): 34.881183       Elapsed: 0.191 s
        Algorithm: DA                 f(x): 409.67197       Elapsed: 0.021 s
        Algorithm: L_BFGS_B           f(x): 1.7576298       Elapsed: 0.009 s
        Algorithm: PSO                f(x): 1.3048264       Elapsed: 0.048 s
        Algorithm: DMSPSO             f(x): 1.2839526       Elapsed: 0.060 s
        Algorithm: SPSO2011           f(x): 1.3928593       Elapsed: 0.050 s
        Algorithm: CMAES              f(x): 1.2839526       Elapsed: 0.062 s
        Algorithm: BIPOP_aCMAES       f(x): 1.2839526       Elapsed: 0.110 s
        Algorithm: RCMAES             f(x): 1.2839526       Elapsed: 0.057 s
        Algorithm: Scipy Nelder-Mead  f(x): 95.146651       Elapsed: 0.436 s
        Algorithm: Scipy L-BFGS-B     f(x): 3.2449736       Elapsed: 0.189 s
        Algorithm: Scipy DA           f(x): 84.671525       Elapsed: 1.593 s

Function: happy_cat
        Algorithm: DE                 f(x): 0.24842443      Elapsed: 0.020 s
        Algorithm: ABC                f(x): 0.14198151      Elapsed: 0.020 s
        Algorithm: LSHADE             f(x): 0.087076102     Elapsed: 0.024 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.062076569     Elapsed: 0.033 s
        Algorithm: JADE               f(x): 0.092519283     Elapsed: 0.041 s
        Algorithm: jSO                f(x): 0.16814755      Elapsed: 0.023 s
        Algorithm: j2020              f(x): 0.21229457      Elapsed: 0.256 s
        Algorithm: LSRTDE             f(x): 0.037592313     Elapsed: 0.023 s
        Algorithm: NLSHADE_RSP        f(x): 0.17675636      Elapsed: 0.025 s
        Algorithm: ARRDE              f(x): 0.069108926     Elapsed: 0.041 s
        Algorithm: GWO_DE             f(x): 0.063681861     Elapsed: 0.024 s
        Algorithm: NelderMead         f(x): 0.67618088      Elapsed: 0.047 s
        Algorithm: DA                 f(x): 0.48024234      Elapsed: 0.042 s
        Algorithm: L_BFGS_B           f(x): 0.48737281      Elapsed: 0.005 s
        Algorithm: PSO                f(x): 0.068418114     Elapsed: 0.019 s
        Algorithm: DMSPSO             f(x): 0.11946681      Elapsed: 0.021 s
        Algorithm: SPSO2011           f(x): 0.1403372       Elapsed: 0.025 s
        Algorithm: CMAES              f(x): 0.053993164     Elapsed: 0.032 s
        Algorithm: BIPOP_aCMAES       f(x): 0.12681222      Elapsed: 0.055 s
        Algorithm: RCMAES             f(x): 0.023070824     Elapsed: 0.035 s
        Algorithm: Scipy Nelder-Mead  f(x): 1.4407279       Elapsed: 0.053 s
        Algorithm: Scipy L-BFGS-B     f(x): 0.0058185876    Elapsed: 0.034 s
        Algorithm: Scipy DA           f(x): 0.030118229     Elapsed: 0.490 s

Function: michalewics
        Algorithm: DE                 f(x): -7.9662317      Elapsed: 0.029 s
        Algorithm: ABC                f(x): -9.1054083      Elapsed: 0.030 s
        Algorithm: LSHADE             f(x): -8.831381       Elapsed: 0.032 s
        Algorithm: LSHADE_cnEpSin     f(x): -6.9124412      Elapsed: 0.042 s
        Algorithm: JADE               f(x): -9.9532791      Elapsed: 0.041 s
        Algorithm: jSO                f(x): -7.2776346      Elapsed: 0.034 s
        Algorithm: j2020              f(x): -8.8476617      Elapsed: 0.232 s
        Algorithm: LSRTDE             f(x): -7.3367531      Elapsed: 0.031 s
        Algorithm: NLSHADE_RSP        f(x): -9.1364566      Elapsed: 0.051 s
        Algorithm: ARRDE              f(x): -6.218818       Elapsed: 0.077 s
        Algorithm: GWO_DE             f(x): -4.6309655      Elapsed: 0.037 s
        Algorithm: NelderMead         f(x): -3.6164748      Elapsed: 0.164 s
        Algorithm: DA                 f(x): -8.8685657      Elapsed: 0.029 s
        Algorithm: L_BFGS_B           f(x): -2.691988       Elapsed: 0.007 s
        Algorithm: PSO                f(x): -8.8899702      Elapsed: 0.026 s
        Algorithm: DMSPSO             f(x): -4.649747       Elapsed: 0.030 s
        Algorithm: SPSO2011           f(x): -4.6285815      Elapsed: 0.033 s
        Algorithm: CMAES              f(x): -8.4216953      Elapsed: 0.036 s
        Algorithm: BIPOP_aCMAES       f(x): -5.4731534      Elapsed: 0.059 s
        Algorithm: RCMAES             f(x): -8.8458964      Elapsed: 0.044 s
        Algorithm: Scipy Nelder-Mead  f(x): -4.2489914      Elapsed: 0.060 s
        Algorithm: Scipy L-BFGS-B     f(x): -3.2901105      Elapsed: 0.171 s
        Algorithm: Scipy DA           f(x): -9.7304209      Elapsed: 1.038 s

Function: scaffer6
        Algorithm: DE                 f(x): 0.44893978      Elapsed: 0.190 s
        Algorithm: ABC                f(x): 0.12666977      Elapsed: 0.188 s
        Algorithm: LSHADE             f(x): 0.13879553      Elapsed: 0.200 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.21941075      Elapsed: 0.211 s
        Algorithm: JADE               f(x): 0.095418172     Elapsed: 0.192 s
        Algorithm: jSO                f(x): 0.58634406      Elapsed: 0.190 s
        Algorithm: j2020              f(x): 0.29763368      Elapsed: 0.255 s
        Algorithm: LSRTDE             f(x): 0.41882412      Elapsed: 0.151 s
        Algorithm: NLSHADE_RSP        f(x): 0.16498872      Elapsed: 0.161 s
        Algorithm: ARRDE              f(x): 0.19949136      Elapsed: 0.164 s
        Algorithm: GWO_DE             f(x): 0.33439201      Elapsed: 0.163 s
        Algorithm: NelderMead         f(x): 0.18775994      Elapsed: 0.102 s
        Algorithm: DA                 f(x): 0.41635277      Elapsed: 0.028 s
        Algorithm: L_BFGS_B           f(x): 0.18775994      Elapsed: 0.021 s
        Algorithm: PSO                f(x): 0.19747744      Elapsed: 0.156 s
        Algorithm: DMSPSO             f(x): 0.45169701      Elapsed: 0.152 s
        Algorithm: SPSO2011           f(x): 0.40176798      Elapsed: 0.164 s
        Algorithm: CMAES              f(x): 0.4988771       Elapsed: 0.162 s
        Algorithm: BIPOP_aCMAES       f(x): 0.86123532      Elapsed: 0.173 s
        Algorithm: RCMAES             f(x): 0.14245952      Elapsed: 0.160 s
        Algorithm: Scipy Nelder-Mead  f(x): 0.38943872      Elapsed: 0.073 s
        Algorithm: Scipy L-BFGS-B     f(x): 0.38943873      Elapsed: 0.057 s
        Algorithm: Scipy DA           f(x): 0.087443189     Elapsed: 0.785 s

Function: hcf
        Algorithm: DE                 f(x): 0.0040127119    Elapsed: 0.020 s
        Algorithm: ABC                f(x): 0.0039428539    Elapsed: 0.020 s
        Algorithm: LSHADE             f(x): 0.00010537824   Elapsed: 0.025 s
        Algorithm: LSHADE_cnEpSin     f(x): 1.4195001e-05   Elapsed: 0.036 s
        Algorithm: JADE               f(x): 0               Elapsed: 0.031 s
        Algorithm: jSO                f(x): 4.1700744e-05   Elapsed: 0.025 s
        Algorithm: j2020              f(x): 4.3023236e-11   Elapsed: 0.207 s
        Algorithm: LSRTDE             f(x): 2.7320902e-05   Elapsed: 0.022 s
        Algorithm: NLSHADE_RSP        f(x): 4.8588408e-06   Elapsed: 0.026 s
        Algorithm: ARRDE              f(x): 3.8417507e-12   Elapsed: 0.038 s
        Algorithm: GWO_DE             f(x): 0.0023568929    Elapsed: 0.025 s
        Algorithm: NelderMead         f(x): 2.358758        Elapsed: 0.213 s
        Algorithm: DA                 f(x): 1.8598669e-12   Elapsed: 0.040 s
        Algorithm: L_BFGS_B           f(x): 5.0026665e-12   Elapsed: 0.007 s
        Algorithm: PSO                f(x): 5.6795821e-08   Elapsed: 0.020 s
        Algorithm: DMSPSO             f(x): 4.2086301e-08   Elapsed: 0.022 s
        Algorithm: SPSO2011           f(x): 0.00079478984   Elapsed: 0.033 s
        Algorithm: CMAES              f(x): 9.5075857e-15   Elapsed: 0.032 s
        Algorithm: BIPOP_aCMAES       f(x): 7.8962444e-14   Elapsed: 0.066 s
        Algorithm: RCMAES             f(x): 5.9729999e-13   Elapsed: 0.031 s
        Algorithm: Scipy Nelder-Mead  f(x): 9.2898681       Elapsed: 0.149 s
        Algorithm: Scipy L-BFGS-B     f(x): 3.4309798e-08   Elapsed: 0.247 s
        Algorithm: Scipy DA           f(x): 4.7082426e-08   Elapsed: 0.642 s

Function: grie_rosen
        Algorithm: DE                 f(x): 6.6380551       Elapsed: 0.019 s
        Algorithm: ABC                f(x): 1.3856696       Elapsed: 0.022 s
        Algorithm: LSHADE             f(x): 4.5895619       Elapsed: 0.036 s
        Algorithm: LSHADE_cnEpSin     f(x): 2.0254878       Elapsed: 0.037 s
        Algorithm: JADE               f(x): 5.4562989       Elapsed: 0.039 s
        Algorithm: jSO                f(x): 3.2760023       Elapsed: 0.024 s
        Algorithm: j2020              f(x): 4.1823264       Elapsed: 0.208 s
        Algorithm: LSRTDE             f(x): 5.4609907       Elapsed: 0.022 s
        Algorithm: NLSHADE_RSP        f(x): 7.6993979       Elapsed: 0.027 s
        Algorithm: ARRDE              f(x): 1.0000266       Elapsed: 0.039 s
        Algorithm: GWO_DE             f(x): 8.1840974       Elapsed: 0.025 s
        Algorithm: NelderMead         f(x): 1               Elapsed: 0.085 s
        Algorithm: DA                 f(x): 1               Elapsed: 0.032 s
        Algorithm: L_BFGS_B           f(x): 1               Elapsed: 0.006 s
        Algorithm: PSO                f(x): 5.5693049       Elapsed: 0.016 s
        Algorithm: DMSPSO             f(x): 8.9923264       Elapsed: 0.019 s
        Algorithm: SPSO2011           f(x): 7.761184        Elapsed: 0.022 s
        Algorithm: CMAES              f(x): 1.0466296       Elapsed: 0.030 s
        Algorithm: BIPOP_aCMAES       f(x): 4.9865791       Elapsed: 0.050 s
        Algorithm: RCMAES             f(x): 1               Elapsed: 0.029 s
        Algorithm: Scipy Nelder-Mead  f(x): 1               Elapsed: 0.081 s
        Algorithm: Scipy L-BFGS-B     f(x): 1               Elapsed: 0.096 s
        Algorithm: Scipy DA           f(x): 1               Elapsed: 0.758 s

Function: dixon_price
        Algorithm: DE                 f(x): 0.66666667      Elapsed: 0.013 s
        Algorithm: ABC                f(x): 0.021504914     Elapsed: 0.021 s
        Algorithm: LSHADE             f(x): 0.6666667       Elapsed: 0.025 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.66666667      Elapsed: 0.035 s
        Algorithm: JADE               f(x): 0.66666667      Elapsed: 0.033 s
        Algorithm: jSO                f(x): 0.66666667      Elapsed: 0.025 s
        Algorithm: j2020              f(x): 0.69717231      Elapsed: 0.239 s
        Algorithm: LSRTDE             f(x): 0.66666667      Elapsed: 0.023 s
        Algorithm: NLSHADE_RSP        f(x): 0.022934338     Elapsed: 0.027 s
        Algorithm: ARRDE              f(x): 0.66666667      Elapsed: 0.039 s
        Algorithm: GWO_DE             f(x): 0.66729414      Elapsed: 0.026 s
        Algorithm: NelderMead         f(x): 0.66666667      Elapsed: 0.049 s
        Algorithm: DA                 f(x): 0.66666667      Elapsed: 0.003 s
        Algorithm: L_BFGS_B           f(x): 0.66666667      Elapsed: 0.004 s
        Algorithm: PSO                f(x): 0.66666667      Elapsed: 0.019 s
        Algorithm: DMSPSO             f(x): 0.66666667      Elapsed: 0.024 s
        Algorithm: SPSO2011           f(x): 0.6668304       Elapsed: 0.029 s
        Algorithm: CMAES              f(x): 0.66666667      Elapsed: 0.032 s
        Algorithm: BIPOP_aCMAES       f(x): 0.66666667      Elapsed: 0.061 s
        Algorithm: RCMAES             f(x): 0.66666667      Elapsed: 0.036 s
        Algorithm: Scipy Nelder-Mead  f(x): 0.66666667      Elapsed: 0.114 s
        Algorithm: Scipy L-BFGS-B     f(x): 0.66666667      Elapsed: 0.101 s
        Algorithm: Scipy DA           f(x): 5.3988228e-11   Elapsed: 0.705 s

Function: eosom
        Algorithm: DE                 f(x): -0.0090056781   Elapsed: 0.028 s
        Algorithm: ABC                f(x): -0.0090033933   Elapsed: 0.035 s
        Algorithm: LSHADE             f(x): -0.0090056781   Elapsed: 0.053 s
        Algorithm: LSHADE_cnEpSin     f(x): -0.0090056781   Elapsed: 0.045 s
        Algorithm: JADE               f(x): -0.0090056781   Elapsed: 0.025 s
        Algorithm: jSO                f(x): -0.0090056781   Elapsed: 0.036 s
        Algorithm: j2020              f(x): -0.0090056781   Elapsed: 0.106 s
        Algorithm: LSRTDE             f(x): -0.0090056781   Elapsed: 0.033 s
        Algorithm: NLSHADE_RSP        f(x): -0.0090056781   Elapsed: 0.035 s
        Algorithm: ARRDE              f(x): -0.0090056781   Elapsed: 0.041 s
        Algorithm: GWO_DE             f(x): -0.0090056781   Elapsed: 0.039 s
        Algorithm: NelderMead         f(x): -7.8737549e-14  Elapsed: 0.013 s
        Algorithm: DA                 f(x): -0.0075252849   Elapsed: 0.001 s
        Algorithm: L_BFGS_B           f(x): 2.8026392e-10   Elapsed: 0.000 s
        Algorithm: PSO                f(x): -0.0090056781   Elapsed: 0.034 s
        Algorithm: DMSPSO             f(x): -0.0090056781   Elapsed: 0.034 s
        Algorithm: SPSO2011           f(x): -0.009005678    Elapsed: 0.039 s
        Algorithm: CMAES              f(x): -0.0090056781   Elapsed: 0.041 s
        Algorithm: BIPOP_aCMAES       f(x): -0.0090056781   Elapsed: 0.062 s
        Algorithm: RCMAES             f(x): -0.0090056781   Elapsed: 0.043 s
        Algorithm: Scipy Nelder-Mead  f(x): -0.0090056781   Elapsed: 0.013 s
        Algorithm: Scipy L-BFGS-B     f(x): -1.4567312e-07  Elapsed: 0.001 s
        Algorithm: Scipy DA           f(x): -0.0090056781   Elapsed: 0.452 s

Function: hgbat
        Algorithm: DE                 f(x): 0.50042909      Elapsed: 0.024 s
        Algorithm: ABC                f(x): 0.51335789      Elapsed: 0.025 s
        Algorithm: LSHADE             f(x): 0.50000605      Elapsed: 0.027 s
        Algorithm: LSHADE_cnEpSin     f(x): 0.50000521      Elapsed: 0.039 s
        Algorithm: JADE               f(x): 0.5             Elapsed: 0.036 s
        Algorithm: jSO                f(x): 0.5000067       Elapsed: 0.027 s
        Algorithm: j2020              f(x): 0.50000057      Elapsed: 0.288 s
        Algorithm: LSRTDE             f(x): 0.50000743      Elapsed: 0.027 s
        Algorithm: NLSHADE_RSP        f(x): 0.50283126      Elapsed: 0.030 s
        Algorithm: ARRDE              f(x): 0.50000001      Elapsed: 0.047 s
        Algorithm: GWO_DE             f(x): 0.50137955      Elapsed: 0.032 s
        Algorithm: NelderMead         f(x): 0.5             Elapsed: 0.088 s
        Algorithm: DA                 f(x): 0.50000001      Elapsed: 0.047 s
        Algorithm: L_BFGS_B           f(x): 0.50000001      Elapsed: 0.005 s
        Algorithm: PSO                f(x): 0.50000021      Elapsed: 0.024 s
        Algorithm: DMSPSO             f(x): 0.50000006      Elapsed: 0.025 s
        Algorithm: SPSO2011           f(x): 0.50012731      Elapsed: 0.028 s
        Algorithm: CMAES              f(x): 0.5             Elapsed: 0.040 s
        Algorithm: BIPOP_aCMAES       f(x): 0.5             Elapsed: 0.076 s
        Algorithm: RCMAES             f(x): 0.5             Elapsed: 0.039 s
        Algorithm: Scipy Nelder-Mead  f(x): 0.5000703       Elapsed: 0.062 s
        Algorithm: Scipy L-BFGS-B     f(x): 0.50000001      Elapsed: 0.072 s
        Algorithm: Scipy DA           f(x): 0.50000001      Elapsed: 0.626 s

Function: styblinski_tang
        Algorithm: DE                 f(x): -349.2515       Elapsed: 0.019 s
        Algorithm: ABC                f(x): -391.66152      Elapsed: 0.028 s
        Algorithm: LSHADE             f(x): -391.66159      Elapsed: 0.033 s
        Algorithm: LSHADE_cnEpSin     f(x): -391.66166      Elapsed: 0.043 s
        Algorithm: JADE               f(x): -349.2515       Elapsed: 0.020 s
        Algorithm: jSO                f(x): -391.66166      Elapsed: 0.032 s
        Algorithm: j2020              f(x): -391.66166      Elapsed: 0.196 s
        Algorithm: LSRTDE             f(x): -391.66166      Elapsed: 0.033 s
        Algorithm: NLSHADE_RSP        f(x): -391.66165      Elapsed: 0.032 s
        Algorithm: ARRDE              f(x): -391.66166      Elapsed: 0.042 s
        Algorithm: GWO_DE             f(x): -391.66158      Elapsed: 0.037 s
        Algorithm: NelderMead         f(x): -306.84134      Elapsed: 0.033 s
        Algorithm: DA                 f(x): -335.11478      Elapsed: 0.002 s
        Algorithm: L_BFGS_B           f(x): -320.97806      Elapsed: 0.001 s
        Algorithm: PSO                f(x): -335.11478      Elapsed: 0.026 s
        Algorithm: DMSPSO             f(x): -363.38822      Elapsed: 0.029 s
        Algorithm: SPSO2011           f(x): -349.24089      Elapsed: 0.031 s
        Algorithm: CMAES              f(x): -363.38822      Elapsed: 0.023 s
        Algorithm: BIPOP_aCMAES       f(x): -349.2515       Elapsed: 0.056 s
        Algorithm: RCMAES             f(x): -391.66166      Elapsed: 0.041 s
        Algorithm: Scipy Nelder-Mead  f(x): -250.29447      Elapsed: 0.057 s
        Algorithm: Scipy L-BFGS-B     f(x): -292.70462      Elapsed: 0.033 s
        Algorithm: Scipy DA           f(x): -391.66166      Elapsed: 0.510 s

Function: step
        Algorithm: DE                 f(x): 0               Elapsed: 0.003 s
        Algorithm: ABC                f(x): 0               Elapsed: 0.015 s
        Algorithm: LSHADE             f(x): 0               Elapsed: 0.013 s
        Algorithm: LSHADE_cnEpSin     f(x): 0               Elapsed: 0.016 s
        Algorithm: JADE               f(x): 0               Elapsed: 0.004 s
        Algorithm: jSO                f(x): 0               Elapsed: 0.010 s
        Algorithm: j2020              f(x): 0               Elapsed: 0.145 s
        Algorithm: LSRTDE             f(x): 0               Elapsed: 0.022 s
        Algorithm: NLSHADE_RSP        f(x): 0               Elapsed: 0.029 s
        Algorithm: ARRDE              f(x): 0               Elapsed: 0.051 s
        Algorithm: GWO_DE             f(x): 0               Elapsed: 0.031 s
        Algorithm: NelderMead         f(x): 98              Elapsed: 0.003 s
        Algorithm: DA                 f(x): 20              Elapsed: 0.009 s
        Algorithm: L_BFGS_B           f(x): 103             Elapsed: 0.000 s
        Algorithm: PSO                f(x): 0               Elapsed: 0.023 s
        Algorithm: DMSPSO             f(x): 0               Elapsed: 0.020 s
        Algorithm: SPSO2011           f(x): 0               Elapsed: 0.019 s
        Algorithm: CMAES              f(x): 0               Elapsed: 0.004 s
        Algorithm: BIPOP_aCMAES       f(x): 0               Elapsed: 0.066 s
        Algorithm: RCMAES             f(x): 0               Elapsed: 0.041 s
        Algorithm: Scipy Nelder-Mead  f(x): 256             Elapsed: 0.019 s
        Algorithm: Scipy L-BFGS-B     f(x): 256             Elapsed: 0.001 s
        Algorithm: Scipy DA           f(x): 0               Elapsed: 0.449 s

Function: weierstrass
        Algorithm: DE                 f(x): 5.8761522       Elapsed: 1.202 s
        Algorithm: ABC                f(x): 2.3723588       Elapsed: 1.044 s
        Algorithm: LSHADE             f(x): 1.5049742       Elapsed: 1.068 s
        Algorithm: LSHADE_cnEpSin     f(x): 2.7693089       Elapsed: 1.223 s
        Algorithm: JADE               f(x): 0.1685608       Elapsed: 1.219 s
        Algorithm: jSO                f(x): 8.8892226       Elapsed: 1.081 s
        Algorithm: j2020              f(x): 2.8053528       Elapsed: 1.292 s
        Algorithm: LSRTDE             f(x): 7.9584357       Elapsed: 1.146 s
        Algorithm: NLSHADE_RSP        f(x): 2.1754807       Elapsed: 1.023 s
        Algorithm: ARRDE              f(x): 3.326122        Elapsed: 0.994 s
        Algorithm: GWO_DE             f(x): 7.4846498       Elapsed: 1.086 s
        Algorithm: NelderMead         f(x): 16.331325       Elapsed: 0.246 s
        Algorithm: DA                 f(x): 8.014514        Elapsed: 1.155 s
        Algorithm: L_BFGS_B           f(x): 17.40283        Elapsed: 0.273 s
        Algorithm: PSO                f(x): 0.027949274     Elapsed: 1.188 s
        Algorithm: DMSPSO             f(x): 4.0940825       Elapsed: 1.040 s
        Algorithm: SPSO2011           f(x): 7.9086895       Elapsed: 1.015 s
        Algorithm: CMAES              f(x): 10.448703       Elapsed: 1.003 s
        Algorithm: BIPOP_aCMAES       f(x): 10.006577       Elapsed: 1.019 s
        Algorithm: RCMAES             f(x): 2.1740897       Elapsed: 1.046 s
        Algorithm: Scipy Nelder-Mead  f(x): 6.4472257       Elapsed: 0.174 s
        Algorithm: Scipy L-BFGS-B     f(x): 15.858066       Elapsed: 0.301 s
        Algorithm: Scipy DA           f(x): 5.1439642       Elapsed: 2.370 s

Function: sum_squares
        Algorithm: DE                 f(x): 1.0058945e-20   Elapsed: 0.025 s
        Algorithm: ABC                f(x): 4.0018809e-06   Elapsed: 0.025 s
        Algorithm: LSHADE             f(x): 1.8222616e-09   Elapsed: 0.032 s
        Algorithm: LSHADE_cnEpSin     f(x): 8.9597182e-12   Elapsed: 0.032 s
        Algorithm: JADE               f(x): 8.2337357e-30   Elapsed: 0.020 s
        Algorithm: jSO                f(x): 8.1234558e-10   Elapsed: 0.021 s
        Algorithm: j2020              f(x): 8.6117047e-13   Elapsed: 0.150 s
        Algorithm: LSRTDE             f(x): 6.5865205e-09   Elapsed: 0.018 s
        Algorithm: NLSHADE_RSP        f(x): 4.0121718e-08   Elapsed: 0.019 s
        Algorithm: ARRDE              f(x): 1.1467257e-24   Elapsed: 0.028 s
        Algorithm: GWO_DE             f(x): 1.4033047e-05   Elapsed: 0.020 s
        Algorithm: NelderMead         f(x): 8.310147e-30    Elapsed: 0.042 s
        Algorithm: DA                 f(x): 1.3587359e-13   Elapsed: 0.002 s
        Algorithm: L_BFGS_B           f(x): 4.0453218e-14   Elapsed: 0.001 s
        Algorithm: PSO                f(x): 8.3874388e-15   Elapsed: 0.015 s
        Algorithm: DMSPSO             f(x): 5.7806741e-15   Elapsed: 0.019 s
        Algorithm: SPSO2011           f(x): 9.4998011e-07   Elapsed: 0.020 s
        Algorithm: CMAES              f(x): 2.5958601e-29   Elapsed: 0.027 s
        Algorithm: BIPOP_aCMAES       f(x): 1.4833479e-26   Elapsed: 0.046 s
        Algorithm: RCMAES             f(x): 1.6814137e-13   Elapsed: 0.027 s
        Algorithm: Scipy Nelder-Mead  f(x): 1.6899228e-08   Elapsed: 0.041 s
        Algorithm: Scipy L-BFGS-B     f(x): 1.8569833e-11   Elapsed: 0.044 s
        Algorithm: Scipy DA           f(x): 4.1442849e-11   Elapsed: 0.456 s

Minimizing Expensive Functions with Multithreading/Multiprocessing

When the objective function is expensive to evaluate, multithreading can be used to speed up the calculation of the vectorized objective function. However, this requires that the objective function is thread-safe.

If the objective function is not thread-safe, then multiprocessing can be used instead. This approach allows parallel execution across separate processes, which avoids the potential issues with thread safety.

Example to vectorize a thread-safe function using multithreading and multiprocessing

If the function is thread-safe to call cuncurrently, then we can safely use concurrent.futures.ThreadPoolExecutor (for multithreading) or concurrent.futures.ProcessPoolExecutor (for multiproceesing) directly.

[6]:
# Function to minimize (expensive to evaluate)
def func(x):
    ret = rosenbrock(x)
    time.sleep(0.01)  # Simulate expensive computation
    return ret

# Parallel execution setup
Nthreads = 8
use_threads = True  # Toggle between ThreadPoolExecutor and ProcessPoolExecutor

if use_threads:
    executor = concurrent.futures.ThreadPoolExecutor(max_workers=Nthreads)
else:
    executor = concurrent.futures.ProcessPoolExecutor(max_workers=Nthreads)

def objective_function(X):
    return list(executor.map(func, X))  # Batch evaluation in parallel

# Optimization problem settings
dimension = 10
maxevals = 1000
x0 = [[3.0] * dimension]
bounds = [(-10, 10)] * dimension

# List of algorithms to test
algorithms = {
    "ARRDE": {"options": None},
    "L_BFGS_B": {"options": {"func_noise_ratio": 0.0, "N_points_derivative": 1}},
    "DA": {"options": None}
}

print("\nOptimization Results:")
print("=" * 100)

# Run optimizations using Minion
for algo, settings in algorithms.items():
    start_time = time.time()
    minimizer = mpy.Minimizer(
        func=objective_function,
        x0=x0,
        bounds=bounds,
        algo=algo,
        maxevals=maxevals,
        callback=None,
        seed=None,
        options=settings["options"]
    )
    result = minimizer.optimize()
    elapsed = time.time() - start_time

    print(f"Algo : {algo:<30} | f(x) = {result.fun:<20.8g} | Elapsed: {elapsed:.2f} sec")

# Compare with SciPy optimizers (without multithreading)
for algo, opt_func in [
    ("Scipy Dual Annealing", dual_annealing),
    ("Scipy L-BFGS-B", minimize)
]:
    start_time = time.time()
    if algo == "Scipy Dual Annealing":
        result = opt_func(func, bounds=bounds, maxfun=maxevals, no_local_search=False, x0=x0[0])
    else:
        result = opt_func(func, x0=x0[0], method="L-BFGS-B", options={"maxfun": maxevals}, bounds=bounds)

    elapsed = time.time() - start_time
    print(f"Algo : {algo:<30} | f(x) = {result.fun:<20.8g} | Elapsed: {elapsed:.2f} sec")

print("=" * 100)

# Shutdown executor gracefully
executor.shutdown()



Optimization Results:
====================================================================================================
Algo : ARRDE                          | f(x) = 174.31405            | Elapsed: 1.81 sec
Algo : L_BFGS_B                       | f(x) = 100                  | Elapsed: 1.74 sec
Algo : DA                             | f(x) = 100.00002            | Elapsed: 1.71 sec
Algo : Scipy Dual Annealing           | f(x) = 100                  | Elapsed: 10.59 sec
Algo : Scipy L-BFGS-B                 | f(x) = 100                  | Elapsed: 4.55 sec
====================================================================================================

The algorithms implemented in Minion (ARRDE, L-BFGS-B, and Dual Annealing) significantly outperform their SciPy counterparts in speed. For example, Minion’s Dual Annealing is roughly 4 times as fast as the SciPy’s, while its L-BFGS-B is almost three times as fast. This performance improvement stems from Minion’s efficient numerical derivative computation, which batches function evaluations—an approach that greatly benefits minion’s L-BFGS-B and Dual Annealing. Note that dual annealing use L-BFGS-B for local search.


Using minionpy.Thread_Parallel to vectorize non-thread-safe member function

In the previous example, we demonstrated how to minimize a thread-safe function. However, in real-world scenarios, the objective function is often a method of a class, and class methods are typically not thread-safe. In this example, we demonstrate how to minimize a non-thread-safe function using the Thread_Parallel class. This approach ensures proper parallelization even when the objective function modifies internal state, which can lead to race conditions in a multi-threaded environment.

1. Define the Class with objective_function

First, define a class that includes the objective_function. This function should accept a list of floats as input and return a single float as the output. In this example, the objective_function modifies an internal state, which makes it non-thread-safe. We will show how the minionpy Thread_Parallel class manages the parallel execution of such functions while ensuring thread isolation.

[7]:
class Objective :
    """
    This illustrate a class with a non-thread-safe self.objective_function
    """
    def __init__ (self, b) :
        self.A=None  # There is a now class member that will be modified when self.objective_function is called.
        self.b = b

    def update_A(self, x) :
        self.A = self.b*np.sin(x) #modify self.A
        time.sleep(0.05)  #simulate an expensive function

    def objective_function(self, x) :
        self.update_A(x)
        ret = np.sum(self.A*x)
        #print(x, ret)
        return ret

2. Define the Thread_Parallel object

[8]:
# Here, we vectorize `Objective.objective_function` using 8 threads, with the `b` parameter in the Objective class constructor set to `0.2`.
t_parallel = mpy.Thread_Parallel(8, Objective, 0.2)

#You can test the vectorization as follows :
X = np.random.rand(8, 8) #randomly creates 6 vectors of dimension 8
start = time.time()
res = t_parallel(X)
print("Vectorization using Thread_Parallel : \n\t", res)
print("Elapsed  : ", time.time()-start, "\n")

obj=Objective(b=0.2)
start = time.time()
res2 = [obj.objective_function(x) for x in X]
print("Calling the function sequentially : \n\t", res2)
print("Elapsed  : ", time.time()-start, "\n")

#test if res and res2 are exactly the same
print(np.array(res).all() == np.array(res2).all())
Vectorization using Thread_Parallel :
         [np.float64(0.49893952609903164), np.float64(0.7409753800678246), np.float64(0.24359533253570678), np.float64(0.5357962121266069), np.float64(0.46151024712130534), np.float64(0.39240877478906944), np.float64(0.6346171946138794), np.float64(0.44213163313063997)]
Elapsed  :  0.0527501106262207

Calling the function sequentially :
         [np.float64(0.49893952609903164), np.float64(0.7409753800678246), np.float64(0.24359533253570678), np.float64(0.5357962121266069), np.float64(0.46151024712130534), np.float64(0.39240877478906944), np.float64(0.6346171946138794), np.float64(0.44213163313063997)]
Elapsed  :  0.4025554656982422

True

3. Minimize using one of minionpy algorithms

[9]:
dimension = 8 #set dimension of the problem
maxevals = 1000 #number of function calls
x0 = [[3.0]*dimension] # initial guess
bounds = [(-10, 10)]*dimension
algo = "ARRDE"

now = time.time()
min = mpy.Minimizer(func=t_parallel, x0=x0, bounds=bounds, algo=algo,
                     maxevals=maxevals, callback=None, seed=None, options={"population_size": 0})
result = min.optimize()
elapsed= time.time()-now
print("Algo : ",algo, "\n\t x : ", result.x, "\n\t f(x) : ", result.fun, "\n\t Elapsed: ", elapsed, " seconds\n")
print("Test function value  : ", Objective(b=0.2).objective_function(np.asarray(result.x)))
Algo :  ARRDE
         x :  [-4.9793382374756305, 9.982636076912668, -4.874947560843359, -4.855394656922106, 4.890119980137681, -4.904571604837544, 4.896492221865951, -4.9504384303105935]
         f(x) :  -7.7911872282137455
         Elapsed:  9.690591812133789  seconds

Test function value  :  -7.7911872282137455

We can observe that the minimum found by the ARRDE algorithm corresponds to the correct function value. But what happens if we use ThreadPoolExecutor without considering the thread-safety of the objective_function method?

[10]:
obj = Objective(b=0.2)
executor = concurrent.futures.ThreadPoolExecutor(max_workers=8)

def vectorize_obj(X) :
    ret = list(executor.map(obj.objective_function, np.asarray(X)))
    return ret

now = time.time()
min = mpy.Minimizer(func=vectorize_obj, x0=x0, bounds=bounds, algo=algo,maxevals=maxevals, callback=None, seed=None, options=None)
result = min.optimize()
elapsed= time.time()-now
print("Algo : ",algo, "\n\t x : ", result.x, "\n\t f(x) : ", result.fun, "\n\t Elapsed: ", elapsed, " seconds\n")
print("Test function value  :", obj.objective_function(np.asarray(result.x)))
executor.shutdown(wait=True)
Algo :  ARRDE
         x :  [8.569440953483959, 7.020317330209963, 9.184611352677384, 2.3169961890615167, 7.969545092991909, 7.909275619087072, 7.717387640207804, 9.991115008678161]
         f(x) :  -9.356496428000847
         Elapsed:  9.68142294883728  seconds

Test function value  : 6.63427532464428

We can see that the function value of the minimum is not the same as the actual function value.

Using multiprocessing for non-thread-safe functions using minionpy.Process_Parallel

If multiprocessing is preferred over multithreading, whether to bypass the Global Interpreter Lock (GIL) or to ensure clean separation of data during objective function vectorization, minionpy provides the Process_Parallel feature. It follows the same usage rules as Thread_Parallel. When using Process_Parallel, a predefined number of reusable processes are created, each with its own instance of the class object. This approach works correctly, but it is best demonstrated from a separate Python script rather than directly from a notebook cell. On many platforms, multiprocessing workers must be able to import the objective class from a real module, so the example should be placed in a standalone file and executed under if __name__ == "__main__":.

[11]:
# Note : the following snippet should be used in a separate script under if __name__ == "__main__", as Process_Parallel does not work in Jupyter notebooks.
p_parallel = mpy.Process_Parallel(8, Objective, 0.2)

#You can test the vectorization as follows :
start = time.time()
X = np.random.rand(8, 6) #randomly creates 6 vectors of dimension 8
res = p_parallel(X)
print("Vectorization using Process_Parallel : \n\t", res)
print("Elapsed  : ", time.time()-start, "\n")

obj=Objective(b=0.2)
start = time.time()
res2 = [obj.objective_function(x) for x in X]
print("Calling the function sequentially : \n\t", res2)
print("Elapsed  : ", time.time()-start, "\n")

#test if res and res2 are exactly the same
print(np.array(res).all() == np.array(res2).all())
Vectorization using Process_Parallel :
         [np.float64(0.14347422107693497), np.float64(0.595757752378875), np.float64(0.24379180202046255), np.float64(0.5777028302138887), np.float64(0.27153814522743025), np.float64(0.32516728314335863), np.float64(0.6222880906835925), np.float64(0.44156938555407277)]
Elapsed  :  0.16840600967407227

Calling the function sequentially :
         [np.float64(0.14347422107693497), np.float64(0.595757752378875), np.float64(0.24379180202046255), np.float64(0.5777028302138887), np.float64(0.27153814522743025), np.float64(0.32516728314335863), np.float64(0.6222880906835925), np.float64(0.44156938555407277)]
Elapsed  :  0.4021761417388916

True
[12]:
# Note : the following snippet should be used in a separate script under if __name__ == "__main__", as Process_Parallel does not work in Jupyter notebooks.
dimension = 8 #set dimension of the problem
maxevals = 1000 #number of function calls
x0 = [[3.0]*dimension] # initial guess
bounds = [(-10, 10)]*dimension
algo = "ARRDE"

now = time.time()
min = mpy.Minimizer(func=p_parallel, x0=x0, bounds=bounds, algo=algo,
                     maxevals=maxevals, callback=None, seed=None, options={"population_size": 0})
result = min.optimize()
elapsed= time.time()-now
print("Algo : ",algo, "\n\t x : ", result.x, "\n\t f(x) : ", result.fun, "\n\t Elapsed: ", elapsed, " seconds\n")
print("Test function value  : ", Objective(b=0.2).objective_function(np.asarray(result.x)))
Algo :  ARRDE
         x :  [4.967707305289708, -5.2841586321752425, -4.819575479547448, 5.001164040521943, 4.751497421558071, -5.056955854461807, 4.853100691209513, -4.817559553728316]
         f(x) :  -7.588002076496824
         Elapsed:  9.84260106086731  seconds

Test function value  :  -7.588002076496824

Algorithm Comparisons Using CEC Benchmark Problems

We can compare the performance of different optimization algorithms by evaluating them on benchmark problems from the Congress on Evolutionary Computation (CEC) competition. The Minion library provides implementations of benchmark problems from the following CEC years: 2011, 2014, 2017, 2019, 2020, and 2022.

  • CEC2014 and CEC2017: These benchmarks contain 30 problems, implemented for dimensions 10, 20, 30, 50, and 100.

  • CEC2019: This set includes 10 problems with varying dimensions.

  • CEC2020: It contains 10 problems with dimensions 5, 10, 15, and 20.

  • CEC2022: This set consists of 12 problems with dimensions 10 and 20.

CEC problems typically include a variety of function types:

  • Basic functions (e.g., Rosenbrock, Rastrigin),

  • Hybrid functions (new functions constructed by combining basic functions, where each component is evaluated using a different basic function),

  • Composite functions (linear combinations of basic functions, where the coefficients are also functions of the input vector).

These functions are often shifted and rotated to introduce additional complexity.

[14]:
import threading
import concurrent.futures

# This script minimizes CEC benchmark problems, repeated for NRuns times.

# Global results variable
results = []
results_lock = threading.Lock()

def test_optimization(func, bounds, dimension, func_name, Nmaxeval, seed):
    """Runs optimization algorithms on a given function and stores the results."""
    global results
    result = {
        "Dimensions": dimension,
        "Function": func_name
    }

    x0 = [[0.0 for _ in range(len(bounds))]]

    print(f"\nRunning optimization for {func_name} (Dimension: {dimension})")
    print("=" * 60)

    for algo in algos:
        res = mpy.Minimizer(
            func, bounds, x0=x0, algo=algo,
            maxevals=Nmaxeval, callback=None, seed=None,
            options={
                "population_size"   : 0, #2*dimension,
                "func_noise_ratio"  :  0.0,
                "N_points_derivative": 1,
                "bound_strategy" : "reflect-random",
                "convergence_tol" : 0.0
                }
        ).optimize()
        result[algo] = res.fun
        print(f"  {algo:<15} f(x): {res.fun:<20.8g}")

    def func_scipy(par):
        return func([par])[0]

    # SciPy Optimizers
    scipy_algorithms = [
        ("Scipy L-BFGS-B", minimize, {"x0": x0[0], "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}, "bounds": bounds}),
         ("Scipy Nelder-Mead", minimize, {"x0": x0[0], "method": "Nelder-Mead", "bounds": bounds, "options": {"maxfev": Nmaxeval, "adaptive": True}}),
        ("Scipy DA", dual_annealing, {"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False, "x0": x0[0]}),
    ]

    for name, func_opt, kwargs in scipy_algorithms:
        res = func_opt(func_scipy, **kwargs)
        result[name] = res.fun
        print(f"  {name:<15} f(x): {res.fun:<20.8g}")

    with results_lock:
        results.append(result)

    print("-" * 60)

def run_test_optimization(j, dim, year=2017, seed=None):
    """Runs the optimization for a specific function and CEC benchmark year."""
    cec_func_classes = {
        2011 : mpy.CEC2011Functions,
        2014: mpy.CEC2014Functions,
        2017: mpy.CEC2017Functions,
        2019: mpy.CEC2019Functions,
        2020: mpy.CEC2020Functions,
        2022: mpy.CEC2022Functions
    }

    if year not in cec_func_classes:
        raise Exception("Unknown CEC year.")

    cec_func = cec_func_classes[year](function_number=j, dimension=dim)
    bounds = [(-100, 100)] * dimension
    if year == 2011 :
        bounds = cec_func.get_bounds()
    test_optimization(cec_func,bounds,  dim, f"func_{j}", Nmaxeval, seed)

# List of algorithms to be tested
algos = [
      "DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP", "IMODE", "AGSK",
        "ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES", "RCMAES"
]

Nmaxeval = 10000  # Maximum number of function evaluations
dimension = 20
NRuns = 1  # Number of repetitions
year = 2022  # CEC benchmark year

# Function numbers for each CEC year
func_numbers_dict = {
    2022: list(range(1, 13)),
    2020: list(range(1, 11)),
    2019: list(range(1, 11)),
    2017: list(range(1, 31)),
    2014: list(range(1, 31)),
    2011 : list(range(1, 23))
}
func_numbers = func_numbers_dict[year]

# Run optimizations using multi-threading
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
    futures = [
        executor.submit(run_test_optimization, j, dimension, year, k)
        for k in range(NRuns)
        for j in func_numbers
    ]
    concurrent.futures.wait(futures)

    for f in futures:
        f.result()



Running optimization for func_1 (Dimension: 20)
============================================================
  DE              f(x): 5085.5257
  ABC             f(x): 44222.213
  LSHADE          f(x): 1088.4817
  LSHADE_cnEpSin  f(x): 393.81561
  JADE            f(x): 1639.1365
  jSO             f(x): 663.08019
  j2020           f(x): 18723.773
  LSRTDE          f(x): 807.35554
  NLSHADE_RSP     f(x): 10900.921
  IMODE           f(x): 35558.207
  AGSK            f(x): 21380.317
  ARRDE           f(x): 347.58412
  GWO_DE          f(x): 10862.459
  NelderMead      f(x): 2325.3118
  DA              f(x): 300
  L_BFGS_B        f(x): 300
  PSO             f(x): 2983.2594
  DMSPSO          f(x): 5558.866
  SPSO2011        f(x): 27812.642
  CMAES           f(x): 300.00821
  BIPOP_aCMAES    f(x): 300
  RCMAES          f(x): 300.01891
  Scipy L-BFGS-B  f(x): 300.00003
  Scipy Nelder-Mead f(x): 14246.918
  Scipy DA        f(x): 300.00008
------------------------------------------------------------

Running optimization for func_2 (Dimension: 20)
============================================================
  DE              f(x): 480.94136
  ABC             f(x): 547.98553
  LSHADE          f(x): 449.38307
  LSHADE_cnEpSin  f(x): 449.12225
  JADE            f(x): 449.10799
  jSO             f(x): 449.25107
  j2020           f(x): 474.63626
  LSRTDE          f(x): 446.6905
  NLSHADE_RSP     f(x): 477.163
  IMODE           f(x): 1143.2173
  AGSK            f(x): 459.71648
  ARRDE           f(x): 449.08483
  GWO_DE          f(x): 466.5408
  NelderMead      f(x): 450.55737
  DA              f(x): 449.08448
  L_BFGS_B        f(x): 449.08448
  PSO             f(x): 528.23266
  DMSPSO          f(x): 449.08486
  SPSO2011        f(x): 472.80406
  CMAES           f(x): 449.0982
  BIPOP_aCMAES    f(x): 445.78458
  RCMAES          f(x): 449.46406
  Scipy L-BFGS-B  f(x): 449.08448
  Scipy Nelder-Mead f(x): 888.69774
  Scipy DA        f(x): 449.08448
------------------------------------------------------------

Running optimization for func_3 (Dimension: 20)
============================================================
  DE              f(x): 605.26772
  ABC             f(x): 627.07364
  LSHADE          f(x): 603.07316
  LSHADE_cnEpSin  f(x): 601.38124
  JADE            f(x): 600.01872
  jSO             f(x): 601.49659
  j2020           f(x): 600.25933
  LSRTDE          f(x): 602.03484
  NLSHADE_RSP     f(x): 605.87478
  IMODE           f(x): 637.59573
  AGSK            f(x): 632.95622
  ARRDE           f(x): 600.02385
  GWO_DE          f(x): 601.76909
  NelderMead      f(x): 668.5376
  DA              f(x): 625.11935
  L_BFGS_B        f(x): 668.5255
  PSO             f(x): 609.19358
  DMSPSO          f(x): 600.04564
  SPSO2011        f(x): 602.3647
  CMAES           f(x): 600.00001
  BIPOP_aCMAES    f(x): 600.12058
  RCMAES          f(x): 600.00064
  Scipy L-BFGS-B  f(x): 668.52549
  Scipy Nelder-Mead f(x): 675.70408
  Scipy DA        f(x): 616.39695
------------------------------------------------------------

Running optimization for func_4 (Dimension: 20)
============================================================
  DE              f(x): 817.15029
  ABC             f(x): 944.69928
  LSHADE          f(x): 875.84062
  LSHADE_cnEpSin  f(x): 875.65484
  JADE            f(x): 848.52088
  jSO             f(x): 898.90865
  j2020           f(x): 933.90753
  LSRTDE          f(x): 889.72233
  NLSHADE_RSP     f(x): 867.09167
  IMODE           f(x): 860.69252
  AGSK            f(x): 927.31042
  ARRDE           f(x): 836.40883
  GWO_DE          f(x): 894.76464
  NelderMead      f(x): 890.54093
  DA              f(x): 923.37427
  L_BFGS_B        f(x): 890.54093
  PSO             f(x): 854.72293
  DMSPSO          f(x): 832.83492
  SPSO2011        f(x): 881.2455
  CMAES           f(x): 821.89128
  BIPOP_aCMAES    f(x): 837.80837
  RCMAES          f(x): 807.95979
  Scipy L-BFGS-B  f(x): 890.54093
  Scipy Nelder-Mead f(x): 905.87623
  Scipy DA        f(x): 890.54093
------------------------------------------------------------

Running optimization for func_5 (Dimension: 20)
============================================================
  DE              f(x): 1202.7482
  ABC             f(x): 2949.1588
  LSHADE          f(x): 916.96704
  LSHADE_cnEpSin  f(x): 903.00592
  JADE            f(x): 901.03453
  jSO             f(x): 901.51869
  j2020           f(x): 973.51848
  LSRTDE          f(x): 902.4021
  NLSHADE_RSP     f(x): 1071.9947
  IMODE           f(x): 3699.1048
  AGSK            f(x): 1290.3339
  ARRDE           f(x): 900.90882
  GWO_DE          f(x): 911.69531
  NelderMead      f(x): 2456.1107
  DA              f(x): 3049.2139
  L_BFGS_B        f(x): 2458.8607
  PSO             f(x): 964.26555
  DMSPSO          f(x): 900.08958
  SPSO2011        f(x): 901.73755
  CMAES           f(x): 900
  BIPOP_aCMAES    f(x): 900.08953
  RCMAES          f(x): 900
  Scipy L-BFGS-B  f(x): 2458.8608
  Scipy Nelder-Mead f(x): 2466.2063
  Scipy DA        f(x): 2436.8814
------------------------------------------------------------

Running optimization for func_6 (Dimension: 20)
============================================================
  DE              f(x): 2001.4795
  ABC             f(x): 79695.375
  LSHADE          f(x): 2930.9272
  LSHADE_cnEpSin  f(x): 3601.2958
  JADE            f(x): 5712.6806
  jSO             f(x): 3003.1556
  j2020           f(x): 2782211.5
  LSRTDE          f(x): 1943.0639
  NLSHADE_RSP     f(x): 2650.1729
  IMODE           f(x): 1.4668535e+08
  AGSK            f(x): 458339.03
  ARRDE           f(x): 2001.3007
  GWO_DE          f(x): 92569.529
  NelderMead      f(x): 1930.6357
  DA              f(x): 1902.3229
  L_BFGS_B        f(x): 1875.3024
  PSO             f(x): 2217.6482
  DMSPSO          f(x): 7137.3758
  SPSO2011        f(x): 451270.38
  CMAES           f(x): 2447.3192
  BIPOP_aCMAES    f(x): 1974.8113
  RCMAES          f(x): 1946.785
  Scipy L-BFGS-B  f(x): 1872.5982
  Scipy Nelder-Mead f(x): 2054.1894
  Scipy DA        f(x): 1825.5024
------------------------------------------------------------

Running optimization for func_7 (Dimension: 20)
============================================================
  DE              f(x): 2024.1839
  ABC             f(x): 2187.1636
  LSHADE          f(x): 2088.4042
  LSHADE_cnEpSin  f(x): 2089.2345
  JADE            f(x): 2039.5176
  jSO             f(x): 2093.4964
  j2020           f(x): 2088.2756
  LSRTDE          f(x): 2034.4739
  NLSHADE_RSP     f(x): 2040.5639
  IMODE           f(x): 2190.9346
  AGSK            f(x): 2111.774
  ARRDE           f(x): 2031.68
  GWO_DE          f(x): 2079.8137
  NelderMead      f(x): 2546.5845
  DA              f(x): 2182.4238
  L_BFGS_B        f(x): 2528.594
  PSO             f(x): 2138.6779
  DMSPSO          f(x): 2046.9619
  SPSO2011        f(x): 2126.0449
  CMAES           f(x): 2050.9847
  BIPOP_aCMAES    f(x): 2078.1172
  RCMAES          f(x): 2024.0517
  Scipy L-BFGS-B  f(x): 2595.2809
  Scipy Nelder-Mead f(x): 2617.3528
  Scipy DA        f(x): 2173.5444
------------------------------------------------------------

Running optimization for func_8 (Dimension: 20)
============================================================
  DE              f(x): 2353.9212
  ABC             f(x): 2224.9259
  LSHADE          f(x): 2238.7499
  LSHADE_cnEpSin  f(x): 2230.5309
  JADE            f(x): 2227.1813
  jSO             f(x): 2236.8952
  j2020           f(x): 2237.586
  LSRTDE          f(x): 2229.7068
  NLSHADE_RSP     f(x): 2230.1174
  IMODE           f(x): 2277.3083
  AGSK            f(x): 2240.1263
  ARRDE           f(x): 2232.3614
  GWO_DE          f(x): 2239.9511
  NelderMead      f(x): 2636.9036
  DA              f(x): 2362.1594
  L_BFGS_B        f(x): 2961.2445
  PSO             f(x): 2357.6243
  DMSPSO          f(x): 2232.1705
  SPSO2011        f(x): 2248.0455
  CMAES           f(x): 2353.5708
  BIPOP_aCMAES    f(x): 2344.7665
  RCMAES          f(x): 2231.7355
  Scipy L-BFGS-B  f(x): 2903.5382
  Scipy Nelder-Mead f(x): 2890.3671
  Scipy DA        f(x): 2348.557
------------------------------------------------------------

Running optimization for func_9 (Dimension: 20)
============================================================
  DE              f(x): 2528.1743
  ABC             f(x): 2511.816
  LSHADE          f(x): 2480.9607
  LSHADE_cnEpSin  f(x): 2480.867
  JADE            f(x): 2480.7815
  jSO             f(x): 2480.8175
  j2020           f(x): 2480.9503
  LSRTDE          f(x): 2481.9435
  NLSHADE_RSP     f(x): 2486.9747
  IMODE           f(x): 2503.6158
  AGSK            f(x): 2481.5201
  ARRDE           f(x): 2480.7815
  GWO_DE          f(x): 2481.4462
  NelderMead      f(x): 2522.4987
  DA              f(x): 2480.7813
  L_BFGS_B        f(x): 2480.7813
  PSO             f(x): 2480.782
  DMSPSO          f(x): 2480.7816
  SPSO2011        f(x): 2498.2139
  CMAES           f(x): 2480.801
  BIPOP_aCMAES    f(x): 2481.4449
  RCMAES          f(x): 2484.9445
  Scipy L-BFGS-B  f(x): 2480.7813
  Scipy Nelder-Mead f(x): 2651.3649
  Scipy DA        f(x): 2480.7813
------------------------------------------------------------

Running optimization for func_10 (Dimension: 20)
============================================================
  DE              f(x): 2500.974
  ABC             f(x): 2613.9834
  LSHADE          f(x): 2500.9714
  LSHADE_cnEpSin  f(x): 2500.82
  JADE            f(x): 2500.5708
  jSO             f(x): 2500.8611
  j2020           f(x): 2501.052
  LSRTDE          f(x): 2500.8716
  NLSHADE_RSP     f(x): 2502.1077
  IMODE           f(x): 2518.3887
  AGSK            f(x): 2501.0293
  ARRDE           f(x): 2635.7722
  GWO_DE          f(x): 2500.8651
  NelderMead      f(x): 6169.0617
  DA              f(x): 4368.065
  L_BFGS_B        f(x): 6109.5459
  PSO             f(x): 2500.8826
  DMSPSO          f(x): 2821.411
  SPSO2011        f(x): 2500.801
  CMAES           f(x): 2638.8114
  BIPOP_aCMAES    f(x): 4363.5404
  RCMAES          f(x): 2500.4804
  Scipy L-BFGS-B  f(x): 6287.3529
  Scipy Nelder-Mead f(x): 6530.8204
  Scipy DA        f(x): 2501.26
------------------------------------------------------------

Running optimization for func_11 (Dimension: 20)
============================================================
  DE              f(x): 3256.454
  ABC             f(x): 3550.2215
  LSHADE          f(x): 2944.6148
  LSHADE_cnEpSin  f(x): 2917.51
  JADE            f(x): 2900.0421
  jSO             f(x): 2912.3607
  j2020           f(x): 3716.4447
  LSRTDE          f(x): 2966.9575
  NLSHADE_RSP     f(x): 3231.9349
  IMODE           f(x): 3235.873
  AGSK            f(x): 3328.527
  ARRDE           f(x): 2900.0141
  GWO_DE          f(x): 2997.3447
  NelderMead      f(x): 3000.0006
  DA              f(x): 2900
  L_BFGS_B        f(x): 2900
  PSO             f(x): 2900.0768
  DMSPSO          f(x): 3000.4364
  SPSO2011        f(x): 2908.4908
  CMAES           f(x): 2900
  BIPOP_aCMAES    f(x): 2900
  RCMAES          f(x): 2900.002
  Scipy L-BFGS-B  f(x): 2900
  Scipy Nelder-Mead f(x): 5999.3357
  Scipy DA        f(x): 2900
------------------------------------------------------------

Running optimization for func_12 (Dimension: 20)
============================================================
  DE              f(x): 2972.9413
  ABC             f(x): 3030.895
  LSHADE          f(x): 2946.2603
  LSHADE_cnEpSin  f(x): 2950.3474
  JADE            f(x): 2941.3209
  jSO             f(x): 2951.2821
  j2020           f(x): 2962.7803
  LSRTDE          f(x): 2967.9779
  NLSHADE_RSP     f(x): 3021.4467
  IMODE           f(x): 3235.7416
  AGSK            f(x): 2960.6791
  ARRDE           f(x): 2933.0833
  GWO_DE          f(x): 2957.3298
  NelderMead      f(x): 5490.2128
  DA              f(x): 3025.7172
  L_BFGS_B        f(x): 5490.213
  PSO             f(x): 3014.8504
  DMSPSO          f(x): 2965.1288
  SPSO2011        f(x): 2973.7025
  CMAES           f(x): 2984.5286
  BIPOP_aCMAES    f(x): 2991.2327
  RCMAES          f(x): 3073.6232
  Scipy L-BFGS-B  f(x): 3344.4993
  Scipy Nelder-Mead f(x): 6393.643
  Scipy DA        f(x): 2963.9672
------------------------------------------------------------

Example of using minion/py in curve fitting problems

Here, an example of using minion to minimize an objective function related to a curve fitting problem is demonstrated. The idea is first to define the data generation model, generate the data, fit the model, and report the result.

Polynomial Fitting Problems

In this problem, we try fit a polynomial from a set of data. Specifically, a set of points (\(\{(x_i, y_i) \mid i = 1, 2, \dots, N\}\)) with \(x \in [0, 1]\) is generated according to:

\[f(x, a) = \sum_{j=0}^{D-1} a_j x^j\]

Given the coefficients \(a_j\) that generate the data, the goal is to reproduce the data points by minimizing the objective function:

\[L = \frac{1}{N}\sum_{i=1}^N \left(y_i - f(x_i, a)\right)^2\]
[15]:
# Step 1: Generate Data Points from a Polynomial
dimension = 10  # Number of free parameters (polynomial degree is dimension - 1)
np.random.seed(8)  # For reproducibility

# True polynomial coefficients (random values)
true_coefficients = [np.random.uniform(-1.0, 1.0) * (1.0 ** i) for i in range(dimension)]

# Generate data points
x_data = np.linspace(0.0, 1, dimension + 10)
y_data = np.polyval(true_coefficients, x_data)

# Step 2: Define the Polynomial Model
def polynomial_model(x, coefficients):
    """Evaluate a polynomial at x given the coefficients."""
    return np.polyval(coefficients, x)

# Step 3: Define the Objective Function
def objective_function(coefficients):
    """Compute the mean squared error between the polynomial model and data points."""
    y_pred = polynomial_model(x_data, coefficients)
    return np.mean((y_data - y_pred) ** 2)

def objective_function_vect(X):
    """Vectorized version of the objective function for batch optimization."""
    return [objective_function(x) for x in X]

# Optimization Settings
bounds = [(-10, 10)] * dimension
Nmaxeval = 20000
algos = [
      "DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
        "ARRDE", "GWO_DE",  "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES", "RCMAES"
]

# Step 4: Minimize the Objective Function and Plot Results
plt.figure(figsize=(6, 4))
plt.scatter(x_data, y_data, label="Data Points", color="black", marker="o", zorder=3)

x0 = [[0.0 for _ in range(dimension)]]

print("\nOptimization Results:")
print("=" * 50)

# Run Optimization with Custom Algorithms
for algo in algos:
    res = mpy.Minimizer(
        objective_function_vect, bounds, x0=x0,
        algo=algo, maxevals=Nmaxeval, callback=None, seed=0,
        options={
            "population_size": 0,
            "func_noise_ratio"  :  0.0,
            "N_points_derivative": 1,
            "convergence_tol" : 0.0}
    ).optimize()

    print(f"{algo:<30}: f(x) = {res.fun:<20.8g}")
    plt.plot(x_data, polynomial_model(x_data, res.x), label=algo, linewidth=1.2, alpha=0.7)

# Run SciPy Optimizers
scipy_algorithms = [
    ("Scipy Dual Annealing (DA)", dual_annealing, {"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False, "x0": x0[0]}),
    ("Scipy L-BFGS-B", minimize, {"x0": x0[0], "bounds": bounds, "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}}),
    ("Scipy Nelder-Mead", minimize, {"x0": x0[0], "bounds": bounds, "method": "Nelder-Mead", "options": {"maxfev": Nmaxeval, "adaptive": True}}),
]

for name, func_opt, kwargs in scipy_algorithms:
    res = func_opt(objective_function, **kwargs)
    print(f"{name:<30}: f(x) = {res.fun:<20.8g}")
    plt.plot(x_data, polynomial_model(x_data, res.x), label=name, linewidth=1.2, alpha=0.7)

print("=" * 50)

# Plot Formatting
plt.legend(loc="upper left", bbox_to_anchor=(1, 1), fontsize=9)
plt.title("Polynomial Fit")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True, linestyle="--", alpha=0.6)
plt.show()



Optimization Results:
==================================================
DE                            : f(x) = 1.4440892e-08
ABC                           : f(x) = 0.0056994221
LSHADE                        : f(x) = 1.4887049e-12
LSHADE_cnEpSin                : f(x) = 2.2760653e-16
JADE                          : f(x) = 2.8549496e-09
jSO                           : f(x) = 5.4336223e-13
j2020                         : f(x) = 8.4535903e-05
LSRTDE                        : f(x) = 5.1056681e-15
NLSHADE_RSP                   : f(x) = 1.0850745e-06
ARRDE                         : f(x) = 1.2473721e-12
GWO_DE                        : f(x) = 1.2315456e-05
NelderMead                    : f(x) = 4.0539659e-15
DA                            : f(x) = 2.5733361e-05
L_BFGS_B                      : f(x) = 7.3320324e-07
PSO                           : f(x) = 3.5313431e-05
DMSPSO                        : f(x) = 2.6368825e-05
SPSO2011                      : f(x) = 0.00054992829
CMAES                         : f(x) = 8.5261952e-12
BIPOP_aCMAES                  : f(x) = 2.1084646e-22
RCMAES                        : f(x) = 1.150172e-13
Scipy Dual Annealing (DA)     : f(x) = 7.3247663e-07
Scipy L-BFGS-B                : f(x) = 7.3247663e-07
Scipy Nelder-Mead             : f(x) = 2.1676521e-11
==================================================
../_images/minionpy_minimizer_30_1.png

Gaussian Mixture Model Fitting Problems

Thsi time, the model is given by the sum of Gaussian functions:

\[f(x, a, b, c) = \sum_{j=1}^{D/3} \frac{a_j}{\sum_{k=1}^{D/3} a_k} \frac{1}{b_j \sqrt{2\pi}} \exp\left[-\frac{1}{2} \frac{(x-c_j)^2}{b_j^2}\right]\]

Here, \(f(x, a, b, c)\) is normalized to represent a probability distribution. The data points are generated using predefined values of \(a_j\), \(b_j\), and \(c_j\) within the interval \(x \in [-20, 20]\). The objective function is the same as in the case of polynomial fitting.

[16]:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, dual_annealing
import concurrent.futures

# Step 1: Generate Data Points from a Gaussian Mixture Model (GMM)
np.random.seed(5)  # For reproducibility

num_gauss = 5  # Number of Gaussians
true_centers = 10 * (-1 + 2 * np.random.random(num_gauss))  # Random center positions
true_widths = np.random.rand(num_gauss) + 1.0  # Widths (variances)
true_coeffs = 2.0 * np.random.rand(num_gauss)  # Coefficients

dimension = num_gauss * 3  # Total number of free parameters

# Define a Gaussian function
def gauss(x, center, width):
    """Compute a Gaussian value at x given center and width."""
    return (1.0 / (2.0 * np.pi * width ** 2)) * 0.5 * np.exp(-((x - center) ** 2) / (2 * width ** 2))

# Define the Gaussian Mixture Model (GMM)
def gmm(x, centers, widths, coeffs):
    """Evaluate the Gaussian Mixture Model (GMM) at x."""
    result = np.zeros_like(x)
    coeffs = np.array(coeffs)
    norm_coeff = coeffs / np.sum(coeffs)  # Normalize coefficients
    for i in range(len(centers)):
        result += norm_coeff[i] * gauss(x, centers[i], widths[i])
    return result

# Generate synthetic data
x_data = np.linspace(-20, 20, dimension + 10)
y_data = gmm(x_data, true_centers, true_widths, true_coeffs)

# Step 2: Define the Model for Fitting
def gmm_model(x, params):
    """Compute GMM model values for given parameters."""
    num_gauss = len(params) // 3
    centers = params[:num_gauss]
    widths = params[num_gauss:2*num_gauss]
    coeffs = params[2*num_gauss:]
    return gmm(x, centers, widths, coeffs)

# Step 3: Define the Objective Function
def objective_function(params):
    """Compute the mean squared error between model and data."""
    y_pred = gmm_model(x_data, params)
    return np.mean((y_data - y_pred) ** 2)

# Parallelized objective function
executor = concurrent.futures.ThreadPoolExecutor(max_workers=8)

def objective_function_vect(params):
    """Vectorized version of objective function using multithreading."""
    return list(executor.map(objective_function, params))

# Optimization Settings
bounds = [(-10, 10)] * dimension
Nmaxeval = 10000
algos = [
    "DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
        "ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]

x0 = [[1.0 for _ in range(dimension)]]

# Step 4: Minimize the Objective Function and Plot Results
plt.figure(figsize=(6, 4))
plt.scatter(x_data, y_data, label="Data", color="black", marker="o", zorder=3)

print("\nOptimization Results:")
print("=" * 60)

# Run Optimization with Custom Algorithms
for algo in algos:
    res = mpy.Minimizer(
        objective_function_vect, bounds, x0=x0,
        algo=algo, maxevals=Nmaxeval, callback=None, seed=None,
        options={"population_size": 0, "convergence_tol": 0.0}
    ).optimize()

    print(f"{algo:<30}: f(x) = {res.fun:<20.8g}")
    plt.plot(x_data, gmm_model(x_data, res.x), label=algo, linewidth=1.2, alpha=0.7)

# Run SciPy Optimizers
scipy_algorithms = [
    ("Scipy L-BFGS-B", minimize, {"x0": x0[0], "bounds": bounds, "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}}),
    ("Scipy Dual Annealing", dual_annealing, {"x0": x0[0],"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False}),
    ("Scipy Nelder-Mead", minimize, {"x0": x0[0],  "bounds": bounds,"method": "Nelder-Mead", "options": {"maxfev": Nmaxeval, "adaptive": True}}),
]

for name, func_opt, kwargs in scipy_algorithms:
    res = func_opt(objective_function, **kwargs)
    print(f"{name:<30}: f(x) = {res.fun:<20.8g}")
    plt.plot(x_data, gmm_model(x_data, res.x), label=name, linewidth=1.2, alpha=0.7)

print("=" * 60)

# Plot Formatting
plt.legend(loc="upper left", bbox_to_anchor=(1, 1), fontsize=9)
plt.title("Gaussian Mixture Model Fit")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True, linestyle="--", alpha=0.6)
plt.show()

executor.shutdown()



Optimization Results:
============================================================
DE                            : f(x) = 4.3643422e-08
ABC                           : f(x) = 7.8145767e-07
LSHADE                        : f(x) = 8.3456067e-07
LSHADE_cnEpSin                : f(x) = 1.4529575e-06
JADE                          : f(x) = 2.4388061e-07
jSO                           : f(x) = 3.025535e-06
j2020                         : f(x) = 6.0027859e-07
LSRTDE                        : f(x) = 4.5803423e-06
NLSHADE_RSP                   : f(x) = 4.3805794e-07
ARRDE                         : f(x) = 4.433319e-09
GWO_DE                        : f(x) = 5.7814618e-08
NelderMead                    : f(x) = 7.3549528e-09
DA                            : f(x) = 1.2573343e-05
L_BFGS_B                      : f(x) = 2.5552938e-05
PSO                           : f(x) = 4.5127993e-09
DMSPSO                        : f(x) = 8.2520556e-09
SPSO2011                      : f(x) = 3.2138426e-06
CMAES                         : f(x) = 6.716247e-09
BIPOP_aCMAES                  : f(x) = 7.4143992e-11
Scipy L-BFGS-B                : f(x) = 2.4099675e-05
Scipy Dual Annealing          : f(x) = 6.1466923e-06
Scipy Nelder-Mead             : f(x) = 4.1184114e-09
============================================================
../_images/minionpy_minimizer_32_1.png

More complex fitting problem: CT18 PDFs Fitting

Here, we provide a slightly more challenging curve fitting problem. The task is to reproduce the CT18 parton distribution functions (PDFs) \cite{Hou:2019efy}. The parameterization for valence up-quark (\(u_v\)), valence down-quark (\(d_v\)), gluon, anti-\(u\) (\(\bar{u}\)), anti-\(d\) (\(\bar{d}\)), and strange quark (\(s\)) PDFs at the initial scale is given by:

\[f_i(x) = a_0 x^{a_1-1} (1-x)^{a_2} P_i(y, a_3, a_4, \dots), \quad i \in \{u_v, d_v, g, \bar{u}, \bar{d}, s\}\]

Here, \(P_i(y)\) is a Bernstein polynomial of degree 4, 3, or 5, depending on the specific PDF. The variable \(y\) is defined as \(y = \sqrt{x}\) for \(u_v\), \(d_v\), and \(g\), and as \(y = (1 - (1 - \sqrt{x}))^{a_3}\) for the sea quarks. The objective function is:

\[L = \sum_i \frac{1}{N} \sum_{j=1}^N \left(y_j - f_i(x_j)\right)^2\]

where \(i \in \{u_v, d_v, g, \bar{u}, \bar{d}, s\}\). The dimensionality of this problem is \(D = 47\).

[17]:
class CT18PDFs :
    def __init__(self) :
        self.parameters = {
            "uv_0" : 3.385, "uv_1" : 0.763, "uv_2" : 3.036, "uv_3" : 1.502, "uv_4" : -0.147,"uv_5" : 1.671, "uv_6" : 0.,
            "dv_0" : 0.490, "dv_1" : 0.763, "dv_2" : 3.036, "dv_3" : 2.615, "dv_4" : 1.828,"dv_5" : 2.721, "dv_6" : 0.,
            "g_0" : 2.690, "g_1" : 0.531, "g_2" : 3.148, "g_3" : 3.032, "g_4" : -1.705, "g_5" : 1.354,
            "ubar_0" : 0.414, "ubar_1" : -0.022, "ubar_2" : 7.737, "ubar_3" : 4.0, "ubar_4" : 0.618,"ubar_5" : 0.195, "ubar_6" : 0.871, "ubar_7" : 0.267,"ubar_8" : 0.733,
            "dbar_0" : 0.414, "dbar_1" : -0.022, "dbar_2" : 7.737, "dbar_3" : 4.0, "dbar_4" : 0.292,"dbar_5" : 0.647, "dbar_6" : 0.474, "dbar_7" : 0.741,"dbar_8" :1.0,
            "s_0" : 0.288, "s_1" : -0.022, "s_2" : 10.31, "s_3" : 4.0, "s_4" : 0.466,"s_5" : 0.466, "s_6" : 0.225, "s_7" : 0.225,"s_8" : 1.0,
        }
        self.xlist = np.linspace(1e-3, 0.8, 50)
        self.paramNames = list(self.parameters.keys())
        self.originalData = self.getData()

    def uv(self, x) :
        a0 = self.parameters["uv_0"]
        a1 = self.parameters["uv_1"]
        a2 = self.parameters["uv_2"]
        a3 = self.parameters["uv_3"]
        a4 = self.parameters["uv_4"]
        a5 = self.parameters["uv_5"]
        a6 = self.parameters["uv_6"]
        y= np.sqrt(x)
        P = np.sinh(a3)*(1-y)**4 + np.sinh(a4) *4*y*(1-y)**3 + np.sinh(a5) *6*y**2*(1-y)**2 + np.sinh(a6) *4*y**3*(1-y) + y**4
        return a0 * x**(a1-1)*(1-x)**a2*P

    def dv(self, x) :
        a0 = self.parameters["dv_0"]
        a1 = self.parameters["dv_1"]
        a2 = self.parameters["dv_2"]
        a3 = self.parameters["dv_3"]
        a4 = self.parameters["dv_4"]
        a5 = self.parameters["dv_5"]
        a6 = self.parameters["dv_6"]
        y= np.sqrt(x)
        P = np.sinh(a3)*(1-y)**4 + np.sinh(a4) *4*y*(1-y)**3 + np.sinh(a5) *6*y**2*(1-y)**2 + np.sinh(a6) *4*y**3*(1-y) + y**4
        return a0 * x**(a1-1)*(1-x)**a2*P

    def g(self, x) :
        a0 = self.parameters["g_0"]
        a1 = self.parameters["g_1"]
        a2 = self.parameters["g_2"]
        a3 = self.parameters["g_3"]
        a4 = self.parameters["g_4"]
        a5 = self.parameters["g_5"]
        y= np.sqrt(x)
        P = np.sinh(a3)*(1-y)**3 + np.sinh(a4) *3*y*(1-y)**2 + np.sinh(a5) *3*y**2*(1-y)  + y**3
        return a0 * x**(a1-1)*(1-x)**a2*P

    def ubar(self, x) :
        a0 = self.parameters["ubar_0"]
        a1 = self.parameters["ubar_1"]
        a2 = self.parameters["ubar_2"]
        a3 = self.parameters["ubar_3"]
        a4 = self.parameters["ubar_4"]
        a5 = self.parameters["ubar_5"]
        a6 = self.parameters["ubar_6"]
        a7 = self.parameters["ubar_7"]
        a8 = self.parameters["ubar_8"]
        y= 1-(1-np.sqrt(x))**a3
        P = (1-y)**5 + a4 * 5*y*(1-y)**4 + a5 * 10*y**2*(1-y)**3 +  a6 * 10*y**3*(1-y)**2 +  a7 * 5*y**4*(1-y)+  a8 * 5*y**5
        return a0 * x**(a1-1)*(1-x)**a2*P

    def dbar(self, x) :
        a0 = self.parameters["dbar_0"]
        a1 = self.parameters["dbar_1"]
        a2 = self.parameters["dbar_2"]
        a3 = self.parameters["dbar_3"]
        a4 = self.parameters["dbar_4"]
        a5 = self.parameters["dbar_5"]
        a6 = self.parameters["dbar_6"]
        a7 = self.parameters["dbar_7"]
        a8 = self.parameters["dbar_8"]
        y= 1-(1-np.sqrt(x))**a3
        P = (1-y)**5 + a4 * 5*y*(1-y)**4 + a5 * 10*y**2*(1-y)**3 +  a6 * 10*y**3*(1-y)**2 +  a7 * 5*y**4*(1-y)+  a8 * 5*y**5
        return a0 * x**(a1-1)*(1-x)**a2*P

    def s(self, x) :
        a0 = self.parameters["s_0"]
        a1 = self.parameters["s_1"]
        a2 = self.parameters["s_2"]
        a3 = self.parameters["s_3"]
        a4 = self.parameters["s_4"]
        a5 = self.parameters["s_5"]
        a6 = self.parameters["s_6"]
        a7 = self.parameters["s_7"]
        a8 = self.parameters["s_8"]
        y= 1-(1-np.sqrt(x))**a3
        P = (1-y)**5 + a4 * 5*y*(1-y)**4 + a5 * 10*y**2*(1-y)**3 +  a6 * 10*y**3*(1-y)**2 +  a7 * 5*y**4*(1-y)+  a8 * 5*y**5
        return a0 * x**(a1-1)*(1-x)**a2*P

    def u(self, x) : return self.uv(x)+self.ubar(x)
    def d(self, x) : return self.dv(x)+self.dbar(x)

    def setParameter(self, pars) :
        assert(len(pars)==len(self.parameters))
        self.parameters= dict(zip(self.paramNames, pars))

    def getData(self) :
        x= self.xlist
        return [ x*self.u(self.xlist), x*self.ubar(self.xlist), x*self.d(self.xlist), x*self.dbar(self.xlist), x*self.g(self.xlist), x*self.s(self.xlist)]

    def objective_function(self, params):
        self.setParameter(params)
        data = self.getData()
        ret =0
        for do, d in zip(self.originalData, data) :
            ret = ret + np.sum((do-d)**2)
        return ret
[18]:
ct18 = CT18PDFs()
data = ct18.getData()
# Create a 3x2 grid of subplots
fig, axes = plt.subplots(2, 3, figsize=(10, 5))

# List of labels for each plot
labels = ["u", "ubar", "d", "dbar", "g", "s"]

# Plotting each function in its corresponding subplot
for i, ax in enumerate(axes.flatten()):
    ax.plot(ct18.xlist, data[i], label=labels[i])
    ax.set_xlim(0.1, 0.8)
    ax.set_xlabel("x")
    if (i%3 == 0):
        ax.set_ylabel(r"$xf(x)$")
    ax.legend()
plt.subplots_adjust(hspace=0.15, wspace=0.17)
plt.show()

../_images/minionpy_minimizer_35_0.png
[19]:
# Step 1: Define Problem Dimensions and Settings
dimension = 47
print("Dimension:", dimension)

bounds = [(-10, 10)] * dimension
Nmaxeval = 100000
x0 = [[1.0] * dimension]  # Initial guess

# Step 2: Set Up Parallel Execution for CT18PDFs
t_parallel = mpy.Thread_Parallel(4, CT18PDFs)  # Vectorize using 4 threads

# Step 3: Define Optimization Algorithms
algos = [
   "DE", "ABC", "LSHADE", "LSHADE_cnEpSin", "JADE", "jSO", "j2020", "LSRTDE", "NLSHADE_RSP",
        "ARRDE", "GWO_DE", "NelderMead", "DA", "L_BFGS_B", "PSO", "DMSPSO", "SPSO2011", "CMAES", "BIPOP_aCMAES"
]

# Step 4: Run Optimization and Collect Results
results = {}

print("\nOptimization Results:")
print("=" * 60)

for algo in algos:
    res = mpy.Minimizer(
        t_parallel, bounds, x0=x0, algo=algo,
        maxevals=Nmaxeval, callback=None, seed=None,
        options={
            "population_size": 0,
            "func_noise_ratio"  :  0.0,
            "N_points_derivative": 1,
            "convergence_tol" : 0.0
        }
    ).optimize()

    print(f"{algo:<30}: f(x) = {res.fun:<20.8g}")
    results[algo] = res

# Step 5: Run SciPy Optimizers
scipy_algorithms = [
    ("Scipy L-BFGS-B", minimize, {"x0": x0[0], "bounds": bounds, "method": "L-BFGS-B", "options": {"maxfun": Nmaxeval}}),
    ("Scipy Dual Annealing", dual_annealing, {"x0": x0[0],"bounds": bounds, "maxfun": Nmaxeval, "no_local_search": False}),
    ("Scipy Nelder-Mead", minimize, {"x0": x0[0],  "bounds": bounds,"method": "Nelder-Mead", "options": {"maxfev": Nmaxeval, "adaptive": True}}),
]

for name, func_opt, kwargs in scipy_algorithms:
    res = func_opt(ct18.objective_function, **kwargs)
    print(f"{name:<30}: f(x) = {res.fun:<20.8g}")
    results[name] = res

print("=" * 60)

# Step 6: Plot Results
fig, axes = plt.subplots(2, 3, figsize=(12, 6))
labels = ["u-data", "ubar-data", "d-data", "dbar-data", "g-data", "s-data"]

# Plot each dataset in its corresponding subplot
for i, ax in enumerate(axes.flatten()):
    ax.plot(ct18.xlist, data[i], label=labels[i], color="black", linestyle="dotted", linewidth=1.2)

    # Overlay model predictions for selected algorithms
    for algo in ["ARRDE", "DA", "Scipy Dual Annealing", "L_BFGS_B"]:
        ct18.setParameter(results[algo].x)
        theo = ct18.getData()
        ax.plot(ct18.xlist, theo[i], label=algo, linewidth=1.2, alpha=0.8)

    ax.set_xlim(0.1, 0.8)
    ax.set_xlabel("x")
    if i % 3 == 0:
        ax.set_ylabel(r"$xf(x)$")
    ax.legend(fontsize=9)

plt.tight_layout()
plt.show()


Dimension: 47

Optimization Results:
============================================================
DE                            : f(x) = 0.09567722
ABC                           : f(x) = 13.802409
LSHADE                        : f(x) = 0.77263411
LSHADE_cnEpSin                : f(x) = 0.82627114
JADE                          : f(x) = 2.6116883
jSO                           : f(x) = 0.031029586
j2020                         : f(x) = 6.6513568
LSRTDE                        : f(x) = 0.97951373
NLSHADE_RSP                   : f(x) = 0.48241609
ARRDE                         : f(x) = 0.087737629
GWO_DE                        : f(x) = 2.2650603
NelderMead                    : f(x) = 0.072777402
DA                            : f(x) = 1.2922966
L_BFGS_B                      : f(x) = 0.015659395
PSO                           : f(x) = 0.23069079
DMSPSO                        : f(x) = 0.080728862
SPSO2011                      : f(x) = 3.3587771
CMAES                         : f(x) = 1.0264104
BIPOP_aCMAES                  : f(x) = 0.3277669
Scipy L-BFGS-B                : f(x) = 0.016101053
Scipy Dual Annealing          : f(x) = 0.98322231
Scipy Nelder-Mead             : f(x) = 0.072777402
============================================================
../_images/minionpy_minimizer_36_1.png
[ ]:

[ ]: