# Find the Minimum and Maximum of a Function in R

The function optimize (also spelled optimise) in R returns the minimum or maximum of a function f(x) within a specified interval.

It takes as inputs:

• f: a function.
• interval: a vector containing the lower and upper bounds of the domain where we want to search for the minimum or maximum.
• maximum: a logical, where TRUE tells optimize that we want to find the maximum, and FALSE the minimum, of f (the default is FALSE).

The function optimize outputs the x and y values of the minimum/maximum.

Here are some examples:

## Finding the minimum of: $$f(x) = x^2 + 1$$

# code the function
f = function(x) {
x^2 + 1
}

# find the minimum of f(x) within the interval [-1, 1]
ans = optimize(f, interval = c(-1,1))

# optimize returns a list of 2 values:
# "minimum" is the x value where the minimum occurs
# and "objective" is the y value, i.e. f(minimum)
x_min = ans$minimum y_min = ans$objective

# plot f(x)
x = seq(-1, 1, length.out = 100) # generates 100 numbers between -1 and 1
plot(x, f(x), type = 'l')

# plot the minimum point
points(x_min, y_min, pch = 15)

# annotation
text(x = x_min, y = y_min, labels = 'Minimum',
pos = 3, col = 'blue')

Output:

## Finding the maximum of: $$f(x) = x^5-5x^4+5x^2-x+1$$

f = function(x) {
x^5 - 5*x^4 + 5*x^2 - x + 1
}

# find the maximum of f(x) within the interval [-1, 1]
ans = optimize(f, interval = c(-1,1), maximum = TRUE)

# extract the coordinates of the maximum
x_max = ans$maximum y_max = ans$objective

# plot f(x)
x = seq(-1, 1, length.out = 100)
plot(x, f(x), type = 'l')

# plot the maximum
points(x_max, y_max, pch = 15)
text(x = x_max, y = y_max, labels = 'Maximum',
pos = 4, col = 'blue')

Output:

## Finding the maximum of: $$f(x) = cos x$$

f = function(x) {
cos(x)
}

# find the maximum of f(x) within the interval [-10, 10]
ans = optimize(f, interval = c(-10,10), maximum = TRUE)

# extract the coordinates of the maximum
x_max = ans$maximum y_max = ans$objective

# plot f(x)
x = seq(-10, 10, length.out = 100)
plot(x, f(x), type = 'l')

# plot the maximum
points(x_max, y_max, pch = 15)
text(x = x_max, y = y_max, labels = 'Maximum',
pos = 4, col = 'blue')

Output:

So why did optimize chose this particular point as maximum?

To investigate at which x values the function is being evaluated, you can use a print statement inside f(x):

f = function(x) {
print(x) # prints the value of x whenever f(x) is called
cos(x)
}
optimize(f, interval = c(-10, 10), maximum = TRUE)

Output:

 -2.36068
 2.36068
 5.27864
 7.082039
 6.804159
 6.2776
 6.25876
 6.283509
 6.283185
 6.283145
 6.283226
 6.283185
$maximum  6.283185$objective
 1

Next, let’s plot these points to see what’s happening:

xs = c(-2.36068,
2.36068,
5.27864,
7.082039,
6.804159,
6.2776,
6.25876,
6.283509,
6.283185,
6.283145,
6.283226,
6.283185)

plot(x, cos(x), type = 'l')
points(xs, cos(xs), col = 'red', pch = 15)
text(x = xs, y = cos(xs), labels = c(1:5, '6-12', rep('', 6)),
pos = 4, col = 'red')

Output:

This plot shows that optimize did not detect a change in the y value between points 1 and 2, and perhaps thought that the function was constant between these 2 points and missed the peak at x = 0.

Note: I tried changing the interval from [-10, 10] to [-7, 10], and optimize had no problem detecting a maximum at (0, 1).

## Finding the minimum of $$f(x) = 3$$

f = function(x) {
3
}

# find the minimum of f(x) within the interval [-1, 1]
ans = optimize(f, interval = c(-1,1))

x_min = ans$minimum y_min = ans$objective

# create empty plot
plot(1, type = "n", xlab = "x", ylab = "f(x)",
xlim = c(-1.1, 1.1), ylim = c(0, 5))

# plot f(x)
abline(h = 3)

# plot the minimum point on f(x)
points(x_min, y_min, pch = 15)
text(x = x_min, y = y_min, labels = 'Minimum',
pos = 3, col = 'blue')

Output:

Even though $$f(x) = 3$$ is constant, optimize managed to find a minimum at x = 1!