# Benchmark algorithms using the uncoupled Rosenbrock problem ```python '''Benchmark algorithms using the uncoupled Rosenbrock problem''' import numpy as np from modopt import ProblemLite, optimize from modopt.postprocessing import load_variables import time import contextlib import io import matplotlib.pyplot as plt def obj(x): nx = len(x) f = 0 if nx % 2 != 0: raise ValueError('Number of variables must be even for uncoupled Rosenbrock function') for i in range(int(nx/2)): f += (1 - x[2*i])**2 + 100*(x[2*i + 1] - x[2*i]**2)**2 return f def grad(x): nx = len(x) g = np.zeros((nx)) if nx % 2 != 0: raise ValueError('Number of variables must be even for uncoupled Rosenbrock function') for i in range(int(nx/2)): g[[2*i, 2*i + 1]] = np.array( [-2 * (1 - x[2*i]) - 400*x[2*i]*(x[2*i + 1] - x[2*i]**2), 200 * (x[2*i + 1] - x[2*i]**2)]) return g def obj_hess(x): nx = len(x) hess = np.zeros((nx, nx)) if nx % 2 != 0: raise ValueError('Number of variables must be even for uncoupled Rosenbrock function') for i in range(int(nx/2)): hess[2*i : 2*(i+1), 2*i : 2*(i+1)] = np.array( [[2 + 800*x[2*i]**2 - 400*(x[2*i + 1] - x[2*i]**2), -400*x[2*i]], [-400*x[2*i], 200]]) return hess # Benchmarking optimization algorithms algs = ['SNOPT', 'IPOPT', 'IPOPT-2', 'PySLSQP', 'BFGS', 'LBFGSB', 'COBYLA', 'COBYQA', 'NelderMead', 'TrustConstr', 'TrustConstr-2'] performance = {} history = {} time_loop = 1 for nx2 in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2056]: nx = 2*nx2 sol = np.ones(nx) x0 = np.array([-1.2, 1] * nx2) name = f'rosenbrock(u)_{nx}d' prob = ProblemLite(x0, name=name, obj=obj, grad=grad, obj_hess=obj_hess) print('\nProblem:', prob.problem_name) print('='*50) for alg in algs: solver = alg options = {} if alg=='IPOPT-2': solver = 'IPOPT' options = {'hessian_approximation': 'exact'} elif alg=='TrustConstr-2': solver = 'TrustConstr' elif alg == 'TrustConstr': options = {'ignore_exact_hessian': True} elif alg == 'SNOPT': options = {'Verbose': False} if (alg in ['COBYLA', 'COBYQA', 'NelderMead'] and nx >= 16) or (alg == 'PySLSQP' and nx >= 128) or (alg == 'BFGS' and nx >= 256): performance[prob.problem_name, alg] = {'time': 1e6, 'success': False, 'nev': 1e6, 'objective': 1e6} continue print(f'\t{alg} \n\t------------------------') start_time = time.time() for i in range(time_loop-1): with contextlib.redirect_stdout(io.StringIO()): results = optimize(prob, solver=solver, solver_options=options, recording=False, turn_off_outputs=True) results = optimize(prob, solver=solver, solver_options=options, recording=True) opt_time = (time.time() - start_time) / time_loop success = np.allclose(results['x'], sol, atol=1e-1) nev = prob._callback_count o_evals = prob._obj_count g_evals = prob._grad_count h_evals = prob._hess_count objective = prob._compute_objective(results['x']) print('\tTime:', opt_time) print('\tSuccess:', success) print('\tEvaluations:', nev) print('\tObj evals:', o_evals) print('\tGrad evals:', g_evals) print('\tHess evals:', h_evals) print('\tOptimized vars:', results['x']) obj_hist = load_variables(f"{results['out_dir']}/record.hdf5", 'obj')['callback_obj'] history[prob.problem_name, alg] = obj_hist performance[prob.problem_name, alg] = {'time': opt_time, 'success': success, 'nev': nev, 'objective': objective} plt.figure() for alg in algs: if (alg in ['COBYLA', 'COBYQA', 'NelderMead'] and nx >= 16) or (alg == 'PySLSQP' and nx >= 128) or (alg == 'BFGS' and nx >= 256): continue y_data = history[prob.problem_name, alg] plt.semilogy(y_data, label=f"{alg} ({len(y_data)})") plt.xlabel('Evaluations') plt.ylabel('Objective') plt.title(f'{prob.problem_name} minimization') plt.legend() plt.grid() plt.savefig(f"{prob.problem_name}-objective-cb.pdf") plt.close() # Print performance print('\nPerformance') print('='*50) for key, value in performance.items(): print(f"{str(key):45}:", value) from modopt.benchmarking import plot_performance_profiles plot_performance_profiles(performance, save_figname='performance.pdf') ```