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:
[1] -2.36068 [1] 2.36068 [1] 5.27864 [1] 7.082039 [1] 6.804159 [1] 6.2776 [1] 6.25876 [1] 6.283509 [1] 6.283185 [1] 6.283145 [1] 6.283226 [1] 6.283185 $maximum [1] 6.283185 $objective [1] 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!