"""Repeat the following paper for `POWELL`:
    Powell, M.J., 1964.
    An efficient method for finding the minimum of a function of several variables without calculating derivatives.
    The Computer Journal, 7(2), pp.155-162.
    https://academic.oup.com/comjnl/article-abstract/7/2/155/335330
    https://docs.scipy.org/doc/scipy/reference/optimize.minimize-powell.html

    Luckily our Python code could repeat the data generated by the other Python code *well*.
    Therefore, we argue that its repeatability could be **well-documented**.
"""
import numpy as np
from scipy.optimize import minimize, Bounds

from pypop7.benchmarks.base_functions import ellipsoid, rosenbrock, rastrigin
from pypop7.optimizers.ds.powell import POWELL as Solver


if __name__ == '__main__':
    functions = [ellipsoid, rosenbrock, rastrigin]
    ndim_problem = 1000

    for f in functions:
        res = minimize(f, 4*np.ones((ndim_problem,)), method='powell',
                       bounds=Bounds(-5*np.ones((ndim_problem,)), 5*np.ones((ndim_problem,))),
                       options={'maxfev': 2e6})
        print(res)
    # ellipsoid: nfev: 20528, fun: 9.576797826010937e-26
    # rosenbrock: nfev: 817629 fun: 0.0002689337326274941
    # rastrigin: nfev: 16002 fun: 0.0

    for f in functions:
        print('*' * 7 + ' ' + f.__name__ + ' ' + '*' * 7)
        problem = {'fitness_function': f,
                   'ndim_problem': ndim_problem,
                   'lower_boundary': -5*np.ones((ndim_problem,)),
                   'upper_boundary': 5*np.ones((ndim_problem,))}
        options = {'max_function_evaluations': 2e6,
                   'fitness_threshold': 1e-10,
                   'max_runtime': 3600,  # 1 hours
                   'seed_rng': 0,
                   'x': 4*np.ones((ndim_problem,)),
                   'sigma': 0.1,
                   'verbose': 20000,
                   'saving_fitness': 20000}
        solver = Solver(problem, options)
        results = solver.optimize()
        print(results)
        # https://github.com/Evolutionary-Intelligence/pypop/blob/main/docs/repeatability/powell/_test_powell.txt
