SciPy Optimizer

SciPy'soptimizemodule provides implementations of common numerical optimization and equation-solving algorithms. We can directly call these functions to solve practical problems, such as finding the minimum or maximum of a function, or finding the roots of equations.

NumPy itself mainly focuses on array computation and linear algebra operations. It providespolynomial root-findingtools (such asnumpy.roots), but it does not provide a genericnonlinear equation numerical root-finding interface.

For example, the following nonlinear equation:

x + cos(x)

For such problems, you can use thescipy.optimize.rootfunction to solve it. The two core parameters commonly used by this function are as follows:

  • fun- The function representing the equation (a return value of 0 indicates that the root has been found)
  • x0- The initial guess for the root

rootThe function returns a result object (OptimizeResult), which contains information such as the solving status, whether it succeeded, the function value, and the final solution.

The actual solution is stored in thexattribute of the returned object. Example:

Example

Find thex + cos(x) = 0root of the equation:

from scipy.optimize import root
from math import cos

def eqn(x):
    return x + cos(x)

myroot = root(eqn, 0)

print(myroot.x)
# View more information
# print(myroot)

Executing the above code produces the following output:

[-0.73908513]

If you print the returned object directly, you can view more complete solution information:

Example

from scipy.optimize import root
from math import cos

def eqn(x):
    return x + cos(x)

myroot = root(eqn, 0)

print(myroot)

Executing the above code produces the following output:

     fjac: array([[-1.]])
      fun: array([0.])
  message: 'The solution converged.'
     nfev: 9
      qtf: array([-2.66786593e-13])
        r: array([-1.67361202])
   status: 1
  success: True
        x: array([-0.73908513])

Where:

  • successIndicates whether the algorithm converged successfully
  • messageDescribes the result of the solving process
  • xThe final root of the equation obtained

Minimization Functions

In mathematics and engineering problems, a function can usually be represented as a curve, and the curve often has high and low points.

The high points of a curve are calledmaxima。

The low points of a curve are calledminima。

The highest point on the entire curve is called theglobal maximum, while the other higher but not highest points are calledlocal maxima。

Similarly, the lowest point on the entire curve is called theglobal minimum, while the other lower but not lowest points are calledlocal minima。

In SciPy, you can use thescipy.optimize.minimize()function to find the minimum of a function.

minimize()The commonly used parameters of the function are described below:

  • fun- The objective function to be minimized

  • x0- The initial guess for the independent variable

  • method- The name of the optimization algorithm used. Common optional values include:'CG'、'BFGS'、'Newton-CG'、 'L-BFGS-B'、'TNC'、 'COBYLA'、'SLSQP'

  • callback- A callback function called after each iteration

  • options- A dictionary of other control parameters, for example:

    {
        "disp": boolean,  # 是否打印详细的优化过程信息
        "gtol": number    # 梯度收敛容差(部分算法适用)
    }

Example

Use the BFGS method to minimize the functionx² + x + 2:

from scipy.optimize import minimize

def eqn(x):
    return x**2 + x + 2

mymin = minimize(eqn, 0, method='BFGS')

print(mymin)

Executing the above code produces the following output:

       fun: 1.75
  hess_inv: array([[0.50000001]])
       jac: array([0.])
   message: 'Optimization terminated successfully.'
      nfev: 8
       nit: 2
      njev: 4
    status: 0
   success: True
         x: array([-0.50000001])

From the result, we can see that the function, atx ≈ -0.5attains its minimum, and the corresponding minimum function value is1.75, which is consistent with the analytical result.

minimize()The function also supports constrained optimization problems. You can add constraints through theconstraintsparameter by specifying equality or inequality constraints, which is suitable for more complex practical application scenarios.

When the objective function cannot be differentiated directly, you can choosemethod='Nelder-Mead'`Nelder-Mead` or other optimization algorithms that do not require gradient information. Such methods gradually approach the optimal solution through simplex search.

In practice,successthe `success` field indicates whether the optimization converged successfully,funthe `fun` field is the optimal objective function value,xand the `x` field is the optimal solution.successIt is recommended to always check the `success` status to ensure the reliability of the solution.

Advanced Root Finding

In addition to theroot()function, SciPy also provides thefsolve()function for solving equation roots. It is more concise and suitable for quickly solving simple equations.

Example

Usefsolveto solvex + cos(x) = 0:

from scipy.optimize import fsolve
from math import cos

def eqn(x):
    return x + cos(x)

result = fsolve(eqn, 0)
print(result)

Executing the above code produces the following output:

[-0.73908513]

fsolve()It directly returns an array of solutions, whileroot()the latter returns a result object containing more information.fsolveThe former is more convenient.

