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!