The first instruction asks for maximization, whereas the later parts refer to minimization. For the literal maximization task, minimize the negative objective:
import numpy as np
from scipy import optimize as opt


def f(x):
    return 1 + np.exp(-x*x/5) * np.sin(5*x)


maximum = opt.minimize(lambda z: -f(z[0]), x0=[-1.0])
print(maximum.x[0], f(maximum.x[0]))
This gives a local maximum near , . If minimization was intended, use opt.minimize(lambda z: f(z[0]), x0=[-1.0]), which instead returns a local minimum near , . The optimizer's stopping criterion establishes local numerical convergence, not a certificate of a global optimum.
Plot the entire stated interval:
import matplotlib.pyplot as plt

x_grid = np.linspace(-4, 4, 1500)
plt.plot(x_grid, f(x_grid))
plt.xlabel("x")
plt.ylabel("f(x)")
plt.show()
The oscillating objective has several wells. A local search starting at need not reach the deepest one, which is near . For the literal maximization in part (a), no minimum was being sought at all. Under the intended minimization interpretation, the result near belongs to a different attraction region from the global minimum.
Figure 1.
Local extrema, the global minimum and the constrained minimum of the oscillatory objective
. Details.
Use reproducible random starts and retain the best successful result:
rng = np.random.default_rng(2024)
starts = rng.uniform(-4, 4, size=100)
results = [opt.minimize(lambda z: f(z[0]), x0=[x0]) for x0 in starts]
successful = [result for result in results if result.success]
best = min(successful, key=lambda result: result.fun)
print(best.x[0], best.fun)
The estimate is , . This random-restart optimization improves coverage of the different attraction regions, but their number alone does not guarantee global optimality.
Here an analytic check is possible. For , the envelope gives , above the candidate. On , . In the remaining interval , the derivative condition is equivalent, with , to . The left side decreases strictly from to while the right side increases, giving one minimum. This certifies the selected well as global rather than relying only on the restart experiment.
Set . Every finite unconstrained value of then gives an allowed point with :
def transformed(y):
    return f(1.5 + np.exp(y[0]))


result = opt.minimize(transformed, x0=[0.0])
x_interior = 1.5 + np.exp(result.x[0])
x_best = min([1.5, x_interior], key=f)
print(x_best, f(x_best))
Explicitly checking covers the boundary omitted by the exponential transformation. The minimum is , , whereas .
Constraint reparameterization enforces feasibility but does not remove nonconvexity. In this example, up to the next negative-sine lobe, the derivative has one minimum in that lobe, and for the envelope gives . Thus later oscillations cannot improve on the displayed constrained minimum.

Articles by others on the same topic (0)

There are currently no matching articles.