This isn't really an answer, but I thought I'd post the (python3) code below to illustrate the point I made in the comments. ``` """ A short script for comparing Nelder-Mead and BFGS on a 'tricky' objective function. """ import matplotlib.pyplot as plt import numpy as np import sys from scipy.optimize import minimize # Read inputs from command line amplitude = float(sys.argv[1]) wavelength = float(sys.argv[2]) # Set up objective function and its derivative objective = lambda x: np.square(x) + amplitude * np.sin(x / wavelength) derivative = lambda x: 2 * x + (amplitude / wavelength) * np.cos(x / wavelength) # Set up a starting position and a large initial simplex starting_position = 100 initial_simplex_length = 10 initial_simplex = np.array([ [starting_position], [starting_position + initial_simplex_length] ]) # Minimise using NM results = {} results["Nelder-Mead"] = minimize( objective, starting_position, method="Nelder-Mead", options={ "initial_simplex": initial_simplex } ) # Minimise using BFGS results["BFGS"] = minimize( objective, starting_position, method="BFGS", jac=derivative ) # Initialise plot _, ax = plt.subplots() # Plot objective function xs = np.arange(-0.2 * starting_position, 1.2 * starting_position, 0.5 * wavelength) ax.plot(xs, objective(xs)) # Mark minima found by both methods for method, result in results.items(): ax.scatter( [np.squeeze(result.x)], [result.fun], label=method ) ax.legend() ax.set_title( f"Nelder-Mead vs BFGS on x^2 + {amplitude} sin(x / {wavelength})\n" f"with x0 = {starting_position}, initial_simplex = {np.squeeze(initial_simplex)}" ) plt.show() # Print results print(results)