Optimization
"Optimization" here means one specific thing: given a function, find the input that makes its output as small as possible. scipy.optimize does the searching for you, so you don't have to work out the calculus by hand.
Minimizing a function of one variable
minimize_scalar is the simplest entry point — hand it a function that takes a single number and returns a number, and it searches for the input that minimizes the output:
from scipy.optimize import minimize_scalar
def f(x):
return (x - 3) ** 2 + 5
result = minimize_scalar(f)
print(result.x)
print(result.fun)
3.0 5.0
The function (x - 3)2 + 5 is a parabola with its lowest point at x = 3, where it equals 5 — and that's exactly what minimize_scalar finds, without you ever taking a derivative. result.x is the input that produced the smallest output; result.fun is that smallest output itself.
Minimizing a function of several variables
For a function that takes more than one input, use minimize instead, passing the inputs as a single array-like argument and providing a starting guess with x0:
from scipy.optimize import minimize
def f(point):
x, y = point
return (x - 1) ** 2 + (y - 2) ** 2
result = minimize(f, x0=[0, 0])
print(result.x)
print(result.success)
[1. 2.] True
f is smallest — exactly 0 — at the point (1, 2), and that's what result.x converges to. result.success is worth checking: it's a boolean telling you whether the optimizer actually believes it found a minimum, rather than just giving up.
minimize_scalar, minimize needs a starting guess (x0) and searches outward from it — it doesn't try every possible input. For a function with multiple local minimums, a bad starting guess can lead the optimizer to the wrong one, or fail to converge at all. Always check result.success rather than assuming result.x is trustworthy just because the call didn't raise an error.