# Non-Convex Univariate Function Optimization

A convex function is one that does not resemble a basin, meaning that it may have more than one hill or valley.

This can make it more challenging to locate the global optima as the multiple hills and valleys can cause the search to get stuck and report a false or local optima instead.

We can define a non-convex univariate function as follows.

# objective function

def objective(x):
return (x - 2.0) * x * (x + 2.0)**2.0
We can sample this function and create a line plot of input values to objective values.

The complete example is listed below.

# plot a non-convex univariate function

from numpy import arange
from matplotlib import pyplot

# objective function

def objective(x):
return (x - 2.0) * x * (x + 2.0)**2.0

# define range

r_min, r_max = -3.0, 2.5

# prepare inputs

inputs = arange(r_min, r_max, 0.1)

# compute targets

targets = [objective(x) for x in inputs]

# plot inputs vs target

pyplot.plot(inputs, targets, ‘–’)
pyplot.show()
Running the example evaluates input values in our specified range using our target function and creates a plot of the function inputs to function outputs.

Note: in a real optimization problem, we would not be able to perform so many evaluations of the objective function so easily. This simple function is used for demonstration purposes so we can learn how to use the optimization algorithm.

Next, we can use the optimization algorithm to find the optima.

As before, we can call the minimize_scalar() function to optimize the function, then summarize the result and plot the optima on a line plot.

The complete example of optimization of an unconstrained non-convex univariate function is listed below.

# optimize non-convex objective function

from numpy import arange
from scipy.optimize import minimize_scalar
from matplotlib import pyplot

# objective function

def objective(x):
return (x - 2.0) * x * (x + 2.0)**2.0

# minimize the function

result = minimize_scalar(objective, method=‘brent’)

# summarize the result

opt_x, opt_y = result[‘x’], result[‘fun’]
print(‘Optimal Input x: %.6f’ % opt_x)
print(‘Optimal Output f(x): %.6f’ % opt_y)
print(‘Total Evaluations n: %d’ % result[‘nfev’])

# define the range

r_min, r_max = -3.0, 2.5

# prepare inputs

inputs = arange(r_min, r_max, 0.1)

# compute targets

targets = [objective(x) for x in inputs]

# plot inputs vs target

pyplot.plot(inputs, targets, ‘–’)

# plot the optima

pyplot.plot([opt_x], [opt_y], ‘s’, color=‘r’)

# show the plot

pyplot.show()
Running the example first solves the optimization problem and reports the result.