Solve a nonlinear equation system with constraints on the variables

Viewed 9715

Some hypothetical example solving a nonlinear equation system with fsolve:

from scipy.optimize import fsolve
import math

def equations(p):
    x, y = p
    return (x+y**2-4, math.exp(x) + x*y - 3)

x, y =  fsolve(equations, (1, 1))

print(equations((x, y)))

Is it somehow possible to solve it using scipy.optimize.brentq with some interval, e.g. [-1,1]? How does the unpacking work in that case?

1 Answers

As sascha suggested, constrained optimization is the easiest way to proceed. The least_squares method is convenient here: you can directly pass your equations to it, and it will minimize the sum of squares of its components.

from scipy.optimize import least_squares
res = least_squares(equations, (1, 1), bounds = ((-1, -1), (2, 2)))

The structure of bounds is ((min_first_var, min_second_var), (max_first_var, max_second_var)), or similarly for more variables.

The resulting object has a bunch of fields, shown below. The most relevant ones are: res.cost is essentially zero, which means a root was found; and res.x says what the root is: [ 0.62034453, 1.83838393]

 active_mask: array([0, 0])
        cost: 1.1745369255773682e-16
         fun: array([ -1.47918522e-08,   4.01353883e-09])
        grad: array([  5.00239352e-11,  -5.18964300e-08])
         jac: array([[ 1.        ,  3.67676787],
       [ 3.69795254,  0.62034452]])
     message: '`gtol` termination condition is satisfied.'
        nfev: 7
        njev: 7
  optimality: 8.3872972696740977e-09
      status: 1
     success: True
           x: array([ 0.62034453,  1.83838393])
Related