Solving with Multiple Initial Values

For equations with multiple roots, starting from different initial values may yield different roots. The following solvesx² - 4 = 0the two roots:

Example

from scipy.optimize import root

def eqn(x):
    return x**2 - 4

# Solve from different initial values
for guess in [-3, 0, 3]:
    result = root(eqn, guess)
    if result.success:
        print(ff"Initial value {guess:2d} -> root: {result.x)

Executing the above code produces the following output:

初始值 -3 -> 根: -2.000000
初始值  0 -> 根:  2.000000
初始值  3 -> 根:  2.000000

Solving Equations with Parameters

In practical problems, equations often contain parameters. We can pass extra parameters to the objective function through theargsparameter:

Example

from scipy.optimize import root

def eqn(x, a, b):
    return a * x + b * cos(x)

# Solve 2x + cos(x) = 0
result = root(eqn, 0, args=(2, 1))
print(ff"Solution: {result.x)

Executing the above code produces the following output:

解: -0.450184

Constrained Optimization

minimize()The function supports adding constraints, including equality constraints and inequality constraints. Here is an example of a constrained optimization problem:

Example

Minimizex² + y², with the constraintx + y = 1:

from scipy.optimize import minimize

def objective(x):
    return x[0]**2 + x[1]**2

def constraint(x):
    return x[0] + x[1] - 1

# Define constraints
con = {'type': 'eq', 'fun': constraint}
result = minimize(objective, [0, 0], constraints=con)

print(ff"Optimal solution: x={result.x)
print(ff"Minimum value: {result.fun:.6f}")

Executing the above code produces the following output:

最优解: x=0.500000, y=0.500000
最小值: 0.500000

Constraint types'eq'Indicates an equality constraint (the constraint function must equal 0),'ineq'Indicates an inequality constraint (the constraint function must be greater than or equal to 0).

Bound-Constrained Optimization

In addition to functional constraints, you can also use theboundsparameter to limit the value range of the independent variable:

Example

Inx ∈ [0, 2]Minimize within the range(x - 1)² + 2:

from scipy.optimize import minimize

def objective(x):
    return (x - 1)**2 + 2

# Define bounds
bounds = [(0, 2)]
result = minimize(objective, 0, bounds=bounds)

print(ff"Optimal solution: x={result.x)
print(ff"Minimum value: {result.fun:.6f}")

Executing the above code produces the following output:

最优解: x=1.000000
最小值: 2.000000

Gradient-Free Optimization

When the objective function is non-differentiable or its derivative is difficult to compute, you can use an optimization algorithm that does not require gradient information, such as theNelder-Meadmethod:

Example

Use the Nelder-Mead method to minimizesin(x) + 0.5*x:

from scipy.optimize import minimize
from math import sin

def objective(x):
    return sin(x) + 0.5 * x

result = minimize(objective, 0, method='Nelder-Mead')
print(ff"Optimal solution: x={result.x)
print(ff"Minimum value: {result.fun:.6f}")
print(ff"Success: {result.success}")

Executing the above code produces the following output:

最优解: x=-1.047198
最小值: -1.523599
是否成功: True

Common Issues and Suggestions

  • Choose an appropriate initial value- The choice of initial value has a great impact on the solution result. It is recommended to perform a simple visualization or analysis of the objective function before solving.
  • Check the convergence status- Always check thesuccess`success` field to ensure the algorithm has converged successfully. If solving fails, try changing the initial value or the optimization algorithm.
  • Choose an appropriate algorithm- For unconstrained problems,BFGS`BFGS` is a good default choice; for large-dimensional problems, you can try `L-BFGS-B`;L-BFGS-Bfor non-differentiable functions, use `Nelder-Mead`.Nelder-Mead。
  • Handling Multiple Roots- For problems with multiple roots, it is recommended to solve starting from multiple different initial values.
  • Parameter Passing- Use theargs`args` parameter to pass extra arguments, avoiding the use of global variables.

Summary

SciPy'soptimizemodule provides powerful optimization and equation-solving tools:

  • Root finding:root()andfsolve()for solving nonlinear equations
  • Unconstrained optimization:minimize()combined with themethod`method` parameter to implement multiple algorithms
  • Constrained optimization: via theconstraints`constraints` parameter to add equality and inequality constraints
  • Bound constraints: useboundsParameter limits the range of variable values
  • Gradient-free methods:Nelder-MeadApplicable to non-differentiable functions

After mastering these basic functions, readers can further exploreoptimizeMore features of the module, such as curve fitting (curve_fit), global optimization (basinhopping、differential_evolution) and other advanced features.

Other extensions